c言語初心者です。
以下の課題を出されたので、コードを記載したのですが、「セグメンテーションフォルトが発生しました」のエラーがでてしまい。どのようにコードを書きなしたらよいかわからず困っております。
#include <stdio.h> #include <stdlib.h> #include <limits.h> #include "oracle.h" int compare(const void *x, const void *y){ return *(int *)x - *(int *)y ;} int main(int argc, char *argv[]){ int i,j; // 入力値 int n; // 文字列配列 char** arrStr; // 出現回数の最大値 int m; // 出現回数加算用ワーク int same_cnt; // その最大回数出現した文字列の種類数 int k; // input & check if (argc != 2) { printf("input errorr argc!=2:%d\n",argc); exit(-1); } n = atoi(argv[1]); if ( !(n > 0 && n <= 2000000 ) ) { printf("input errorr n:%d\n",n); exit(-1); } // 長さ n のデータ列を設定 setup(n); // 全ての文字列を取得 arrStr = calloc(sizeof(char *),n); for(i=0;(arrStr[i]=getNo())!= INT_MIN;i++) ; // 文字列配列のソート qsort(arrStr,n,sizeof(char *),compare); // // 文字列検査 m=k=same_cnt=1; // for(i=0; i!=n-2;i++) { j=i+1; while(1){ // 同じ文字列が続く場合 if ( strcmp(arrStr[i],arrStr[j]) == 0 ) { same_cnt++; j++; // 配列の最後の場合ループ終了 if (j>n-1) break; // 異なる文字列が現れた場合 } else { // 最大値の更新 if (m<same_cnt){ m=same_cnt; k=1; } // 出現回数のカウントアップ if (m==same_cnt){ k++; } same_cnt=1; //出現回数の初期化 i=(j-1); //文字列配列のサーチ位置を更新 break; } } } free(arrStr); // 2回以上出現回数がある場合に出力 if (m!=1) printf("%d(%d)\n",m,k-1); return 0; }
問題内容
個の非負整数値からなるデータの列が与えられたとき、それら全てを読み取って2度以上現れる(重複して現れる)値の有無を調べるプログラムを作れ。
入力
コマンドライン入力から正整数 n( 0 < n ≦ 2000000 )が与えられる。データの列は、つぎの2つの関数を使って得る。
void setup(int n);
// 長さ n のデータ列を設定する
int getNo();
// setup で設定されたデータの列から次の数値を1つ取り出して返してくる
// データの列が尽きているなら -2^31 を返してくる
なお、-2^31 は int型(32ビット)の最小値である。ライブラリ limits にマクロ INT_MIN として定義されている。
出力
2度以上現れる数値が存在しなければ、何も出力しないで実行を終了する。2度以上現れる数値が存在していれば、現れた回数が最も大きな数値の出現回数 m を求め、かつ、その出現回数をもつ数値が何種類存在したかを、つぎの形の1行として標準出力に書き出す。
m(k)
m 出現回数の最大値
k その最大回数出現した数値の種類数
二つの数値 m、k は必要最小限の桁数で書き出す
補足説明
数値列の具体例に対する出力例を示す。
数値列 出力 説明
8 3 9 1 2 5 4 なし 2度以上現れる数値がない
8 3 8 1 2 5 4 2(1) 2度が最大回数。その数値は8だけの1種類
8 3 8 1 2 5 1 2(2) 2度が最大回数。その数値は8,1の2種類
8 3 8 1 2 3 1 2(3) 2度が最大回数。その数値は8,3,1の3種類
8 3 8 1 2 8 1 3(1) 3度が最大回数。その数値は8だけの1種類
8 3 3 3 2 8 3 4(1) 4度が最大回数。その数値は3だけの1種類
実行例
コマンドライン入力
1000
標準出力
2(5)
コマンドライン入力
3000
標準出力
3(3)
実用的な高速性をもって整列を行う関数 qsort がライブラリ stdlib に用意されている。それを用いて、得られた数値をまず整列した上で数値の重複の状況を調査する。
数値列を得るためのファイル oracle.h、oracle.c
oracle.c には、関数 setup と getNo の関数定義が与えてある。
ただし、その中身を見ることはできない。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/08/11 15:43