• ベストアンサー

プログラムの考え方。

コマンドラインから引数を入力してお金の種別に分類せよ。(2000円札は考えない) main関数ではコマンドラインからの引数を判断し、引数の数や値がおかしいときにはエラーメッセージを表示する。正しいときはsyubetu関数にデータを渡してその結果を表示する。 syubetu関数は以下のとおりである。 ・関数名 syubetu ・引数 金額 money(int) 金種格納 kinsyu(int*) ・戻り値 なし ・機能 金額、金種格納用ポインタを引数とし、金種ごとの枚数を計算する関数 こういう問題があって、 コマンドラインの引数に数字を入力したら 一万円札から順番に何枚あるかの種別に分けるプログラムなんですが、 その分類をどうやってさせていいのかがわかりません。 例えば13531とかいれたら 一万円 一枚 5千円 0枚 千円 3枚 5百円 1枚 百円 0枚 50円 0枚 10円 3枚 5円 0枚 1円 1枚 っと表示させます。 この分類のところはどのように考えたらプログラムできるでしょうか? フローチャートを考えている途中なのですが、いまいち考え方がわかりません。 よろしくおねがいします。

質問者が選んだベストアンサー

  • ベストアンサー
  • arukamun
  • ベストアンサー率35% (842/2394)
回答No.7

こん**は >特に「j/=10」や、「money%(2*j)/j」の処理の意味>がわかりません。 No.5の回答は j/=10; は j=j/10; と同じ意味です。 jは10分の1されていく変数ですね。 money%(2*j)/j; ←5系 money%(5*j)/j; ←1系 自分より1個大きい紙幣や硬貨の余りを自分自身で割って、枚数を出している訳です。 また、10000という、自分より1個大きい紙幣や硬貨が存在しないので、別に分けている訳ですね。 moneyの引き算をやってしまうと、10000の場合と、5000,500,50,5の場合と、1000,100,10,1の場合に分けられませんね。 そこで、 kinsyu[0] = money/10000 ; これで、一万円札の枚数、 for (i=1,j=5000 ;i<9 ;i+=2,j/=10) kinsyu[i] = money%(2*j)/j ; これで、五千円札、五百円玉、五十円玉、五円玉の枚数、 for (i=2,j=1000 ;i<9 ;i+=2,j/=10) kinsyu[i] = money%(5*j)/j ; これで、千円札、百円玉、十円玉、一円玉の枚数となる訳です。 No.6の回答は 1系と5系を同じループで行う事が出来ないかを考えた結果です。 for (i=0,j=10000,k=2 ;i<9 ;kinsyu[i]=money/j,money%=j,i++,j/=k,k=7-k); これを理解するには、i,j,k,moneyがどのように変化していくのかを表にすれば解りますよ。 i  j    k  money  kinsyu[i] 0  10000  2  13531  1 1  5000   5  3531   0 2  1000   2  3531   3 3  500   5  531   1 4  100   2  31    0 5  50    5  31    0 6  10    2  31    3 7  5    5  1    0 8  1    2  1    1

usui323
質問者

お礼

回答ありがとうございました。 やっと理解できました。

その他の回答 (7)

noname#5537
noname#5537
回答No.8

テーブルを用意しとくのが分かりやすいんとちゃうかな? int table[] = {  10000, 5000, 1000, 500, 100, 50, 10, 5, 1, 0, }; void syubetu(int money, int* kinsyu) {  int i;  for (i=0 ; table[i] ; i++) {   kinsyu[i] = money / table[i];   money %= table[i];  } }

usui323
質問者

お礼

回答ありがとうございました。 こういう使い方もできるんですねー。 わかりやすかったです。

  • arukamun
  • ベストアンサー率35% (842/2394)
回答No.6

こん**は、No.5のarukamunです。 No.5の回答も決して模範的なものではありません。 学校のプログラムの授業は、もしかすると先生と生徒の立場が逆転してしまうものかもしれませんね。 先生が正しくプログラムを理解できるのであれば、こんなforループ1個でも良いんですよね。 syubetu(int money,int kinsyu[]) {   int i,j,k ;   for (i=0,j=10000,k=2 ;i<9 ;kinsyu[i]=money/j,money%=j,i++,j/=k,k=7-k); }

usui323
質問者

お礼

回答ありがとうございました。 こっちのプログラムはさっぱりわかりません。 私は引き算でループでグルグル回す方法しか考え付きませんでしたが、 それだとかなり長くなってしまうのでこういう風に工夫すれば短くなるんですね。 これがどういう処理を行ってるかとか考えつきませんが(^^;)

  • arukamun
  • ベストアンサー率35% (842/2394)
回答No.5

こん**は 私からは、コメント無しのソースを示します。 これもフローチャートを書くという課題であれば、ヒントになるでしょう。 syubetu(int money,int kinsyu[]) {   int i,j ;   for (i=0 ;i<9 ;i++) kinsyu[i] = 0 ;   kinsyu[0] = money/10000 ;   for (i=1,j=5000 ;i<9 ;i+=2,j/=10) kinsyu[i] = money%(2*j)/j ;   for (i=2,j=1000 ;i<9 ;i+=2,j/=10) kinsyu[i] = money%(5*j)/j ; }

usui323
質問者

お礼

回答ありがとうございました。 このプログラムで実行できたのですが、 このfor (i=1,j=5000 ;i<9 ;i+=2,j/=10) kinsyu[i] = money%(2*j)/j ; for (i=2,j=1000 ;i<9 ;i+=2,j/=10) kinsyu[i] = money%(5*j)/j ; がどういう意味をもつのかがちょっとわかりません。 1万円の場合は別に計算しといて 初めのループでは5千円、5百円、50円、5円を計算してて最後のループで千円、百円、10円、1円を kinsyu配列に格納しているようですが、 特に「j/=10」や、「money%(2*j)/j」の処理の意味がわかりません。 どういった処理を行っているのでしょうか?

回答No.4

13531 / 10000 = 1 ... 3531 3531 / 5000 = 0 ... 3531 3531 / 1000 = 3 ... 531 531 / 500 = 1 ... 31 31 / 100 = 0 ... 31 31 / 50 = 0 ... 31 31 / 10 = 3 ... 1 1 / 5 = 0 ... 1 1 / 1 = 1 ... 0 です。高額の金種から順に割り、商と余りを...

usui323
質問者

お礼

回答ありがとうございました。

  • fm0606
  • ベストアンサー率10% (1/10)
回答No.3

数字の引数を文字列と考えていけばよろしいのではないでしょうか。 たぶんargv[]でコマンドラインから数字を受け取るのでしょうね。 例えば1万の位をだすには for(i=0; i<9; i++){ if(strncmp(&arg[0],i,1)==0){ man = i*10000; printf("1万円%d\n枚",man); } } 分岐文のところで if(strncmp(&arg[0],i,2)==0){千の位 if(strncmp(&arg[0],i,3)==0){百の位        ・        ・        ・ と検索すればよいのではないでしょうか・・ 50円が何枚かというのはちょっと意味がわかりませんね・・同様に5円も。。

usui323
質問者

お礼

回答ありがとうございました。

回答No.2

金種の特性を考えましょう。 3円支払うには1円玉でないとだめですが、 7円支払うには5円玉を含んでも良いですよね。 30円支払うには10円玉でないとダメ(題意より)ですが 70円支払うには50円玉を含んでも良いです。 これで、大体わかると思いますが… いかがでしょうか? フローのヒントを出すと答えになってしまいますので (それくらい簡単で基本的な問題です) この程度にしましたが、類題に「学籍番号を入力し、 その人の入学年度・学部・学科を判定せよ」と言うのが あります。 これは学籍番号が「入学年度」「学部」「学科」「個人の番号」 という要素で出来ているときに、学籍番号からそれぞれの 情報を取り出すのですが、いろいろなところで サンプルがあると思いますよ。

usui323
質問者

お礼

回答ありがとうございました。

回答No.1

こんにちは。  授業の問題か、それに類するものですね。自分で考えないと身に付きませんよ。  例えば、8千円あるとすると、5千円札が1枚で、千円札が3枚ですね。では、なぜ1万円札はいらないと判断しました?8千円は、1万円よりも小さいからですね。では、5千円札が1枚と判断したのは?8千円の方が5千円よりも大きいからですね。では、なぜ1枚?8千円から5千円を1回引くことができるからですね。あまりは3千円となり、もう5千円を引くことはできません。同じように、千円札が3枚なのは、3千円から千円を3回引くことができるからですね。  ここでは引き算を使いましたが、引き算をしようとするとfor文でグルグル回さなければならないので、もっと効率のいい方法を見つけましょう。

usui323
質問者

お礼

回答ありがとうございました。