【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※マルチポスト(多重投稿)は謹んで!

 詳しくはこちら



 本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール   掲示板2こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.19474

入力した語の出現頻度を求める
投稿者---あつし(2005/01/25 17:54:01)


入力した語の出現頻度を求めるプログラムを作成してるのですが、
ソースの部分がうまくいっていないみたいなのです。
実行しても重複した語句が直り、違う種類の語句が
出てくるだけなのです。
よろしくお願いします。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

typedef struct{
    char *words;
    int count;
}Word;

void error(char *s)
{
    fprintf(stderr,"%s\n",s);
    exit(1);
}
char *strsave(char *s)
{
    char *p;
    if((p=malloc(strlen(s)+1))==NULL)
        error("can not get memory for string");
    strcpy(p,s);
    return(p);
}
int regist_string(char *s,int smax,char *pw[])
{
    int i;
    for(i=0;i<smax;++i)
        if(!strcmp(s,pw[i]))
            return smax;
        pw[smax++]=strsave(s);
        return(smax);
}
void sortlist(int cmax,char *pw[])
{
    int gap,i,j,n;
    char *p,*w;
    for(i=0;i<n;++i){
        for(j=i;j<n;++j){
            if(strcmp(pw[j],pw[i])<0){
                w=pw[j];
                pw[j]=pw[i];
                pw[i]=w;
            }
        }
    }
}
int getword(int bmax,char *s)
{
    int c,i=0;
    for(i=0;i<bmax-1;++i){
        if(('a'<=(c=getchar())&&c<='z')
||      ('A'<=c&&c<='Z'))
            *s++=c;
        else
            break;
    }
    *s='\0';
    if(c==EOF&&i<=0)i=-1;
    return(i);
}
int main(int argc,char *argv[])
{
    int i,smax,len;
    char str[80];
    char *words[2048];

    smax=0;
    while(len=getword(80,str)){
        if(len==0)continue;
        smax=regist_string(str,smax,words);
    }
    sortlist(smax,words);
    for(i=0;i<smax;++i)
        printf("%d:%s\n",,words[i]);
}




この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:入力した語の出現頻度を求める 19475 nop 2005/01/25 18:00:26
<子記事> Re:入力した語の出現頻度を求める 19481 RiSK 2005/01/25 22:20:52
<子記事> Re:入力した語の出現頻度を求める 19483 HALLS 2005/01/25 23:17:46


No.19475

Re:入力した語の出現頻度を求める
投稿者---nop(2005/01/25 18:00:26)


>入力した語の出現頻度を求めるプログラムを作成してるのですが、
>ソースの部分がうまくいっていないみたいなのです。

過去ログに、同一の課題が多々あるので、
まずはそちらを参照しては如何でしょうか?


この投稿にコメントする

削除パスワード

No.19476

Re:入力した語の出現頻度を求める
投稿者---あつし(2005/01/25 19:57:03)


>過去ログに、同一の課題が多々あるので、
>まずはそちらを参照しては如何でしょうか?
実はそれを見たのですが、すべてファイルを参照したものであって、
ちょっと考え方が違ったみたいなんです。。。
ややこしいのですがよろしくお願いします。。。!!!


この投稿にコメントする

削除パスワード

No.19478

Re:入力した語の出現頻度を求める
投稿者---REE(2005/01/25 20:21:54)


>>過去ログに、同一の課題が多々あるので、
>>まずはそちらを参照しては如何でしょうか?
>実はそれを見たのですが、すべてファイルを参照したものであって、
>ちょっと考え方が違ったみたいなんです。。。
>ややこしいのですがよろしくお願いします。。。!!!

入力がファイルであろうと直接であろうと、基本的な部分は変わらないはずです。
まずは、そちらを理解してみましょう。


この投稿にコメントする

削除パスワード

No.19480

Re:入力した語の出現頻度を求める
投稿者---あつし(2005/01/25 20:25:43)


>入力がファイルであろうと直接であろうと、基本的な部分は変わらないはずです。
>まずは、そちらを理解してみましょう。
そうなんですが、構造体を使ってないものなので、そこもまた違うんです・・・ポインタのみ使っているんですが、最後のところで、
頻度の数を出力するんですけど、それは、iではなくて、
べつに格納しなければならないのですか?


この投稿にコメントする

削除パスワード

No.19481

Re:入力した語の出現頻度を求める
投稿者---RiSK(2005/01/25 22:20:52)


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

#define BUF_SIZE 80
#define MAX_WORD_NUM 2048
#define Error(msg) fprintf(stderr,"%s [Line:%d]\n", msg, __LINE__), exit(1)

typedef struct {
    char * word;
    int freq;
} WORD;

char * strdup(const char * s)
{
    char * p;
    if ((p = malloc(strlen(s)+1)) == NULL) {
        Error("Out of memory.");
    }
    return strcpy(p, s);
}

int GetWord(char * s, int len)
{
    int c, i = 0;
    while (i < len-1 && (c = getchar()) != EOF && c != '\n') {
        if (isalpha(c)) {
            s[i++] = c;
        }
    }
    s[i] = '\0';
    return i;
}

int RegistWord(char * s, int smax, WORD words[])
{
    int i;
    for (i = 0; i < smax; ++i) {
        if (strcmp(s, words[i].word) == 0) {
            ++words[i].freq;
            return 0;
        }
    }
    words[i].word = strdup(s);
    return 1;
}

int CompareWord(const void * e1, const void * e2)
{
    const WORD * w1 = e1;
    const WORD * w2 = e2;
    return w2->freq - w1->freq;
}

int main(int argc, char * argv[])
{
    char buf[BUF_SIZE];
    int smax = 0, i;
    WORD words[MAX_WORD_NUM] = {0};
    while(GetWord(buf, BUF_SIZE)){
        smax += RegistWord(buf, smax, words);
    }
    qsort(words, smax, sizeof(WORD), CompareWord);
    for (i = 0; i < smax; ++i) {
        printf("%d:%s %d回\n", i+1, words[i].word, words[i].freq);
        free(words[i].word);
    }
    return 0;
}



この投稿にコメントする

削除パスワード

No.19484

Re:入力した語の出現頻度を求める
投稿者---あつし(2005/01/25 23:56:56)


ありがとうございます。そこで実行してみたのですが、Ctrl+zを押してもループからぬけないみたいなんです。。。あと、qsortの中のsizeofといのはint型みたいな型宣言のものなのでしょうか?qsortを今まで使ったことがなく、まだ全然理解できてなくて。。。
すみませんが、よろしくお願いします。


この投稿にコメントする

削除パスワード

No.19486

Re:入力した語の出現頻度を求める
投稿者---RiSK(2005/01/26 00:49:25)


>ありがとうございます。そこで実行してみたのですが、Ctrl+zを押してもループからぬけないみたいなんです。。。

押しても抜けますし,押さなくても抜けます。
アルファベットが一文字もなければ抜けるのですから。

>あと、qsortの中のsizeofといのはint型みたいな型宣言のものなのでしょうか?qsortを今まで使ったことがなく、まだ全然理解できてなくて。。。

管理人さんのウェブページを参考にしてください。
14−4.sizeof演算子
# 全角文字やめてください。コンパイルエラーになります。


>すみませんが、よろしくお願いします。

# 猛烈にデジャビュ。くらくらする。何なんだ???


この投稿にコメントする

削除パスワード

No.19494

Re:入力した語の出現頻度を求める
投稿者---Craft(2005/01/26 12:11:44)


>qsortを今まで使ったことがなく、まだ全然理解できてなくて。。。

qsort()を理解するためのサンプルを提示しておきます。
以下で使っているqsort()の構文説明;
> qsort( (void *)num, 10, sizeof(int), sortfunc );
第一引数の num は、ソート対象の配列など
第二引数の 10 は、ソート対象のソートする要素数
第三引数の sizeof(int) は、第一引数の1要素の長さ
第四引数の sortfunc はソートするために比較を行う関数名
qsort()はどういうことをするものなのか、調べたほうがいいです。

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

/* プロトタイプ宣言 */
int sortfunc( const void *n1, const void *n2 );

int main( void )
{
    int i;

    /* 初期データ */
    static int num[10] = { 9, 5, 1 ,7, 2, 6, 8, 4, 0, 3 };

    /* データのソート */
    qsort( (void *)num, 10, sizeof(int), sortfunc );

    /* 結果の表示 */
    for( i = 0; i < 10; i++ )   printf( "%d ", num[i] );
    putchar('\n');

    return 0;
}

/* ソート関数(昇順ソートさせる) */
int sortfunc( const void *n1, const void *n2 )
{
    int *pn1 = (int *)n1;
    int *pn2 = (int *)n2;

    if( *pn1 < *pn2 ){
        return -1;
    }
    else if( *pn1 > *pn2 ){
        return 1;
    }
    return 0;
}



この投稿にコメントする

削除パスワード

No.19501

Re:入力した語の出現頻度を求める
投稿者---あつし(2005/01/26 13:56:53)


無事プログラムが完成しました。ありがとうございました。
qsortについては、詳しく勉強します!!
とても参考にします☆


この投稿にコメントする

削除パスワード

No.19505

Re:入力した語の出現頻度を求める
投稿者---あつし(2005/01/26 14:33:25)


何度もすみませんが、constというのは記憶クラスのものなんですか?
autoやstaticではダメなのでしょうか?


この投稿にコメントする

削除パスワード

No.19515

Re:入力した語の出現頻度を求める
投稿者---YuO(2005/01/26 16:59:16)


>何度もすみませんが、constというのは記憶クラスのものなんですか?

記憶クラスではありません。
型修飾子です。

constをつけた型のオブジェクトは,初期化後の変更が出来ません。
const void *型であれば,const void型へのポインタになります。


>autoやstaticではダメなのでしょうか?

autoやstaticとは目的が異なります。



この投稿にコメントする

削除パスワード

No.19483

Re:入力した語の出現頻度を求める
投稿者---HALLS(2005/01/25 23:17:46)


>実行しても重複した語句が直り、違う種類の語句が
>出てくるだけなのです。

おっしゃっている意味をはかりかねます。
それはさておき、ソースを子細に検討したわけではありませんが
main関数の最後のprintf()が正しくないであろう、ということはわかりました。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧