ここから本文です

c言語のプログラミングの問題で、エラーが出て困っています。

アバター

ID非公開さん

2019/11/2219:06:05

c言語のプログラミングの問題で、エラーが出て困っています。

コンパイルはできるのですが、実行しようとすると「セグメントエラー」となってしまいます。
どなたか原因がわかる方がいれば教えてください。
よろしくお願いします。

/* SUBSET-SUM 問題を解く列挙法のアルゴリズム */

#include <stdio.h> /* 標準入出力プロトタイプ宣言 */
#include <stdlib.h> /* 標準ライブラリプロトタイプ宣言 */
#define N 100 /* 配列a[ ]の最大サイズの定義 */
enum yn {yes, no}; /* 列挙データ型の定義 */
/* 関数の宣言 */
enum yn ssum(int *a, int b, int *x, int n);
void next(int *x, int n);

int main() {
/* メインプログラム:問題SUBSET-SUMの入出力 */
int a[N], x[N], b; /* 変数の宣言 */
int n, j;
FILE *file;

file=fopen("ssumi.d","r"); /* 入力ファイルを開く*/
fscanf(file, "%d", &n); /* ファイルからnの読込*/
if(n>N) { /* n の大きさチェック*/
printf("Illegal array size n=%d for N = %d¥n", n, N);
exit(1);
}
printf("n = %d¥na = ", n);
/* 入力データa[j]の読込み */
for(j=0; j<n; j++) fscanf(file, "%d", &a[j]);
for(j=0; j<n; j++) printf("%d ", a[j]);
printf("¥n");
fscanf(file, "%d", &b); /* 入力データbの読込み*/
printf("b = %d¥n", b);
/* 関数 ssumで問題を解く*/
if(ssum(a, b, x, n)==yes) {
printf("Yes¥nx = "); /* Yesの出力 */
/* 解の出力 */
for(j=0; j<n; j++) printf("%d", x[j]);
printf("¥n");
} else printf("No¥n"); /* Noの出力 */
return 0;
}

enum yn ssum(int *a, int b, int *x, int n) {
/* 列挙法によるSUBSET-SUMのアルゴリズム */
/* 入力データは配列 a[ ] と b. 変数は n個. 解はx[ ]に置かれる. */
int j, full, s; /* 変数の宣言 */

for(j=0; j<n; j++) x[j]=0; /* x[ ] の初期化 */
/* 2進数(0/1)ベクトルの列挙と条件のチェック */
while(1) {
s=0; /* 部分和の初期化 */
/* 2進数ベクトルx[ ]から部分和を計算 */
for(j=0; j<n; j++) s=s+x[j]*a[j];
if(s==b) return(yes); /* 解を発見 */
full=1; j=0;
do {
full=full*x[j];
j=j+1;
} while(full==1 && j<=n-1);
if(full==1) return(no); /* 解なしを結論 */
next(x, n); /* 次の2進数ベクトル*/
}
}

void next(int *x, int n) {
/* 2 進数(0/1) ベクトル(配列)x[0],...,x[n-1] を次の2進数に更新 */
int j=n-1;

do {x[j]=1-x[j]; j=j-1;} while(x[j+1]==0);
}

補足このプログラム文は先生から与えられたもので、”必要な部分を各自で付け加えて実行せよ”という課題です。
そのため、このプログラムを大幅に変えることはしなくて良いのだと思うのですがどこが間違っているのかがわからないです。
このプログラムに付け加えるor一部変えることで正しく動くプログラムにしたいです。

閲覧数:
64
回答数:
3
お礼:
100枚

違反報告

ベストアンサーに選ばれた回答

umi********さん

2019/11/2220:33:48

質問への回答ではありませんが、fopen()やfscanf()の戻り値をちゃんとチェックするようにしてください。

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

アバター

質問した人からのコメント

2019/11/24 15:37:32

何度も回答をいただきありがとうございました!
おかげで無事プログラムを実行することができました!

ベストアンサー以外の回答

1〜2件/2件中

並び替え:回答日時の
新しい順
|古い順

prwssさん

2019/11/2221:34:21

>SUBSET-SUM 問題を解く列挙法のアルゴリズム

こうします

***

#include<stdio.h>
#include<stdlib.h>

#define N 100

//#include<stdbool.h>
typedef int bool;
#define false 0
#define true 1

void show(char* caption, const int* x, const int n){
int i;
printf(caption);
for(i=0; i<n; i++){
printf("%d ", x[i]);
}
printf("\n");
}

int powint(const int a, const int n){
return n==1 ? a : a * powint(a, n-1);
}

bool getSubsetSum(const int*a, const int n, const int m){
int i;
int sum = 0;
for(i=0; i<n; i++){
sum += a[i] * ((m>>i)&1);
}
return sum;
}

void setSolution(int*x, const int n, const int m){
int i;
for(i=n-1; i>=0; i--){
x[i] = ((m>>i)&1);
}
}

bool solveSubsetSum(int *a, const int b, int *x, const int n){
const int max = powint(2, n);
int i;
for(i=1; i<max; i++){
if( b == getSubsetSum(a, n, i) ){
setSolution(x, n, i);
return true;
}
}
return false;
}

int main(void){
int a[N];
int x[N];
int b;
int n;
int i;
FILE *file;
char fn[] = "ssumi.d";

//read the file
file = fopen(fn, "r");
fscanf(file, "%d", &n);
if(n > N){
printf("Illegal array size n = %d for N = %d\n", n, N);
exit(EXIT_FAILURE);
}

for(i=0; i<n; i++){
fscanf(file, "%d", &a[i]);
}

fscanf(file, "%d", &b);

//check
printf("n = %d\n", n);
show("a = ", a, n);
printf("b = %d\n", b);

//solve
if( solveSubsetSum(a, b, x, n) ){
printf("Yes\n");
show("x = ", x, n);
}else{
printf("No\n");
}

return 0;
}

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

2019/11/2219:24:11

直接の回答ではないが

if(n>N) { /* n の大きさチェック*/



if(n>=N) { /* n の大きさチェック*/

だと思う。

あわせて知りたい

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる