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

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

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

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

0回答

2284閲覧

c++ 類似度計算とリスト構造を理解できていないため、結果が出力されません。

asdfgpo

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2020/07/17 02:48

編集2020/07/17 15:36

main文内の類似度計算結果が上手くできません。恐らくリストの先頭に戻す方法が間違っていると思うのですが、いまいちリスト構造を理解できておらず苦戦しています。よろしければ、ご教授お願いします。
<内容>
mk_tfidf_list関数は、引数として指定した記事IDに含まれる名詞のTF・IDF値をリストにして返す関数です。最終的に類似度計算結果を出力します。

c++

1以下コード 2#include <iostream> 3#include <fstream> 4#include <cstdlib> 5#include <cstring> 6#include <cmath> 7 8#define N 227 9 10using namespace std; 11 12struct cell 13{ 14 string key; 15 int value; 16 double tfidf; 17 18 struct cell *next; 19}; 20 21struct cell* make_cell(int value, string key) { 22 struct cell* mk_cell; 23 mk_cell = new struct cell; 24 mk_cell->key = key; 25 mk_cell->value = value; 26 mk_cell->next = NULL; 27 return mk_cell; 28} 29 30struct cell* search_cell(string key, cell* head) { 31 struct cell* buf; 32 buf = head; 33 while (buf != NULL) { 34 if (buf->key == key) { 35 return buf; 36 } 37 buf = buf->next; 38 } 39 return NULL; 40} 41 42using namespace std; 43 44// 機能:引数として指定した記事IDに含まれる名詞のTF・IDF値をリストにして返す 45// 備考:TF・IDF計算プログラムを関数にしたもの 46struct cell *mk_tfidf_list(string input_id) 47{ 48 int size = 0; 49 ifstream f_data("posdata.txt"); // posdata.txt ファイルオープン 50 string line; 51 struct cell* head; 52 head = NULL; 53 // postdata.txtから1行ずつ読み込み 54 while (f_data >> line) { 55 // 記事IDと名詞例(noun1, noun2,...)のデータに分割 56 int index = line.find(","); 57 string f_id = line.substr(0, index); 58 string w_str = line.substr(index + 1); 59 if (f_id == input_id) { 60 // split 名詞列のデータから名詞を1つずつ取り出し 61 int n; 62 for (int i = 0; i <= w_str.length(); i = n + 1) { 63 n = w_str.find_first_of(",", i); 64 if (n == string::npos) { 65 n = w_str.length(); 66 } 67 string word = w_str.substr(i, n - i); //単語 68 if (search_cell(word, head) == NULL) { //単語がなかった場合 69 struct cell* tmp; 70 tmp = make_cell(1, word); 71 tmp->next = head; 72 head = tmp; 73 size++; 74 } 75 else if (search_cell(word, head) != NULL) { 76 cell* tmp2; 77 tmp2 = search_cell(word, head); 78 tmp2->value++; 79 } 80 } 81 } 82 } 83 ifstream fin("df.txt"); 84 string line2; 85 cell* head2; 86 head2 = NULL; 87 while (fin >> line2) { 88 int index = line2.find(","); 89 string f_id2 = line2.substr(0, index); 90 string w_str2 = line2.substr(index + 1); 91 int num2 = atoi(w_str2.data()); 92 cell* tmp2 = make_cell(num2, f_id2); 93 tmp2->next = head2; 94 head2 = tmp2; 95 } 96 cell* buf = head; 97 98 while (buf != NULL) { 99 cell *tmp = search_cell(buf->key, head2); 100 if (tmp != NULL) { 101 buf->tfidf = buf->value * log2(N * 1.0 / tmp->value); 102 } 103 buf = buf->next; 104 } 105 f_data.close(); 106 buf = head; 107 return buf; 108} 109 110int main(int argc, char *argv[]) 111{ 112 string id1 = argv[1]; 113 string id2 = argv[2]; 114 115 // 指定した記事ID1のTF・IDFリスト 116 struct cell *tf_idf1; 117 tf_idf1 = mk_tfidf_list(id1); 118 119 // 指定した記事ID2のTF・IDFリスト 120 struct cell *tf_idf2; 121 tf_idf2 = mk_tfidf_list(id2); 122 123 double sim = 0; 124 double naiseki = 0; 125 double size1 = 0; 126 double size2 = 0; 127 int cnt = 0; 128 129 ```以下の部分で間違いがあると思われます。 130コード 131while (tf_idf1 != NULL) { 132 if (cnt != 0) { 133 tf_idf2 = tf_idf2->next; 134 } 135 cnt++; 136 if (tf_idf1->key == tf_idf2->key) { 137 naiseki += tf_idf1->tfidf * tf_idf2->tfidf; 138 tf_idf1 = tf_idf1->next; 139 cell *head = mk_tfidf_list(id2); 140 tf_idf2 = head; 141 cnt = 0; 142 } 143 if (tf_idf2 == NULL) { 144 cell *head = mk_tfidf_list(id2); 145 tf_idf2 = head; 146 tf_idf1 = tf_idf1->next; 147 cnt = 0; 148 } 149 } 150 151 cell *head = mk_tfidf_list(id1); 152 tf_idf1 = head; 153 cell *head2 = mk_tfidf_list(id2); 154 tf_idf2 = head2; 155 156 157 while(tf_idf1 != NULL){ 158 size1 += tf_idf1->tfidf * tf_idf1->tfidf; 159 tf_idf1 = tf_idf1->next; 160 } 161 162 while(tf_idf2 != NULL){ 163 size2 += tf_idf2->tfidf * tf_idf2->tfidf; 164 tf_idf2 = tf_idf2->next; 165 } 166 167 168 sim = naiseki / (sqrt(size2) * sqrt(size1)); 169 cout << id1 << " - " << id2 << " : " << sim << endl; 170 return 0; 171 }

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

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

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

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

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

cateye

2020/07/17 03:14 編集

見にくいので、ソースは<code>で出てくる```と```の中に貼り付けて下さい。 また、Cのヘッダファイル(stdlib.hなど)は、頭にcを付けて.hを外すとc++のヘッダにできます↓ e.g. string.h→cstring
asdfgpo

2020/07/17 15:38

失礼しました。コードの貼り付けと、頭にcを付けなおしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問