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

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

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

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

Q&A

解決済

3回答

2671閲覧

文章に出現する各単語の出現回数を求める プログラムを実装したい

rft3

総合スコア7

C

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

0グッド

0クリップ

投稿2020/07/02 12:18

ヘッダーファイルを作成し、読み取ったtxtの文章に出現する各単語の出現回数を求めるプログラムを実装したいです。

方針としましては
1.Node構造体に出現頻度を表すメンバint freqを追加する
2.出現単語をinsertする際,freqをインクリメントすることで,
各単語の出現頻度を数え上げる
3.全単語をshowする際,"{id+1}¥t{str}¥t{freq}¥n"をprintfする
といった流れで作業したのですが、エラーメッセージを見ても修正すべき点が分かりません。どうかご教授お願い致します。

ヘッダーファイル↓(trie.h)

C

1#define NUM_OF_CHARS 26 2 3typedef struct node Node; 4struct node{ 5 int id; 6 int freq; 7 Node* next_char[NUM_OF_CHARS]; 8}; 9 10 11Node* create(){ 12 Node* node = (Node*) malloc(sizeof(Node)); 13 node->id = -1; 14 for(int i = 0; i < NUM_OF_CHARS; i++) node->next_char[i] = NULL; 15 return node; 16} 17 18void show(Node *curr, char *str, int pos){ 19 if(curr == NULL) return; 20 if(curr->id != -1){ 21 str[pos] = '\0'; 22 printf("%d\t%s\n", curr->id+1, str); 23 printf({id+1}\t{str}\t{freq}\n); 24 } 25 for(int i = 0; i < NUM_OF_CHARS; i++){ 26 if(curr->next_char[i] != NULL){ 27 str[pos] = i+'a'; 28 show(curr->next_char[i], str, pos+1); 29 } 30 } 31} 32 33 34void insert(Node *freq, char *str){ 35 static int WID = 0; 36 if(freq == NULL) return; 37 while(*str){ 38 char ch = *str-'a'; 39 if(freq->next_char[ch] == NULL) freq->next_char[ch] = create(); 40 freq = freq->next_char[ch]; 41 str++; 42 } 43 if(freq->id == -1) freq->id = WID++; 44} 45

ソースファイル↓(word_freq.c)

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include "trie.h" 5 6int N; 7char **words; 8 9void read_text(char *fn){ 10 FILE *fp = fopen(fn, "r"); 11 char str[32]; 12 fscanf(fp, "%d\n", &N); 13 words = (char **) malloc(N*sizeof(char *)); 14 for(int i = 0; i < N; i++){ 15 fgets(str, 32, fp); 16 char *p = strchr(str, '\n'); 17 *p = '\0'; 18 int len = strlen(str); 19 words[i] = (char *) calloc(len+1, sizeof(char)); 20 strcpy(words[i], str); 21 } 22fclose(fp); 23} 24 25int main(int argc, char *argv[]){ 26 read_text(argv[1]); 27 Node* root = create(); 28 for(int i = 0; i < N; i++) insert(root, words[i]); 29 char str[32]; 30 show(root, str, 0); 31} 32

実現したい実行結果↓
./cpgm/word_freq data/news.txt | sort -n -k 3 -r | head
13 the 12
23 to 9
11 huawei 6
6 of 4
1 google 4
22 states 3
21 united 3
9 with 2
87 is 2
77 components 2


エラーメッセージ↓
cpgm/trie.h: In function ‘create’:
cpgm/trie.h:12:24: warning: implicit declaration of function ‘malloc’ [-Wimplicit-function-declaration]
Node* node = (Node*) malloc(sizeof(Node));
^
cpgm/trie.h:12:24: warning: incompatible implicit declaration of built-in function ‘malloc’
cpgm/trie.h:12:24: note: include ‘<stdlib.h>’ or provide a declaration of ‘malloc’
cpgm/trie.h:14:62: error: ‘NULL’ undeclared (first use in this function)
UM_OF_CHARS; i++) node->next_char[i] = NULL;
^
cpgm/trie.h:14:62: note: each undeclared identifier is reported only once for each function it appears in
cpgm/trie.h: In function ‘show’:
cpgm/trie.h:19:14: error: ‘NULL’ undeclared (first use in this function)
if(curr == NULL) return;
^
cpgm/trie.h:22:5: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
printf("%d\t%s\n", curr->id+1, str);
^
cpgm/trie.h:22:5: warning: incompatible implicit declaration of built-in function ‘printf’
cpgm/trie.h:22:5: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’
cpgm/trie.h:23:12: error: expected expression before ‘{’ token
printf({id+1}\t{str}\t{freq}\n);
^
cpgm/trie.h:23:12: error: stray ‘\’ in program
cpgm/trie.h:23:12: error: stray ‘\’ in program
cpgm/trie.h:23:12: error: stray ‘\’ in program
cpgm/trie.h: In function ‘insert’:
cpgm/trie.h:36:6: error: ‘curr’ undeclared (first use in this function)
if(curr == NULL) return;
^
cpgm/trie.h:36:14: error: ‘NULL’ undeclared (first use in this function)
if(curr == NULL) return;

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

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

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

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

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

guest

回答3

0

ベストアンサー

word_freq.c の中に trie.h を直接書いて、★の修正を加えてみました。

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4//#include "trie.h" 5#define NUM_OF_CHARS 26 6 7typedef struct node Node; 8struct node{ 9 int id; 10 int freq; 11 Node* next_char[NUM_OF_CHARS]; 12}; 13 14 15Node* create(){ 16 Node* node = (Node*) malloc(sizeof(Node)); 17 node->id = -1; 18 node->freq = 0; // ★ 追加 19 for(int i = 0; i < NUM_OF_CHARS; i++) node->next_char[i] = NULL; 20 return node; 21} 22 23void show(Node *curr, char *str, int pos){ 24 if(curr == NULL) return; 25 if(curr->id != -1){ 26 str[pos] = '\0'; 27 printf("%d\t%s\t%d\n", curr->id+1, str, curr->freq); // ★ 変更 28 //printf({id+1}\t{str}\t{freq}\n); // ★ 削除 29 } 30 for(int i = 0; i < NUM_OF_CHARS; i++){ 31 if(curr->next_char[i] != NULL){ 32 str[pos] = i+'a'; 33 show(curr->next_char[i], str, pos+1); 34 } 35 } 36} 37 38 39void insert(Node *freq, char *str){ 40 static int WID = 0; 41 if(freq == NULL) return; 42 while(*str){ 43 char ch = *str-'a'; 44 if(freq->next_char[ch] == NULL) freq->next_char[ch] = create(); 45 freq = freq->next_char[ch]; 46 str++; 47 } 48 if(freq->id == -1) freq->id = WID++; 49 freq->freq++; // ★ 追加 50} 51 52int N; 53char **words; 54 55void read_text(char *fn){ 56 FILE *fp = fopen(fn, "r"); 57 if (!fp) { perror("fopen"); return; } // ★ 追加 58 char str[32]; 59 fscanf(fp, "%d\n", &N); 60 words = (char **) malloc(N*sizeof(char *)); 61 for(int i = 0; i < N; i++){ 62 fgets(str, 32, fp); 63 char *p = strchr(str, '\n'); 64 *p = '\0'; 65 int len = strlen(str); 66 words[i] = (char *) calloc(len+1, sizeof(char)); 67 strcpy(words[i], str); 68 } 69fclose(fp); 70} 71 72int main(int argc, char *argv[]){ 73 read_text(argv[1]); 74 Node* root = create(); 75 for(int i = 0; i < N; i++) insert(root, words[i]); 76 char str[32]; 77 show(root, str, 0); 78}

投稿2020/07/02 14:32

kazuma-s

総合スコア8224

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

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

rft3

2020/07/05 04:53

read_txt内を変更するという発想が出なかったです。大変参考になりました。
guest

0

  1. まずは、ヘッダーファイルのことは忘れて#include "trie.h"はコメントにし、その直後にでもtrie.hの内容をすべて貼り付けてください。
  2. ソースコードをコンパイルしてエラーをつぶしてください。ほかの方の回答にもあるように、printfにC言語にはない変数埋め込み風の構文の写し間違い(少なくとも"で囲むべきだろう)のようなものが存在しますね。
  3. エラーがなくなったらコードを実行してみてください。read_textを読む限り、何か特定の構造を持ったファイルを想定しているようですが、提示されていないので検証できません。

なお、C言語では一般にヘッダーファイルに関数は書きません(デバッグ用途など特殊な目的を除く)。

投稿2020/07/02 13:13

Daregada

総合スコア11990

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

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

0

printf({id+1}\t{str}\t{freq}\n);

C言語にはこういう構文はありません。

投稿2020/07/02 12:58

y_waiwai

総合スコア88042

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問