初投稿で不慣れな点も多いと思います。また、プログラミングの超初心者なので優しく答えていただけるととてもありがたいです。
今回やろうとしたのは文章をn-gramで解析してまとめあげて生成したものをテキストファイルに保存してマルコフ連鎖の仕組みによって新たな文章生成をしようというプログラムです。実は、以下①のプログラムで②のような内容のテキストファイルを読み取って文章を作ろうとしているのですが、何度やっても表示されるのは『?????????』で、うまくいきません。
試したことは
⑴様々な文字コードに変更して実行。(EUC,JIS,Unicode UTF-8など)
⑵プログラム言語のミスがないかの確認。
です。(使用機器:mac,ターミナルで実行)
①
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXNO 100000
#define MAXLINE 256
#define FILENAME "3gram.txt"
int read2gram(char db2gram[MAXNO][6])
{
FILE *fp;
char line[MAXLINE];
int i=0;
if((fp=fopen(FILENAME,"r"))==NULL){
fprintf(stderr, "エラー ファイル3gram.txtがありません。\n");
exit(1);
}
while (fgets(line, MAXLINE, fp)!=NULL) {
strncpy(db2gram, line,4);
db2gram[5]='\0';
++i;
}
return i;
}
int findch(char *startch,char db2gram[MAXNO][6],int n)
{
int i;
int no=0;
for (i=0; i<n; ++i) {
if (strncmp(startch, db2gram, 2)==0) ++ no;
}
return no;
}
int setrnd(int num)
{
int rndno;
while ((rndno=(double)rand()/RAND_MAX*num)==num);
return rndno;
}
void setrndstr(char *startch,char db2gram[MAXNO][6],int n)
{
int i;
int point;
point=setrnd(n);
for (i=0; i<n; ++i) {
if (i==point) {
startch[0]=db2gram[2];
startch[1]=db2gram[3];
startch[2]='\0';
break;
}
}
}
void setnext(char *startch,char db2gram[MAXNO][6],int n,int num)
{
int i;
int no=0;
int point;
point=setrnd(num);
for (i=0; i<n; ++i) {
if (strncmp(startch, db2gram, 2)==0)++ no ;
if (no==point) {
startch[0]=db2gram[2];
startch[1]=db2gram[3];
startch[2]='\0';
break;
}
}
}
void generates(char *startch,char db2gram[MAXNO][6],int n)
{
int num;
putchar(startch[0]);putchar(startch[1]);
do{
num=findch(startch, db2gram, n);
if (num!=0)
setnext(startch, db2gram, n, num);
else
setrndstr(startch, db2gram, n);
putchar(startch[0]);putchar(startch[1]);
}while ((strncmp(startch, "。", 2)!=0)&&
(strncmp(startch, "、", 2)!=0)) ;
printf("\n");
}
int main()
{
char line[MAXLINE];
char db2gram[MAXNO][6];
int n;
char startch[MAXLINE];
srand(65535);
n=read2gram(db2gram);
printf("さくら:メッセージをどうぞ。\n");
printf("あなた:");
while (fgets(line, MAXLINE, stdin)!=NULL) {
printf("さくら:");
strncpy(startch, &(line[setrnd((strlen(line)-1)/2)*2]),2);
generates(startch, db2gram, n);
printf("あなた:");
}
printf("さくら:バイバーイ。\n");
return 0;
}
②ファイル名:3gram.txt
134 ネッド
127 した。
122 た。そ
118 ように
117 かった
111 ていた
111 あった
103 って、
95 だった
94 してい
92 自動車
92 いた。
90 火星人
88 のよう
88 だろう
87 んだ。
84 。それ
84 であっ
n-gram処理データを基にしたマルコフ連鎖による文生成の質問
Re: n-gram処理データを基にしたマルコフ連鎖による文生成の質問
文字コードの変更というのはターミナルの設定ですか、それともテキストファイルの文字コードですか?
とりあえず、1文字が2byteという前提で計算しているようなのでUTF-8ではまず動かないと思いますが。
とりあえず、1文字が2byteという前提で計算しているようなのでUTF-8ではまず動かないと思いますが。
Re: n-gram処理データを基にしたマルコフ連鎖による文生成の質問
h2so5さんの補足になりますが・・・
以下のページでもみて、各文字コードのバイト数の違いを確認してください。
文字数カウント・チェック
http://www.word-tool.net/app/counter.php
追記:たとえば「自動車」で確認すると、UTF-8は9バイトになりますね。
これだけでも2バイト固定でやるのは間違ってるとわかるよね?
以下のページでもみて、各文字コードのバイト数の違いを確認してください。
文字数カウント・チェック
http://www.word-tool.net/app/counter.php
追記:たとえば「自動車」で確認すると、UTF-8は9バイトになりますね。
これだけでも2バイト固定でやるのは間違ってるとわかるよね?
- 添付ファイル
-
- すべて3文字だが、6バイトなのはEUC-JPとshift-jis。
- dixq_net_forum_3_t_15910_image_1.png (27.88 KiB) 閲覧数: 2443 回
written by へにっくす