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

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

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

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

Q&A

0回答

1338閲覧

音声処理のユニグラムバイグラムトライグラムについて

naoki9

総合スコア0

C++

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

0グッド

0クリップ

投稿2020/07/24 16:32

編集2020/07/27 23:32

全くの初心者です。
大学の課題ですごく難しい問題が出されました。
まだ今年始めたばかりなので出来ればソースを見ながら理解したいです。
先生にも質問しましたがまだ返信が来ず提出期限も迫っているため質問させて頂きました。
問題
Example2.txtは英語の文章が入っていました。
下記のexample2.txtのユニグラム・バイグラム・トライグラム値を、それぞれアルファベット順に出力したファイルを提出しなさい。また、その際に作成したプログラムも提出しなさい。
ユニグラムの例は以下のとおりである。(1単語目はアルファベット順になる)
(前略)
a 2.021773e-02
above 5.184033e-04
absolute 1.036807e-03
(後略)
バイグラムの例は以下のとおりである。(1単語目も2単語目もアルファベット順になる)
(前略)
a boat 2.021773e-02
a cup 5.184033e-04
boat is 1.036807e-03
(後略)
トライグラムの例は以下のとおりである。(1単語目も2単語目も3単語目もアルファベット順になる)
(前略)
a boat is 2.021773e-02
a boat was 5.184033e-04
a cup is 1.036807e-03
(後略)
なお以下の点について注意すること。
1)文頭記号を<s>、文末記号を</s>とする。
2)バックオフについては考慮しなくてよい。
3)example2.txtの単語の定義は、空白で挟まれた数字・文字列とする。
4)単語内のアルファベットは、すべて小文字に表記変換すること
5)ピリオドとカンマは削除すること。
6)トライグラムの計算は難しいが、ユニグラムの計算は易しいので、できたところまで提出すること。但し、未完成のものの提出は不要。
7)配列で大きなメモリをとるためには、スタックサイズをunlimitedにしないと、segmentation faultで落ちる。動的にとれる人は動的にとるかvectorを使用したほうがよい。スタックで行う場合にメモリを拡張する方法は、各自のプログラミング環境により異なるので、自分でインターネットで調査すること。
8)出力ファイルの単語と確率値の間はタブとする。
9)確率値は、指数表示・小数点以下6桁で表すものとする。上記の例を参照。
10)単数と複数は別の単語として扱うものとする。
11)ユニグラム値はunigram.txt、バイグラム値はbigram.txt、トライグラム値はtrigram.txtに保存すること。
以下ユニグラムのコードです
あってますでしょうか
#include<iostream>
#include<fstream>
#include<string>
#include<iomanip>
using namespace std;
int mkdict(string dict[],int num[]){
int count=0;
string x;
ifstream fin("example2.txt");
if(!fin){
cerr<<"error"<<endl;
return 1;
}
while(fin>>x){
int i;
for(int s=0;s<x.size();s++){
if(x[s]==','||x[s]=='.')
x[s]=' ';
if(x[s]>='A'&&x[s]<'Z')
x[s]=x[s]-'A'+'a';
}
for( i=0;i<count;i++){
if(x==dict[i]){
num[i]++;
break;
}
}
if(i==count){
dict[count]=x;
count++;
}
}
return count;
}
int main(){
const int DICSZ=100000;
string dict[DICSZ];
int num[DICSZ];
for(int i=0;i<DICSZ;i++)
num[i]=1;
int nwords=mkdict(dict,num);
int nnum=0;
for(int i=0;i<nwords;i++){
for(int j=0;j<nwords;j++){
if(dict[i]<dict[j]){
string keep=dict[i];
dict[i]=dict[j];
dict[j]=keep;
int keep1=num[i];
num[i]=num[j];
num[j]=keep1;
}
}
}
for(int i=0;i<nwords;i++)
nnum+=num[i];
for(int i=0;i<nwords;i++){
cout<<dict[i]<<" "<<scientific<<setprecision(6)<<((double)(num[i])/nnum)<<endl;;
}
cout<<endl;
cout<<nnum;
return 0;
以上です、
簡単なことでも全部でもヒントでも構いません。
よろしくお願いします。

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

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

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

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

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

e-watt

2020/07/25 06:12

この質問の内容ですと、 ・「あなたが(課題の題材 and/or C++について)どこまでわかっている(べきなの)か」が不明で回答のポイントが不明確ですし、 ・そこそこ規模の大きいプログラムになる(のでteratailのQAではやってらんない)でしょうし、 ・現状では「丸投げ」 なので回答がつく可能性は低いでしょう。 そこそこ動くくらいのコードをなんとか書いてから、解決できない部分を質問しましょう。 とりあえず、題材については以下のページの内容で近いんでしょうかね? 近ければ読んで参考にすればいいし、遠いのならば上記のごとく「何の話か回答者にわかりそうな」ところまで絞るのが良いでしょう。 https://mieruca-ai.com/ai/bi-gram_markov_model/ 【技術解説】bi-gramマルコフモデル
naoki9

2020/07/25 16:32

返信ありがとうございます。 確かにこのままでは丸投げにしていました。 現状のユニグラムのコードです。 まだ簡単な関数しか学習しておらずおそらく大変醜いコードではありますがよろしくお願いします。
Penpen7

2020/07/25 20:37 編集

ユニグラムであれば単に単語の出現頻度を見るだけなので、適切に前処理を行って、std::map<std::string,int>で集計しますかね。 ところで、大学の教員は忙しいのでメールは気づかないことも多いです。もし返信が来なければ、直接研究室に行ったほうがいいですよ。
naoki9

2020/07/25 21:29

コメントありがとうございます。 今の大学の方針ではライブラリ関数などを使う前にどのようなことをしているのか自分でコードを作ったりして内面の理解を深めようとしています。 なので簡単な関数、再帰関数、までしか分かりません。 またコロナウイルスで大学も封鎖されてしまっていてお手上げ状態です。
Penpen7

2020/07/26 04:12

意図的に質問の内容を消去されますと、低評価が付きますのでご注意ください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問