ページ 1 / 1
テキストファイルに数字がそれぞれいくつ入っているか
Posted: 2015年12月16日(水) 18:15
by marimomon
お世話になっております。
現在C言語の学習をしているのですが、分からないプログラムがあります。
数字が書いてあるテキストファイルを読み込んで、数字がそれぞれ何回出たかをカウントして出力したいのですが、やり方が思いつきませんでした。
(テキストファイルの中身 例)
5
4
10
1
6
5
9
8
実際は100行くらいあります。
上の例で言うと、5は全部で2個、4は1個、10は1個、といった具合にしたいと考えています。
どなたか教えていただけると助かります。
よろしくお願いします。
Re: テキストファイルに数字がそれぞれいくつ入っているか
Posted: 2015年12月16日(水) 19:11
by box
marimomon さんが書きました:
数字が書いてあるテキストファイルを読み込んで、数字がそれぞれ何回出たかをカウントして出力したいのですが、やり方が思いつきませんでした。
とのことですが、
marimomon さんが書きました:
10
ここを
0が1個で1も1個
と数えるのではなくて
marimomon さんが書きました:
上の例で言うと、5は全部で2個、4は1個、10は1個、といった具合にしたいと考えています。
ということは、数字ではなくて数値ですね。それでよいですか?
Re: テキストファイルに数字がそれぞれいくつ入っているか
Posted: 2015年12月16日(水) 19:44
by かずま
構造体を使わずにやってみます。
コード:
#include <stdio.h>
#define 最大種類数 200
int main(void)
{
int 数値[最大種類数], 個数[最大種類数], 種類数 = 0, 値, i;
while (scanf("%d", &値) == 1) {
数値[種類数] = 値;
個数[種類数] = 0;
for (i = 0; i <= 種類数; i++)
if (数値[i] == 値) break;
if (i == 最大種類数) {
printf("データが多すぎる\n");
return 1;
}
個数[i]++;
if (i == 種類数) 種類数++;
}
for (i = 0; i < 種類数; i++)
printf("%8d: %d\n", 数値[i], 個数[i]);
return 0;
}
入力データ
コード:
32767
4096
2016
1
12
2015
12
16
2015
5
12
実行結果
コード:
32767: 1
4096: 1
2016: 1
1: 1
12: 3
2015: 2
16: 1
5: 1
結果は昇順に、とかではなくてかまいませんよね。
標準入力から読み込んでいるので、テキストファイルから読み込みたかったら、
コマンドラインのリダイレクトを使うか、自分でファイルをオープンするコードを
追加してください。できたら、ソースをここに貼ってくださいね。
ところで、コンパイラは何ですか?
Re: テキストファイルに数字がそれぞれいくつ入っているか
Posted: 2015年12月16日(水) 19:57
by かずま
かずま さんが書きました:
コード:
for (i = 0; i <= 種類数; i++)
if (数値[i] == 値) break;
あ、間違えた。次のように書くつもりだったんです。
コード:
for (i = 0; 数値[i] != 値; i++) ;
このように書き方は何通りもあります。
このプログラムを参考に独自のコードを書いてください
Re: テキストファイルに数字がそれぞれいくつ入っているか
Posted: 2015年12月17日(木) 10:43
by かずま
かずま さんが書きました:
コード:
int 数値[最大種類数], 個数[最大種類数], 種類数 = 0, 値, i;
誰からも指摘がありませんが、このプログラムにはバグがあります。
int 数値[最大種類数+1], 個数[最大種類数+1],
にしないと、データ数が多過ぎる場合、範囲外アクセスで死にます。
コンパイラは何ですか?
と聞いたのは、最近の VC++ ではこのままコンパイルできるからです。
Re: テキストファイルに数字がそれぞれいくつ入っているか
Posted: 2015年12月17日(木) 11:34
by marimomon
boxさん
その通りです。
数字ではなく数値の間違いでした。
Re: テキストファイルに数字がそれぞれいくつ入っているか
Posted: 2015年12月17日(木) 11:37
by marimomon
かずまさん
サンプルを載せてくださり、ありがとうございます。
使用しているコンパイラはgccです。
Re: テキストファイルに数字がそれぞれいくつ入っているか
Posted: 2015年12月22日(火) 14:25
by marimomon
かずまさん
本当に初歩的な質問かもしれませんが、かずまさんが書かれたプログラムを、標準入力ではなく配列に格納されているデータについて判別するにはどうしたらいいですか?
例えば
a[10]
に
[10, 5, 4, 10, 7, 0, 0, 0, 3, 9]
というデータが入っていた時、どうすればいいのでしょうか?
大学の授業に全くついていけていないのですが、どうにかしたいと思っています。
よろしくお願いします。
Re: テキストファイルに数字がそれぞれいくつ入っているか
Posted: 2015年12月23日(水) 08:28
by かずま
int a[10] = { 10, 5, 4, 10, 7, 0, 0, 0, 3, 9 };
を追加してください。
main() の中に書く場合は、
static int a[10] = { 10, 5, 4, 10, 7, 0, 0, 0, 3, 9 };
にしたほうが良いでしょう。
scanf() の行を
コード:
for (j = 0; j < 10; j++) {
値 = a[j];
に置き換える
あなたのソースプログラムをここに貼ってください。
Re: テキストファイルに数字がそれぞれいくつ入っているか
Posted: 2015年12月23日(水) 14:25
by marimomon
かずまさん
ありがとうございます。
プログラムのアルゴリズムの部分はこちらになります。
コード:
static int aa[10]={10,5,4,10,7,0,0,0,3,9};
int bb[10];
int num;
int suuti[10], kosuu[10], syuruisuu = 0, atai;
for(j=0;j<10;j++)
{
atai=a[j];
kosuu[syuruisuu] = 0;
for (i = 0; i <= syuruisuu; i++)
if (suuti[i] == atai) break;
if (i == 10) {
printf("データが多すぎる\n");
return 1;
}
kosuu[i]++;
if (i == syuruisuu) syuruisuu++;
}
for (i = 0; i < syuruisuu; i++)
printf("%8d: %d\n", suuti[i], kosuu[i]);
実行してもエラーを吐かれてしまいます。
Re: テキストファイルに数字がそれぞれいくつ入っているか
Posted: 2015年12月23日(水) 14:47
by みけCAT
marimomon さんが書きました:実行してもエラーを吐かれてしまいます。
そうですか。じゃあ修正すればいいでしょう。
例えば、「数値[種類数] = 値;」にあたるコードが無いので、それを追加するといいでしょう。
実行したということは、少なくともコンパイルは通ったのですね?
Re: テキストファイルに数字がそれぞれいくつ入っているか
Posted: 2015年12月23日(水) 14:47
by box
marimomon さんが書きました:
実行してもエラーを吐かれてしまいます。
どういうエラーが出るかを正確に書かないと、ちゃんと説明したことにはなりません。
「エラーが出る」だけだと、「ふ~ん。それで?」となるだけです。
Re: テキストファイルに数字がそれぞれいくつ入っているか
Posted: 2015年12月23日(水) 15:00
by marimomon
ありがとうございます。
エラーの原因は内容と関係がないものでした。
コード:
#include<stdio.h>
int main(void)
{
static int aa[10]={10,5,4,10,7,0,0,0,3,9};
int bb[10];
int num;
int i,j;
int suuti[10], kosuu[10], syuruisuu = 0, atai;
for(j=0;j<10;j++)
{
suuti[syuruisuu]=atai;
atai=aa[j];
kosuu[syuruisuu] = 0;
for (i = 0; i <= syuruisuu; i++)
if (suuti[i] == atai) break;
if (i == 10) {
printf("データが多すぎる\n");
return 1;
}
kosuu[i]++;
if (i == syuruisuu) syuruisuu++;
}
for (i = 0; i < syuruisuu; i++)
printf("%8d: %d\n", suuti[i], kosuu[i]);
return 0;
}
を実行したところ、
0:2
という結果しか出力されませんでした。
原因が分かるようでしたら教えていただけると助かります。
Re: テキストファイルに数字がそれぞれいくつ入っているか
Posted: 2015年12月23日(水) 15:05
by みけCAT
ataiに値を代入する処理の位置が間違っているので、未初期化の値や古い値が処理に使用されていますね。
そのため、入力の数値が連続で同じものになっている部分以外では
i == syuruisuuという条件が真にならず、syuruisuuがインクリメントされないからでしょう。
Re: テキストファイルに数字がそれぞれいくつ入っているか
Posted: 2015年12月23日(水) 15:16
by marimomon
コード:
static int aa[10]={10,5,4,10,7,0,0,0,3,9};
int bb[10];
int num;
int i,j;
int suuti[10], kosuu[10], syuruisuu = 0, atai;
for(j=0;j<10;j++)
{
atai=aa[j];
suuti[syuruisuu]=atai;
kosuu[syuruisuu] = 0;
for (i = 0; i <= syuruisuu; i++)
if (suuti[i] == atai) break;
if (i == 10) {
printf("データが多すぎる\n");
return 1;
}
kosuu[i]++;
if (i == syuruisuu) syuruisuu++;
}
for (i = 0; i < syuruisuu; i++)
printf("%8d: %d\n", suuti[i], kosuu[i]);
のように、ataiに代入する処理の位置をfor文の頭に持ってきたらうまくいきました。
アドバイスくださった方々、本当にありがとうございました!
Re: テキストファイルに数字がそれぞれいくつ入っているか
Posted: 2015年12月23日(水) 22:49
by かずま
No.3 でサンプルプログラムを提示し、
No.4 で forループの継続条件と終了条件を一つにまとめる修正を示し、
No.5 で、バグを修正しているのに、
なぜ、ちゃんと反映させないのか不思議でなりません。
コードの意味なんて全然考えていないのでしょう。
また、最大種類数とデータの個数は異なるものです。
どっちも 10 と書いたら、どちらかを変更したくなったとき、どこを直して
どこを直さないかわからず困るでしょう。
バグの件ですが、試しに次のようにデータの個数を増やすと、
コード:
static int a[15] = { 10, 5, 4, 10, 7, 0, 0, 0, 3, 9, 1, 6, 8, 1, 4 };
for (j = 0; j < 15; j++) {
データが多すぎるというエラーメッセージが出ずに、実行が不正終了するでしょう。
変数名を漢字で書くのは面倒なので、通常通り書いてみます。
コード:
#include <stdio.h>
#define MAX_N 10
#define DATA_SIZE 15
int main()
{
static int a[DATA_SIZE] = {
10, 5, 4, 10, 7, 0, 0, 0, 3, 9, 1, 6, 8, 1, 4
};
int value[MAX_N + 1], count[MAX_N + 1], n = 0, i, j; // No.5
for (j = 0; j < DATA_SIZE; j++) {
value[n] = a[j];
count[n] = 0;
for (i = 0; value[i] != a[j]; i++) ; // No.4
if (i == MAX_N) {
printf("データが多すぎる\n");
return 1;
}
count[i]++;
if (i == n) n++;
}
for (i = 0; i < n; i++)
printf("%8d: %d\n", value[i], count[i]);
return 0;
}