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

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

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

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

Q&A

解決済

2回答

729閲覧

すべての組み合わせの列挙

gekko

総合スコア16

C

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

0グッド

0クリップ

投稿2020/02/12 15:41

編集2020/02/13 09:00

商品の情報をファイルから入手し、入力された予算に応じて買うことのできる全ての組み合わせを列挙する問題です。お助けいただけると幸いです。書いたコード貼っときます。()
例)F1.txt(name price amount /商品は10個と確定しています。)
Apple 1 20
Banana 4 25
Peach 4 34
Grape 4 3
Strawberry 2 40
Blueberry 3 9
Rice 10 2
Egg 1 22
Pen 6 10
Note 1 19

c

1#include <stdio.h> 2#include <float.h> 3#define rep(i,n) for(int i = 0; i < (n); ++i) 4 5typedef struct{ 6 char name[30]; 7 float price; 8 int amount; 9}Data; 10 11float budget; 12 13void input(FILE* fi, Data* data) { 14 rep(i,10) { 15 fscanf(fi,"%s %f %d", (data+i)->name, &(data+i)->price, &(data+i)->amount); 16 } 17} 18 19int check(Data* data) { 20 int f = 0; 21 rep(i,10){ 22 if(budget >= (data+i)->price) f++; 23 } 24 if(f==0) printf("you don't have enough money:'(\n"); 25 return f; 26} 27 28 29int count = 0; 30//the number of all possible combinations 31void pick(Data* data, int index, int maxindex, float price) { 32 if(maxindex <= index) return; 33 float newprice = price + (data+index)->price; 34 if(newprice <= budget){ 35 count++; 36 pick(data, index+1, maxindex, newprice); 37 } 38 pick(data, index+1, maxindex, price); 39 40} 41 42int main(){ 43 Data p[10]; 44 Data *q = &p; 45 char ni[10] ="F1.txt"; 46 FILE *fi; 47 fi = fopen(ni,"r"); 48 printf("insert your budget!!\n"); 49 scanf("%f", &budget); 50 input(fi, q); 51 int C = check(q); 52 if(C == 0) return 0; 53 pick(q, 1, 9, 0); 54 printf("%d", count); 55 /*rep(i,10) { 56 printf("%s %f %d\n", (q+i)->name, (q+i)->price, (q+i)->amount); 57 }*/ 58 59 return 0; 60 61} 62 63 64 65 66 67 68

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

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

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

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

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

guest

回答2

0

いわゆるナップサック問題ですね

ナップサック問題は大体条件があるので、
枝刈りという、その条件に合致しないパターンであれば探索を打ち切る仕組みが入りますが、
この例だとすべて列挙なので枝刈りも必要ないです

ちょっと修正して、1が3つあるとき、最大2円で6が返ってくるのを確認しました

#include <stdio.h> struct Data{ float price; }; int pick(Data *data, int index, int maxindex, float price, float maxprice){ int count = 0; if (maxindex <= index) return 0; float newprice = price + data[index].price; if (newprice <= maxprice){ (count)++; // indexの商品を追加して次の工程に count += pick(data, index + 1, maxindex, newprice, maxprice); } // indexの商品を追加せずに次の工程に count += pick(data, index + 1, maxindex, price, maxprice); return count; } int main(){ Data d[] = {{1}, {1}, {1}}; int count = pick(d, 0, 3, 0, 2); printf("%d", count); }

投稿2020/02/12 22:13

編集2020/02/13 09:42
izmktr

総合スコア2856

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

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

gekko

2020/02/12 22:23

ありがとうございます!参考にさせていただきます!
gekko

2020/02/12 23:09

何通りかはは出すことができました。問題は実際に全ての組み合わせをターミナルに表示しなければならないのでその部分をどうしたらいいか実装してみます。!
kazuma-s

2020/02/13 01:47

何通りか出すことができるそのコードと、10個のデータを書いた F1.txt を質問に追加してもらうと、私の回答を示せます。あと、何通りか出すことができた時に使った予算の値もお願いします。
gekko

2020/02/13 09:03

気づいたのですが1とかで試してみると1としかかえってこなくて、本当は価格が1のものが3つあるので3と返したいのですが。。もうすこし変えてみます!
gekko

2020/02/13 09:26

あと個数も入れなくちゃいけなくてもしお助けいただけるとうれしいです
guest

0

ベストアンサー

質問のコードの main で、Data *q = &p; の行で警告が出ませんか?
使用しているコンパイラは何ですか?

C

1#include <stdio.h> 2 3typedef struct { 4 char name[30]; 5 float price; 6 int amount; 7} Data; 8 9float budget; 10 11void input(FILE *fi, Data *data) 12{ 13 for (int i = 0; i < 10; i++) 14 fscanf(fi,"%s %f %d", data[i].name, &data[i].price, &data[i].amount); 15} 16 17int check(const Data *data) 18{ 19 for (int i = 0; i < 10; i++) 20 if (budget >= data[i].price) return 1; 21 printf("you don't have enough money:'(\n"); 22 return 0; 23} 24 25void search(const Data *data, int i, float money, int *count) 26{ 27 if (i == 10) { 28 const char *sep = ""; 29 for (int j = 0; j < 10; j++) 30 if (count[j] > 0) { 31 printf("%s%s %d", sep, data[j].name, count[j]); 32 sep = ", "; 33 } 34 putchar('\n'); 35 } 36 else 37 for (count[i] = 0; count[i] <= data[i].amount; count[i]++) { 38 float cost = data[i].price * count[i]; 39 if (cost > money) return; 40 search(data, i + 1, money - cost, count); 41 } 42} 43 44int main(void) 45{ 46 Data data[10]; 47 int count[10]; 48 FILE *fi = fopen("F1.txt", "r"); 49 if (!fi) return 1; 50 printf("insert your budget!!\n"); 51 scanf("%f", &budget); 52 input(fi, data); 53 fclose(fi); 54 if (check(data)) search(data, 0, budget, count); 55 return 0; 56}

このように書いてみましたが、これは期待するものでしょうか?

投稿2020/02/13 09:26

kazuma-s

総合スコア8224

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

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

gekko

2020/02/13 09:44

ありがとうございます! はい!!これがしたかったんです。ほんとにあろがとうございます!!
kazuma-s

2020/02/13 18:38

質問のコードの main で、Data *q = &p; の行で警告が出ませんか? 使用しているコンパイラは何ですか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問