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

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

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

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

Q&A

解決済

1回答

608閲覧

セグメンテーションフォルトが発生しました 対処方法について

tamura0425

総合スコア37

C

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

0グッド

0クリップ

投稿2021/08/11 14:58

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 の関数定義が与えてある。
ただし、その中身を見ることはできない。

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

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

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

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

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

guest

回答1

0

ベストアンサー

getNoint 型の整数値を返すことになっているのに文字列として扱おうとしているのが根本的な誤りでしょう。 そこで型が合わなくなって全体が破綻しています。 全体的におかしいのでここを直せばよいというようなことは申し上げられません。

投稿2021/08/11 15:27

SaitoAtsushi

総合スコア5684

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

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

tamura0425

2021/08/11 15:43

ありがとうございました。 もう一度見直してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問