n-gram処理データを基にしたマルコフ連鎖による文生成の質問

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
リクヤ⭐️

n-gram処理データを基にしたマルコフ連鎖による文生成の質問

#1

投稿記事 by リクヤ⭐️ » 5年前

初投稿で不慣れな点も多いと思います。また、プログラミングの超初心者なので優しく答えていただけるととてもありがたいです。
今回やろうとしたのは文章を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 であっ

アバター
h2so5
副管理人
記事: 2212
登録日時: 9年前
住所: 東京
連絡を取る:

Re: n-gram処理データを基にしたマルコフ連鎖による文生成の質問

#2

投稿記事 by h2so5 » 5年前

文字コードの変更というのはターミナルの設定ですか、それともテキストファイルの文字コードですか?
とりあえず、1文字が2byteという前提で計算しているようなのでUTF-8ではまず動かないと思いますが。

アバター
へにっくす
記事: 630
登録日時: 8年前
住所: 東京都

Re: n-gram処理データを基にしたマルコフ連鎖による文生成の質問

#3

投稿記事 by へにっくす » 5年前

h2so5さんの補足になりますが・・・
以下のページでもみて、各文字コードのバイト数の違いを確認してください。

文字数カウント・チェック
http://www.word-tool.net/app/counter.php

追記:たとえば「自動車」で確認すると、UTF-8は9バイトになりますね。
これだけでも2バイト固定でやるのは間違ってるとわかるよね?
添付ファイル
dixq_net_forum_3_t_15910_image_1.png
すべて3文字だが、6バイトなのはEUC-JPとshift-jis。
dixq_net_forum_3_t_15910_image_1.png (27.88 KiB) 閲覧数: 1163 回
written by へにっくす

閉鎖

“C言語何でも質問掲示板” へ戻る