ページ 11

多重リスト

Posted: 2010年6月26日(土) 15:14
by asdf
商品管理簿を多重リストを使って作れ.
商品管理簿は,以下のデータからなるものとする.

顧客番号,顧客氏名,顧客電話番号,受注した商品の個数,出荷した商品の個数.

1)作成した商品管理簿に対し,商品の発送,新規商品の追加,廃番商品の削除,
顧客の登録,削除,新規商品の受注ができること.

2)商品ごとの受注量,出荷量,受注残量,顧客ごとの受注個数,受注残個数が計
算できること.

という問題で、「cプログラマのためのアルゴリズムとデータ構造」という本を参考に作ったのですが、削除の段階で躓いてしまいました。
Insert関数が変な追加の仕方をしているため、どう削除すればよいか分からなくなってしまいました。
(このInsert関数は、この本にのっている例をほとんど写しただけのものなのですが・・・)


自分が作ったプログラムは、少し長いので添付しました。
月曜日までに終わらせないといけません・・・
どうかご助力をお願いします。 画像

Re:多重リスト

Posted: 2010年6月26日(土) 16:42
by Poco
2つ質問があります。

・データ構造に関する指定はありました?
・発送の所で失敗しているケースがありますが、問題文のどの箇所からこの処理が必要だと判断しました?

Re:多重リスト

Posted: 2010年6月26日(土) 16:53
by asdf
>データ構造に関する指定はありました?

どういう意味でしょうか。多重リストというのがデータ構造なのではないでしょうか。

>発送の所で失敗しているケースがありますが、問題文のどの箇所からこの処理が必要だと判断しました?

受注残があるということから、受注分だけ発送できないときがあるということになります。
実際に発送できる量をいちいち入力するのが面倒だったので、rand関数を使っています。 画像

Re:多重リスト

Posted: 2010年6月26日(土) 16:58
by asdf
添付プログラムの、構造体KANRIの説明が双方向になっていますが、あれは、最初は双方向で作ろうとしたのをやめたのに消すのを忘れていたからです。ということで、あのコメントは無視してください。

Re:多重リスト

Posted: 2010年6月26日(土) 17:00
by Poco
> どういう意味でしょうか。多重リストというのがデータ構造なのではないでしょうか。

リストの要素(リストのポインタを除く)に関する指定です。

> 受注残があるということから、受注分だけ発送できないときがあるということになります。
> 実際に発送できる量をいちいち入力するのが面倒だったので、rand関数を使っています。

受注残って、単純に発送していない受注のことではないでしょうか?

Re:多重リスト

Posted: 2010年6月26日(土) 17:07
by asdf
指定は特にないです。問題文に書かれていることがすべてです。

>受注残って、単純に発送していない受注のことではないでしょうか?

今までの累計受注が受注量で、発送していない受注が受注残量ということでしょうか。
確かにそうかもしれませんね。

とりあえず、発送のところは直しておきます。

今は、削除(または、Insert関数)のところだけお願いします。 画像

Re:多重リスト

Posted: 2010年6月26日(土) 17:29
by Poco
> 今は、削除(または、Insert関数)のところだけお願いします。

すみません、横道にそれちゃいましたね。

Insert()は問題ないと思います。

配列syohin[/url]の該当するデータのリストslinkを順々辿り、各要素(struct KANRI構造体) に対して
 0.(単方向リストなら)自要素の顧客方向へのリストに関して前の要素を取得する。
 1.顧客方向へのリストで自要素の前と後ろを連結する。
 2.自要素を解放する。
を行えば良いです。
#双方向リストだと、0の処理は不要です。

別件で、商品の削除ですが、それまでの受注情報どうしますか?
商品を削除する際に
 1.受注残データが残っていたら、削除できないようにする。
 2.受注データが残っていたら、受注データももろとも消す(注文がなかったことになる)。

Re:多重リスト

Posted: 2010年6月26日(土) 17:41
by asdf
>Insert()は問題ないと思います。

問題があると思うのですが・・・
こう思う理由は、以下のようにした場合です。(見づらいですが、よろしくお願いします)

ーー実行結果ーー

商品管理簿
何をしますか?
商品の受注:1 商品の発送:2 新規商品の追加:3 新規顧客の登録:4
商品の削除:5 顧客の削除:6 商品毎の表示(受注量 出荷量 受注残量):7
顧客毎の表示(受注個数 受注残個数):8 > 1

商品の受注を行います
顧客番号を入力> 0
商品番号を入力> 2
注文個数を入力> 39

何をしますか?
商品の受注:1 商品の発送:2 新規商品の追加:3 新規顧客の登録:4
商品の削除:5 顧客の削除:6 商品毎の表示(受注量 出荷量 受注残量):7
顧客毎の表示(受注個数 受注残個数):8 > 1

商品の受注を行います
顧客番号を入力> 0
商品番号を入力> 0
注文個数を入力> 39

何をしますか?
商品の受注:1 商品の発送:2 新規商品の追加:3 新規顧客の登録:4
商品の削除:5 顧客の削除:6 商品毎の表示(受注量 出荷量 受注残量):7
顧客毎の表示(受注個数 受注残個数):8 > 1

商品の受注を行います
顧客番号を入力> 0
商品番号を入力> 1
注文個数を入力> 30

何をしますか?
商品の受注:1 商品の発送:2 新規商品の追加:3 新規顧客の登録:4
商品の削除:5 顧客の削除:6 商品毎の表示(受注量 出荷量 受注残量):7
顧客毎の表示(受注個数 受注残個数):8 > 8
顧客番号0番 Sato Taro (tel:00-220-22)
Xbox : 30個注文 0個受取 ( 30個の受注残があります)
Wii : 39個注文 0個受取 ( 39個の受注残があります)
PS3 : 39個注文 0個受取 ( 39個の受注残があります)

合計: 108個の注文 108個の受注残

顧客番号1番 Kato Taro (tel:389-2-323)

合計: 0個の注文 0個の受注残

顧客番号2番 Tanaka Taro (tel:378-2823-2)

合計: 0個の注文 0個の受注残


何をしますか?
商品の受注:1 商品の発送:2 新規商品の追加:3 新規顧客の登録:4
商品の削除:5 顧客の削除:6 商品毎の表示(受注量 出荷量 受注残量):7
顧客毎の表示(受注個数 受注残個数):8 > 1

商品の受注を行います
顧客番号を入力> 0
商品番号を入力> 1
注文個数を入力> 33

何をしますか?
商品の受注:1 商品の発送:2 新規商品の追加:3 新規顧客の登録:4
商品の削除:5 顧客の削除:6 商品毎の表示(受注量 出荷量 受注残量):7
顧客毎の表示(受注個数 受注残個数):8 > 1

商品の受注を行います
顧客番号を入力> 0
商品番号を入力> 0
注文個数を入力> 33

何をしますか?
商品の受注:1 商品の発送:2 新規商品の追加:3 新規顧客の登録:4
商品の削除:5 顧客の削除:6 商品毎の表示(受注量 出荷量 受注残量):7
顧客毎の表示(受注個数 受注残個数):8 > 8
顧客番号0番 Sato Taro (tel:00-220-22)
Wii : 33個注文 0個受取 ( 33個の受注残があります)
Xbox : 33個注文 0個受取 ( 33個の受注残があります)
Xbox : 30個注文 0個受取 ( 30個の受注残があります)
Wii : 39個注文 0個受取 ( 39個の受注残があります)
PS3 : 39個注文 0個受取 ( 39個の受注残があります)

合計: 174個の注文 174個の受注残

顧客番号1番 Kato Taro (tel:389-2-323)

合計: 0個の注文 0個の受注残

顧客番号2番 Tanaka Taro (tel:378-2823-2)

合計: 0個の注文 0個の受注残

ーー実行結果ここまでーー

Wiiの商品番号は、0
Xboxは、1
PS3は、2
です。
本来なら、Wii→Xbox→PS3の順番で計3個出ないといけないのに、このようになってしまいます。
そもそも、1回目の表示で、Xbox→Wii→PS3となっている時点でおかしいです。

Re:多重リスト

Posted: 2010年6月26日(土) 17:45
by asdf
>配列syohin[/url]の該当するデータのリストslinkを順々辿り、各要素(struct KANRI構造体) に対して
 0.(単方向リストなら)自要素の顧客方向へのリストに関して前の要素を取得する。
 1.顧客方向へのリストで自要素の前と後ろを連結する。
 2.自要素を解放する。
を行えば良いです。


このアルゴリズム自体はわかっているのですが、上記の理由のため、どう実装したらよいかわかりませんでした・・・

>商品を削除する際に
 1.受注残データが残っていたら、削除できないようにする。
 2.受注データが残っていたら、受注データももろとも消す(注文がなかったことになる)。


なるほど。確かにそうしたほうが良いですね。
時間があればやってみます。

Re:多重リスト

Posted: 2010年6月26日(土) 20:11
by Poco
> このアルゴリズム自体はわかっているのですが、上記の理由のため、どう実装したらよいかわかりませんでした・・・

大体、問題はわかりました。
話をすすめる上で、以下を前提として置かせてください。
 ・構造体KANRIは顧客kと商品sの受注状況、発送状況を格納する。
 ・上記kとsのペアは、管理簿の中で1つしか存在しない。
  (なので注文履歴は出せません。/私はさっきまで複数あってもOKと前提を置いていました。)
 ・他の関数群に関しては、修正しない。

以上を前提とした場合、Insert(k,s,val)関数は、次のようになります。
1.顧客kのリストから商品sの注文を検索する(KANRI構造体を取得する)
 1.1商品sの注文がない場合
  1.1.1構造体KANRIのオブジェクトを作成する。
  1.1.2作成したKANRI構造体を商品sの顧客情報リストに追加する。
  1.1.3作成したKANRI構造体を顧客kの商品情報リストに追加する。

2.受注数にvalを足す。

とします。
ポイントは1.1.2と1.1.3で、これらのリストに追加する際に、ソートされた状態で追加します。
1.1.2では顧客番号順に並ぶように追加する場所を選び、1.1.3では商品番号順に並ぶように追加する場所を選びます。

Re:多重リスト

Posted: 2010年6月27日(日) 05:35
by asdf
  1.1.2作成したKANRI構造体を商品sの顧客情報リストに追加する。
  1.1.3作成したKANRI構造体を顧客kの商品情報リストに追加する。

の方法でなんとか作れました。

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

何故かエラーが出まくり、今までかかってしまいました(笑)