アプリ版:「スタンプのみでお礼する」機能のリリースについて

2つの整数(月、日)を入力すると、2007年度があと残り何日かを計算するプログラムが書きたいのですが、できるだけif文(またはswitch文)を少なくして書きたいのですが、12こif文を使うと書けるものの、それ以下に絞ることができません。
2007年度(2007年4月1日~2008年3月31日)のみに適応できればいいので、日付をコンピュータから取得せず、入力された値だけに反応するものを書きたいです。
if文、switch文、printf文、scanf文のみで仕上げるというのが課題なのですが、他の文をつかえばできるとは思うのですが、上記のものだけで作るとなると、難しいです…、どなたか、教えていただけないでしょうか。

A 回答 (6件)

★アドバイス


・if、switch を減らしたいのなら配列のテーブルで残りの日数を用意します。
 あとは配列の添え字に『月』を指定すればそのまま残りの日数を得ることが出来ます。
>if文、switch文、printf文、scanf文のみで仕上げるというのが課題なのですが、
>他の文をつかえばできるとは思うのですが、上記のものだけで作るとなると、
>難しいです…、どなたか、教えていただけないでしょうか。
 ↑
 まずは if、switch、printf、scanf で出来ているソースを貼り付けてみて下さい。
 ちなみに配列データは次のようにすれば良いです。
 
 static const int table1[] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
 static const int table2[] = {
  0,
  31 + 29, ←2008年1月
  31, ←2008年2月
  0, ←2008年3月
  31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31, ←2007年4月
  31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 30,
  31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 31,
  31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
  31 + 29 + 31 + 30 + 31 + 30 + 30,
  31 + 29 + 31 + 30 + 31 + 31,
  31 + 29 + 31 + 30 + 30,
  31 + 29 + 31 + 31,
  31 + 29 + 31, ←2007年12月
 };
 テーブルの内容は
>2007年度(2007年4月1日~2008年3月31日)
 ↑
 これに合わせています。
 このテーブルの table2[ month ] とすることで残りの日数が簡単に求まります。
 この値に入力された day の残りに数を加えれば良いです。
 つまり ans = table2[month] + (table1[month] - day); とします。
・このような方法なら if、switch は使いません。
 特に2007年度限定ならば。
 入力部分と入力値の補正処理はご自分で行って下さい。
 ちなみに今日は2007年10月24日なので
 table2[10] + (table1[10] - 24);
 とすると
 151 + (31 - 24)
 となって 158 が残り日数となります。
・table1 は各月の日数です。
 table2 が 2007 年度(2008/3/31)までの残り日数を記述しています。
 極端に if、switch 文を減らそうとするとこのようになります。
 普通は西暦1年1月1日(1970/1/1でも良いけど)からの累計数を求めてその数を
 引き算するようにします。そうすれば 2007 年度以外にも対応できます。
・以上。テーブルの作り方などを参考にして下さい。

この回答への補足

#include <stdio.h>

int main(void)
{
int month, day, nokori;

printf("Input date : ");
fflush(stdout);
scanf("%d %d", &month, &day);

if( month == 4 && day>=1 && day <=30){
nokori = 11 * 30 + 6 + (30 - day);
}
else if( month == 5 && day >= 1 && day<= 31){
nokori = 10 * 30 + 5 + (31- day);
}
else if( month == 6 && day >= 1 && day<= 30){
nokori = 9 * 30 + 5 + (30- day);
}
else if( month == 7 && day >= 1 && day<= 31){
nokori = 8 * 30 + 4 + (31- day);
}
else if( month == 8 && day >= 1 && day<= 31){
nokori = 7 * 30 + 3 + (31- day);
}
else if( month == 9 && day >= 1 && day<= 30){
nokori = 6 * 30 + 3 + (30- day);
}
else if( month == 10 && day >= 1 && day<= 31){
nokori = 5 * 30 + 2 + (31- day);
}
else if( month == 11 && day >= 1 && day<= 30){
nokori = 4 * 30 + 2 + (30- day);
}
else if( month == 12 && day >= 1 && day<= 31){
nokori = 3 * 30 + 1 + (31- day);
}
else if( month == 1 && day >= 1 && day<= 31){
nokori = 2 * 30 + (31- day);
}
else if( month == 2 && day >= 1 && day<=29){
nokori = 31+ ( 29- day);
}
else if( month == 3 && day >= 1 && day<= 31){
nokori = 31- day;
}
else{
printf("this month or day is not correct");
return (-1);
}

printf("nokori is %d \n", nokori);

return (0);
}

と、私が作ったものはこのような感じに、if文がならんでいます…
入力された値が正しいかどうかのif文はのこしておいて、正しければテーブルを使用した計算をする、というような構成でいいのでしょうか。

補足日時:2007/10/24 22:28
    • good
    • 0

>具体的にどういった風に使用すればよいかわからなかったので


3/31だと1(=Month3[31-1])を返せばいいですよね。
if( monthNo == 3 ){
return( Month3[dayNo-1] );
}
    • good
    • 0

★入力値をチェックしましょう。


・以上。
    • good
    • 0

★アドバイス


>入力された値が正しいかどうかのif文はのこしておいて、
>正しければテーブルを使用した計算をする、
>というような構成でいいのでしょうか。
 ↑
 そうです。
 入力した『年』『月』『日』のチェックをした後にテーブル参照で求めれば良いです。
 ただし、日付のチェックはちょっと面倒です。
 理由は 28、29、30、31 と4パターンあるからです。
 でも前回紹介した table1 を使えば簡単にチェックできます。
 つまり
 if ( (day >= 1) && (day <= table1[month]) ){
  // day入力値は有効
 }
 else{
  // day入力値は無効
 }
 とすれば良いです。
 なお先に month の有効性をチェックしておいて下さい。
・以上。
    • good
    • 0

(3/31で1日と答えると仮定しています)


それが美しいかどかは別として...
if,switchの数を減らせばいいのなら、2変数だからswitch文2個
入れ子にすれば足ります。
数字はプログラムでなくあなたが先に計算しておくこともできます。
switch( monthNo ){
 case 1://1月
  switch( dayNo ){
   case 1://1日
    return(91);//1月1日->91日
   case 2:
    return(90);
   ...
  }
  break;
 case 2:
  ...
}
入力値から日数を計算すれば、計算式は使いますがif,switchなどは
全く使わずに作れますよね。
const int Month3[31] = {31,30,29,...2,1};
const int Month2[29] = {60,59,58,...33,32};
と答えのテーブルを作っておくのも一案です。
リソースとしてメモリはあるけど時間は使いたくない時に、
複雑なif文を回避するためにこういうテーブルを使うこと
もありますよ。

この回答への補足

回答ありがとうございます。
const int Month3[31] = {31,30,29,...2,1};
const int Month2[29] = {60,59,58,...33,32};

というテーブルを具体的にどういった風に使用すればよいかわからなかったので、詳しく教えていただけませんか?
なにぶん、授業で2~3時間レクチャーを受けただけで、知識といえば、型があること、if文、switch文、printf文、scanf文くらいまでしか教わっていないので…。

そして補足欄が一度書いてしまうと訂正できませんでしたので、ここからはAno2のOh-Orangeさんへのお返事になります。申し訳ありません、機能を把握していなくて・・・。
Oh-Orangeさんのご回答を参考にしてテーブルを使ってみたのですが...
#include <stdio.h>

int main(void)
{
int month, day, nokori;
static const int table1[] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static const int table2[] = {
0,
31 + 29,
31,
0,
31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31,
31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 30,
31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 31,
31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
31 + 29 + 31 + 30 + 31 + 30 + 30,
31 + 29 + 31 + 30 + 31 + 31,
31 + 29 + 31 + 30 + 30,
31 + 29 + 31 + 31,
31 + 29 + 31,
};

printf("Input date : ");
fflush(stdout);
scanf("%d %d", &month, &day);

if( month < 1 || month > 12 || day < 1 || day > 31){
printf("this month or day is not correct");
return (-1);
}

else{
nokori = table2[month] + (table1[month] - day);
}

printf("nokori is %d \n", nokori);

return (0);
}

とすると、2 30 (2月30日)など存在しない日を入力しても答えを計算してしまいます。(その場合、3月1日と入力したのと同じ回答が得られます)
一応、最初のif文で、1未満や12より大きい月、1未満や31より大きい日などははじくようにしてあるのですが…。
あと3つくらいif文を追加すれば判別できるのでしょうけど…
条件文のところに、29日の月、30日の月、31日の月であれば計算する…というような条件を書いて。
うまくまとめる方法はないでしょうか…。

補足日時:2007/10/24 22:51
    • good
    • 0

#include <stdio.h>



int main(void)
{
int m[12] = {30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 28, 31};
int month, day, sum, i;

scanf("%d %d", &month, &day);
if(month < 1 || 12 < month) return 1;
month = (month + 8) % 12;
if(day < 1 || m[month] < day) return 1;
sum = m[month] - day;
switch(month + 1){
case 1: sum += m[1];
case 2: sum += m[2];
case 3: sum += m[3];
case 4: sum += m[4];
case 5: sum += m[5];
case 6: sum += m[6];
case 7: sum += m[7];
case 8: sum += m[8];
case 9: sum += m[9];
case 10: sum +=m[10];
case 11: sum +=m[11];
default : ;
}
printf("%d\n", sum);
return 0;
}
    • good
    • 0
この回答へのお礼

ご回答本当にありがとうございます。
私の言い方が悪かったのですが、スイッチ文を少なくするというのはスイッチ文の中のケースも少なくする、という意味なので、いただいた回答とは少しずれがありました。せっかくご回答頂いたのに申し訳ないです。
でも私のソースよりもすっきりしていて見やすくって、とても参考になりました。今後プログラムを書くのに参考にさせていただきます。
ありがとうございました。

お礼日時:2007/10/24 22:48

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!