質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.92%

c言語で自動販売機のフローチャートを作成

解決済

回答 5

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 8,935

kmercy

score 7

こんにちは。c言語の学習を始めて1ヵ月の初心者です。現在、教本の自動販売機のフローチャートの作成に挑戦しているのですが思ったように進まず困っています。
特におつりの処理がわかりません。
私は、おつりを{500、100、50、10}の配列で順に割っていきその枚数を自動販売機の保有硬貨の数から引けばいいと考えたのですが、保有硬貨が足りない場合を考えていないと指摘されてからわからなくなってしまいました。
教本自体に答えが載っていないためどんずまり状態です。みなさんならどういうふうに書くかまた、よろしければ、全体的にどのようにコーディングするのかお手本も知りたいので何卒、ご教授願います。

想定する自販機の仕様は
・1回1個の商品しか買えない
・商品は150円と120円が5個づつ
・扱えるお金は、1000円、500円、100円、50円、10円
・商品ボタンが押されるまで投入金を加算する機能
・返金ボタンの機能

・おつりは500円、100円、50円、10円で返す

・自販機の保有硬貨は各100枚づつ保有硬貨が足りない場合も考える

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

+3

答えが重要じゃなく、考え方が重要ですね。

1-仕様を処理と制約に分けましょう。
■処理
・投入機能
・返金機能
・購入機能

■制約
・1回1個の商品しか買えない 
・商品A(150円,5個)
・商品B(120円,5個) 
・購入用(1000円,500円,100円,50円,10円)
・おつりは500円、100円、50円、10円で返す
・お釣り用(500円,100枚)
・お釣り用(100円,100枚)
・お釣り用(50円,100枚)
・お釣り用(10円,100枚)

2-制約の中で、減ったり増えたりする物をさがしてください、これが変数なります。
また、減ったり増えたりする範囲を探してください、これが条件になります。
どちらでもないものは制約のまま残してください。
■処理
・投入機能
・返金機能
・購入機能

■制約
・1回1個の商品しか買えない 
・購入用お金(1000円,500円,100円,50円,10円)
・おつりは500円,100円,50円,10円で返す
・商品Aは150円
・商品Bは120円

■変数
・商品Aの個数
・商品Bの個数
・お釣り用500円硬貨の枚数
・お釣り用100円硬貨の枚数
・お釣り用50円硬貨の枚数
・お釣り用10円硬貨の枚数

■条件
・商品Aは0個〜5個
・商品Bは0個〜5個
・お釣り用500円硬貨は0枚〜100枚
・お釣り用100円硬貨は0枚〜100枚
・お釣り用50円硬貨は0枚〜100枚
・お釣り用10円硬貨は0枚〜100枚

3-機能の実行によって増えたり減ったりする物を考えましょう。新しく変数に追加してください。
4-機能の実行が出来る条件(購入は投入額が商品額を超えないとできない等々)を考えましょう。
5-機能だけのフローチャートを描きます。
6-変数をフローチャートに追加します。
7-条件をフローチャートに追加します。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

考え方についての質問なので、考えてみました。
1.500円,100円,50円,10円の枚数を決めます。
2.500円,100円,50円,10円の順に割っていき結果を表示します。
3.それぞれの商を初めに決めた500円,100円,50円,10円の枚数から引きます。
4.初めに決めた硬貨の枚数が0になった場合は該当する硬貨では割りません。
5.おつりが出せなくなったら繰り返しを終了します。
下のプログラムが意図したとおりに動くかどうかは分かりません。

#encoding : utf-8

coin_500 = 100
coin_100 = 100
coin_50 = 100
coin_10 = 100

loop{
  input = gets.chomp.to_i

  items = gets.chomp.to_s.split(",").map(&:to_i)

  item1_price = items[0]
  item1_num = items[1]

  item2_price = items[2]
  item2_num = items[3]

  sum = (item1_price * item1_num) + (item2_price * item2_num)
  res = input - sum
  puts"合計金額:#{sum}円"
  puts"おつり:#{res}円"

  if coin_500 > 0
    num_500 = res / 500
    puts "500円:#{num_500}枚"
    res = res - (500 * num_500 )
    coin_500 -= num_500
  end
  if coin_100 > 0
    num_100 = res / 100
    puts "100円:#{num_100}枚"
    res = res - (100 * num_100)
    coin_100 -= num_100
  end
  if coin_50 > 0
    num_50 = res / 50
    puts "50円:#{num_50}枚"
    res = res - (50 * num_50 )
    coin_50 -= num_50
  end
  if coin_10 > 0
    num_10 = res / 10
    puts "10円:#{num_10}枚"
    res = res - (10 * num_10 )
    coin_10 -= num_10
  end
  if coin_500 + coin_100 + coin_50+ coin_10 == 0
    break
  end
  puts"-------------------------------------\n"
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

+1

フローチャート

イベントが複数あるかと思い、
・お金投入イベント
・返金イベント
・商品選択イベント
で、フローチャートを分けています。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/01 21:10

    具体的な返答をしていただき、ありがとうございます。

    キャンセル

+1

目的とする処理をどうやって実装すればよいか判らない場合は、処理を小さく切り分けて考えると実装方法が分かってきます。コツは自分で勝手に想定した「都合がいい処理」が存在するものとして考えることです。「都合がいい処理」の中身は、後で別に考えればいいです。

今回の場合、問題は『お釣りを自動販売機から出したい。でも、自動販売機の中に存在しない硬貨を出すことはできない』ということですよね。
であれば、

「指定された金額のお釣りを得るために、自販機の中から都合がいい硬貨を1枚取り出す」

という処理が存在すると想定すると、保有硬貨が足りない場合を考慮した処理が作れそうな気がしてきませんか?(この処理を何回も繰り返して、お釣りとして出す必要があるだけ硬貨を1枚ずつ引っ張り出してくればいいのです)

そのあとで「指定された金額のお釣りを得るために、自販機の中から都合がいい硬貨を1枚取り出す」というのは具体的にどんな動きなんだ?と考えるわけです。

例:
【指定された金額のお釣りを得るために、自販機の中から都合がいい硬貨を1枚取り出す】の詳細

この処理では、500円、100円、50円、10円 のいずれかの硬貨を1枚取り出す。
この処理で硬貨を取り出すと、自販機の保有硬貨数が1枚減る。
この処理では、自販機の中に存在しない硬貨は取り出せない。
この処理では、取り出す硬貨の枚数が少なくて済むように、価値が高い硬貨を優先して取り出そうとする。
(例: 999円のお釣りなら、500円硬貨を1枚取り出そうとする)
(例: 499円をお釣りなら、100円硬貨を1枚取り出そうとする)

この処理は元の問題を切り分けたものなので、ここで考えなければいけない問題の難度は元の問題よりも下がっています。

それでもまだ難しいなら、この「都合がいい処理」を実装するには、どんな「もっと都合いい処理」が存在していればよいか…と言った具合に考えていくとよいとおもいます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

フローチャートを作るのですね。今できているものを、不完全でも見せていただけると回答がしやすいです。ともかく、回答します。


ソフトウェアというのは「現実をモデル化して、それをプログラムで実現したもの」です。フローチャートは、モデルの動作 (動き) を図で表現したものです。そういうわけですから、まずは現実の自動販売機を観察してみましょう。近所に自動販売機、ありますよね?

外側から見えるのは▽お金の投入口、▽商品のボタン、▽商品取り出し口、▽釣り銭や返金の返却口です。自販機が内部でどんな動作をしているのかは見ることができませんが、▽商品の保管場所と、▽保有硬貨の保管場所があることは想像がつきますね。

  • 自動販売機は、上記の構成要素から成るモデルで表現できます。

釣り銭返却処理にしぼって考えると、見えるものはもうひとつあります。釣り銭が返却口に出てくる順番です。私の見たところ、釣り銭が一度にまとめて出てくる機種は割と少ないです。たいてい、1枚ずつか数枚ずつ順番に出てきます。つまり、

  • 釣り銭返却処理は、保有硬貨から1枚あるいは数枚を取って、返却口に出すという動作を繰り返す処理です。

実際に観察してみるとわかりますが、硬貨が出てくる順番は私の知る範囲では (一度にまとめて出てくるものを除き) 少なくとも3種類あります。①大きな額面の硬貨から先に出す、②小さな額面の硬貨から先に出す、③異なる額面の硬貨1枚ずつを一緒に出す、のいずれかです。それぞれ、どういう考え方でお金を順番に出しているのか、実物を観察して考えてみるといいでしょう[1]。

「保有硬貨から1枚あるいは数枚を取って、返却口に出す」という処理を、①から③のどれかの方式でやるとします。これには▽すでに返却口から出した金額、▽投入金額、▽購入金額、▽保有硬貨の額面毎の枚数、が関係します。一方、処理の結果は▽返却口から出す額面と▽その枚数で表されます。そして、上で述べたように、この処理を繰り返せば釣り銭返却処理ができます。

以上のことを図にまとめれば、課題のフローチャートになると思います。


[1] ①の方式が多いのはなんとなく分かるような気がしますが、③も意外と多いです。③がどういう方式なのかの詳細説明は省きますので、もしも見つけたらよく観察してみて下さい (特定の製造メーカーの機種が比較的多いです)。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/02 00:27

    ありがとうございます。
    もっと自動販売機を観察してみます

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る