テキストファイルに数字がそれぞれいくつ入っているか

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
marimomon

テキストファイルに数字がそれぞれいくつ入っているか

#1

投稿記事 by marimomon » 9年前

お世話になっております。

現在C言語の学習をしているのですが、分からないプログラムがあります。
数字が書いてあるテキストファイルを読み込んで、数字がそれぞれ何回出たかをカウントして出力したいのですが、やり方が思いつきませんでした。

(テキストファイルの中身 例)
5
4
10
1
6
5
9
8

実際は100行くらいあります。
上の例で言うと、5は全部で2個、4は1個、10は1個、といった具合にしたいと考えています。

どなたか教えていただけると助かります。
よろしくお願いします。

box
記事: 2002
登録日時: 14年前

Re: テキストファイルに数字がそれぞれいくつ入っているか

#2

投稿記事 by box » 9年前

marimomon さんが書きました: 数字が書いてあるテキストファイルを読み込んで、数字がそれぞれ何回出たかをカウントして出力したいのですが、やり方が思いつきませんでした。
とのことですが、
marimomon さんが書きました: 10
ここを
0が1個で1も1個
と数えるのではなくて
marimomon さんが書きました: 上の例で言うと、5は全部で2個、4は1個、10は1個、といった具合にしたいと考えています。
ということは、数字ではなくて数値ですね。それでよいですか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

かずま

Re: テキストファイルに数字がそれぞれいくつ入っているか

#3

投稿記事 by かずま » 9年前

構造体を使わずにやってみます。

コード:

#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: テキストファイルに数字がそれぞれいくつ入っているか

#4

投稿記事 by かずま » 9年前

かずま さんが書きました:

コード:

		for (i = 0; i <= 種類数; i++)
			if (数値[i] == 値) break;
あ、間違えた。次のように書くつもりだったんです。

コード:

		for (i = 0;  数値[i] != 値; i++) ;
このように書き方は何通りもあります。
このプログラムを参考に独自のコードを書いてください

かずま

Re: テキストファイルに数字がそれぞれいくつ入っているか

#5

投稿記事 by かずま » 9年前

かずま さんが書きました:

コード:

	int 数値[最大種類数], 個数[最大種類数], 種類数 = 0, 値, i;
誰からも指摘がありませんが、このプログラムにはバグがあります。
int 数値[最大種類数+1], 個数[最大種類数+1],
にしないと、データ数が多過ぎる場合、範囲外アクセスで死にます。

コンパイラは何ですか?
と聞いたのは、最近の VC++ ではこのままコンパイルできるからです。

marimomon

Re: テキストファイルに数字がそれぞれいくつ入っているか

#6

投稿記事 by marimomon » 9年前

boxさん

その通りです。
数字ではなく数値の間違いでした。

marimomon

Re: テキストファイルに数字がそれぞれいくつ入っているか

#7

投稿記事 by marimomon » 9年前

かずまさん

サンプルを載せてくださり、ありがとうございます。
使用しているコンパイラはgccです。

marimomon

Re: テキストファイルに数字がそれぞれいくつ入っているか

#8

投稿記事 by marimomon » 9年前

かずまさん

本当に初歩的な質問かもしれませんが、かずまさんが書かれたプログラムを、標準入力ではなく配列に格納されているデータについて判別するにはどうしたらいいですか?
例えば
a[10]

[10, 5, 4, 10, 7, 0, 0, 0, 3, 9]
というデータが入っていた時、どうすればいいのでしょうか?
大学の授業に全くついていけていないのですが、どうにかしたいと思っています。

よろしくお願いします。

かずま

Re: テキストファイルに数字がそれぞれいくつ入っているか

#9

投稿記事 by かずま » 9年前

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];
に置き換える

あなたのソースプログラムをここに貼ってください。

marimomon

Re: テキストファイルに数字がそれぞれいくつ入っているか

#10

投稿記事 by marimomon » 9年前

かずまさん

ありがとうございます。

プログラムのアルゴリズムの部分はこちらになります。

コード:

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]);

実行してもエラーを吐かれてしまいます。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: テキストファイルに数字がそれぞれいくつ入っているか

#11

投稿記事 by みけCAT » 9年前

marimomon さんが書きました:実行してもエラーを吐かれてしまいます。
そうですか。じゃあ修正すればいいでしょう。
例えば、「数値[種類数] = 値;」にあたるコードが無いので、それを追加するといいでしょう。
実行したということは、少なくともコンパイルは通ったのですね?
最後に編集したユーザー みけCAT on 2015年12月23日(水) 14:49 [ 編集 1 回目 ]
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 2002
登録日時: 14年前

Re: テキストファイルに数字がそれぞれいくつ入っているか

#12

投稿記事 by box » 9年前

marimomon さんが書きました: 実行してもエラーを吐かれてしまいます。
どういうエラーが出るかを正確に書かないと、ちゃんと説明したことにはなりません。
「エラーが出る」だけだと、「ふ~ん。それで?」となるだけです。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

marimomon

Re: テキストファイルに数字がそれぞれいくつ入っているか

#13

投稿記事 by marimomon » 9年前

ありがとうございます。

エラーの原因は内容と関係がないものでした。

コード:

#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

という結果しか出力されませんでした。
原因が分かるようでしたら教えていただけると助かります。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: テキストファイルに数字がそれぞれいくつ入っているか

#14

投稿記事 by みけCAT » 9年前

ataiに値を代入する処理の位置が間違っているので、未初期化の値や古い値が処理に使用されていますね。
そのため、入力の数値が連続で同じものになっている部分以外では
i == syuruisuuという条件が真にならず、syuruisuuがインクリメントされないからでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

marimomon

Re: テキストファイルに数字がそれぞれいくつ入っているか

#15

投稿記事 by marimomon » 9年前

コード:

	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: テキストファイルに数字がそれぞれいくつ入っているか

#16

投稿記事 by かずま » 9年前

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;
}

閉鎖

“C言語何でも質問掲示板” へ戻る