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

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

新規登録して質問してみよう
ただいま回答率
85.46%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

852閲覧

構造体の使い方についてアドバイスを頂きたい

blitz

総合スコア1

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2021/12/18 16:50

前提・実現したいこと

構造体の使い方について,アドバイスを頂きたい。

発生している問題・エラーメッセージ

構造体を定義し,scanf関数を用いてナップサック問題を解くプログラムコードを作成しています。
構造体へ値を格納することはできているのですが,うまく所望の関数に値が渡されていないようで,最適解を求められずにいます。
構造体の使い方が間違っている点などを指摘していただけたら幸いです。

該当のソースコード

C

1typedef struct { 2 int N, c; 3 int value[256], weight[256]; 4} ksdata; 5 6int knapsack(int a, int b); 7 8int main(void){ 9 10 ksdata data; 11 ksdata *pdata; 12 13 pdata = &data; 14 15 int i; 16 printf("Input capacity of knapsuck as a positive integer.\n"); 17 scanf("%d", &(*pdata).c); 18 printf("Input number of items as a positive integer.\n"); 19 scanf("%d", &(*pdata).N); 20 21 for(i=0; i<(*pdata).N; i++){ 22 printf("Input #%d item's value as a positive integer.\n", i+1); 23 scanf("%d", &(*pdata).value[i]); 24 printf("Input #%d item's weight as a positive integer.\n", i+1); 25 scanf("%d", &(*pdata).weight[i]); 26 } 27 28int answer = knapsack(0, (*pdata).c); 29 30printf("%d\n", answer); 31 32return 0; 33} 34 35int knapsack(int a, int b) { 36 int put_value; //品物を入れた場合の価値を格納する変数 37 int no_put_value; //品物を入れない場合の価値を格納する変数 38 int max_value; //最大価値(解)を格納する変数 39 40 ksdata data; 41 ksdata *pdata; 42 pdata = &data; 43 int N = (*pdata).N; 44 45 if (a > N-1) return 0; //入れる品物がない場合,0を返却 46 47 no_put_value = knapsack(a+1, b); //品物iを入れなかった場合の最大価値を求める→knapsack(i+1,c)を実行(*iは入れていないのでcは変化しない) 48 49 /* 品物iがナップサックに入る場合,品物を入れる */ 50 if ((*pdata).weight[a] <= b){ //品物iがまだナップサックに入る場合(ナップサックの容量以下) 51 52 /* 品物iを入れた場合の最大価値を求める → 品物iを入れるのでナップサックの容量cはweight[i]分減り,価値はvalue[i]だけ増える */ 53 put_value = knapsack(a+1, b-(*pdata).weight[a]) + (*pdata).value[a]; 54 } else { 55 /* もう品物iがナップサックに入らない場合 */ 56 57 put_value = -1;//価値は-1(no_put_valueよりも必ず小さい値)としておく(no_put_valueよりも大きな値だと,今後の比較に支障が出る) 58 } 59 60 /* 品物iを入れた場合と入れなかった場合の大きい方の価値を返却 */ 61 if (no_put_value > put_value) { 62 max_value = no_put_value; 63 } else { 64 max_value = put_value; 65 } 66 67 return max_value; 68}

試したこと

構造体のポインタ

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2021/12/18 17:23 編集

具体的に状況をご説明頂けますか。 >うまく所望の関数に値が渡されていないようで というのは、どのように入力したらどの表示がどうなるはずがどうなったのでしょうか。 > 試したこと > 構造体のポインタ 構造体のポインタ・・・をどういうお考えで、どうコードに反映して試されたのでしょうか。 その結果はどうなったのでしょう。 knapsack 関数の中に、各変数の値を確認するような表示が一切見当たりませんが、関数の動作についてどこまで確認されていますでしょうか。
blitz

2021/12/18 17:41

お騒がせいたしました。「cx20」様の解答で解決することができました。 質問内容が抽象的で伝わりにくく,申し訳ありません。 この度は初歩的な質問に対応してくださってありがとうございます。
guest

回答1

0

ベストアンサー

うまく所望の関数に値が渡されていない

main() 関数と knapsack() 関数で、それぞれ ksdata data; を宣言していますが、関数内で宣言した変数はローカル変数と呼ばれ、その関数の中でしか利用できません。(つまり関数に値が渡っていません。)

試しに ksdata data;ローカル変数ではなくグローバル変数に変更してみて下さい。
main() 関数の外で宣言した変数がグローバル変数となります。

<参考>
■ 【C言語】動的計画法をナップサック問題を解いて理解する
https://daeudaeu.com/knapsack-bydp/

投稿2021/12/18 17:25

cx20

総合スコア4633

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

blitz

2021/12/18 17:36

恥ずかしながらローカル変数の性質を忘れていました。 また,グローバル変数は#define文で記述されるものだと大きな勘違いをしておりました。 関数の外で構造体変数を宣言した結果,ポインタを使うことなく所望の解を求めることができました。 この度は貴重なアドバイスありがとうございます!
cx20

2021/12/18 17:42

ちなみに、このサンプルの場合、ポインタを使う必要はありません。(現状、意味のない使い方となっています。) 「ksdata *pdata;」を使わない形に変更してみて下さい。
blitz

2021/12/18 18:03

わかりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問