プロが教える店舗&オフィスのセキュリティ対策術

typedef struct{
int num;
char basic_gainen[MAX][32];
int particle[MAX];
}Gainen;
int main (void){
Gainen g1, g2;
char str1[256] = "外国_の_大型_の_船";
char str2[256] = "大型_の_船";
char buf[256];
divide(&g1, str1);//文字列の中から助詞と名詞を取得
divide(&g2,str2);//文字列の中から助詞と名詞を取得
printf("gainen:%s\n",print(&g1,buf));
printf("gainen:%s\n",print(&g2,buf));
if(hikaku(&g1,&g2)==1)
printf("一部の単語は一致する\n");
}
//二つの文字列を比較し、一部一致するかどうかの判定
int hikaku(Gainen *g1, Gainen *g2){
int n,i;
if(g1->num != g2->num){
if(g1->num >= g2->num)
n = g2->num;
else
n = g1->num;
printf("n:%d\n",n);
for(i=n;i>0;i--){
printf("inside loop i:%d\n",i);
if(g1->particle[n] != g2->particle[n])
return 0;
else if(strcmp(g1->basic_gainen[n],g2->basic_gainen[n])
!= 0 )
return 0;
}
}
return 1;
}
divide関数を省略させて頂きます。
hikaku関数のところで、二つの文字列の助詞と名詞が一致しなかったら0を返すその以外は1と返すというふうにしたいですが、実行したらhikaku関数から0の値wが返された。ループの数を表示したら、上のやり方でループがまわらないというのはわかったんです。上の条件判断はいけないですか?ご教授よろしくお願いします。

A 回答 (9件)

divide関数ですが


void divide(Gainen *gainen,char* str){
int i,k,count,particle;

k = 0;
particle = 0;
count = 1;
for(i=0;i<strlen(str);i++){
if(str[i] == '_'){
count++;
}
}
gainen->num = count;
i = 0;
while(str[i]){
i++;
if(str[i] == '_'){
--count;
strncpy(gainen->basic_gainen[count], &str[k], i-k);
gainen->basic_gainen[count][i-k]=0;
k = i + 1;
particle = get_jyoshi(gainen->basic_gainen[count]);
gainen->particle[count] = particle;
}
}
if(count == 1){
strncpy(gainen->basic_gainen[0],&str[k],i-k);
gainen->basic_gainen[0][i-k]=0;
particle = get_jyoshi(gainen->basic_gainen[0]);
gainen->particle[0] = particle;
}
}
こうすれば
g1->particleに 0,1,0,1,0
g1->basic_gainenに "船" "の" "大型" "の" "外国"
が代入されますがこういう仕様のほうがわかりやすいのでは
    • good
    • 0
この回答へのお礼

ありがとうございます。確かにこのやりかたの方が解りやすいですが。自分がやったのはbasic_gainenに助詞に当たる部分、この例では"の"、を除いて、名詞だけ格納するようにしてました。でもphp504が言ったとおり別々にすると先の初期化の問題が出てしまって、処理が難しくなりますね。
どうもありがとうございます。
参考になりますm(_ _)m

お礼日時:2009/11/20 15:55

#4 で「意味がわからん」と書いたのは, つまるところ「num が数えているものと basic_gainen に入れているものくいちがっているんだけど, どっちが正しいのかがわからん」ってことがあるわけで.


つまり, 現状だと num は「単語の数」を表すように見えるんだけど, basic_gainen に入っているのは「単語」じゃないのでおかしい. 一方, basic_gainen に入っているのは「文節」と考えられるんだけど, そうすると num には「文節」の数を入れなきゃならない. だから, 今のプログラムをそのまま使うなら num の値を修正しないとダメ. あるいは, #8 のように単語ごとに入れるという手もある. どっちにするかは「このあとどのような処理を想定しているか」によります.
もちろん「なぜ basic_gainen に逆順に入っているのか」という疑問は残る. 逆順にする理由は全くわかりません.
    • good
    • 0

char str1[256] = "外国_の_大型_の_船";


char str2[256] = "大型_の_船";
divide(&g1, str1); //文字列の中から助詞と名詞を取得
divide(&g2, str2); //文字列の中から助詞と名詞を取得

ということは、devide()によってstr1, str2が処理され、その結果がg1, g2にセットされたのでしょう。どのような値がg1, g2にセットされたのか、わかっていますか。

"外国…"と"大型…"という、異なるデータを処理したなら、g1とg2に異なる結果が格納されたであろう、と推測できますから、むしろhikaku()が「一致しない」という意味の0を返すほうが自然に思えますけど。

結局、devide()が処理した結果(途中経過)が分からないことには、hikaku()の処理が適切かどうかということも判断のしようがありません。
まずは、devide()の仕様を確認するとか、g1, g2 にどんな内容がセットされたのか表示してみる、といったことが先決ではないでしょうか。
    • good
    • 0

>これでも、まだ返す値が0です。

1が帰ってほしかったのに。=_="
とにかく、printfで動作中の各値を確認しましょう。デバッグの基本です。

この回答への補足

そうでしたね。m(_ _)m
printfで動作確認したら、以下のようになります。
これならやっぱり値が0になってますね。^_^;;
gainen:外国_の_大型_の_船
gainen:大型_の_船
n:2
ループ内 i:2
比較するもの :
gainen1[2]:外国,jyoshi1[2]:1 gainen2[2]:55.0.2.ELsmp,jyoshi2[2]:2727536
助詞一致しない

補足日時:2009/11/20 15:17
    • good
    • 0

g1->num や g2->numポインタです。

g1 や g2 が持つnumというメンバーを指します。
そういうのはここの回答者であれば見ればわかります(g1は構造体のポインタですがnumは整数なのもわかります))
そういうことを聞いているのではなく
g1->numは"外国_の_大型_の_船"の文節の数('_'の数+1)を現します
とか言うことが知りたいのですよ
"外国_の_大型_の_船"の例だと
g1->particle[ ]は0-1しか値が代入されてないし
g1->basic_gainen[ ]は0-2しか値が入らないと思いますよ
残りは初期化してないので不定な値が入っています
g1->numは5なのでg1->particle[4]とかを見ても意味がないです

この回答への補足

そうでしたか?質問の意味伝わらなくてすみませんでした。m(_ _)m
どうやって初期化するんですか?

補足日時:2009/11/20 14:49
    • good
    • 0

気になるところ:


・g1, g2 が初期化されていない.
・g1->num や g2->num の意味が分からん.
・(それと関連するけど) divide の仕様が理解不能.

この回答への補足

一応構造体やってますのでg1,g2はインスタンス化してますので、初期化は関係ないと思います。
ご意見ありあがとうございます。

補足日時:2009/11/20 13:53
    • good
    • 0
この回答へのお礼

後、追加ですが、g1->num や g2->numポインタです。g1 や g2 が持つnumというメンバーを指します。
ポインタと構造体わかる方お願いします。

お礼日時:2009/11/20 14:02

>if(g1->particle[i] != g2->particle[i])


この場合のiはnから始まりますよね。
nの値は、
> n = g2->num;
もしくは
> n = g1->num;
ですから、範囲外ではないでしょうか?
ついでに
> for(i=n;i>0;i--){
ですから、添え字が0のの要素も比較されませんね。
for(i=n-1;i>=0;i--){
だと、どうでしょう。

この回答への補足

なんてごちゃごちゃなコード載せてしまった。ー。ー;;すみませんでした。
訂正すると
int hikaku(Gainen *g1, Gainen *g2){
int n,i,count;
count = 0;
if(g1->num != g2->num){
if(g1->num >= g2->num)
n = g2->num;
else
n = g1->num;
for(i=0;i<n;i++){
if(g1->particle[i] != g2->particle[i]){
return 0;
}
else if(strcmp(g1->basic_gainen[i],g2->basic_gainen[i])
!= 0 )
return 0;
}
}
return 1;
}
これでも、まだ返す値が0です。1が帰ってほしかったのに。=_="

補足日時:2009/11/20 13:29
    • good
    • 0

 forループそのものは問題ないように見えます。


 普通は先頭から比較するものですが、趣味の問題ですから。
 プログラマが何をしたいかよく分からんですが以下の行の
[n]は[i]ではないのかな。?

if(g1->particle[n] != g2->particle[n])

この回答への補足

すみません、そうでしたね。
if(g1->particle[i] != g2->particle[i])
ありがとうござあいます。
でもまだうまく実行できないです。
何をやりたいか。。伝わってないか~~ 説明が下手ですみません-.-;;

補足日時:2009/11/20 12:54
    • good
    • 0

省略したdivide関数が肝心だと思います。


構造体の各メンバーにどういう風にどんな値をセットしているか、
提示のコードではわかりません。

この回答への補足

すみません。divideは以下のようになります。よろしくお願いします
char* divide(Gainen *gainen,char* str){
int i,j,k,pnum,gnum;
int count,particle;
char buf[256],buf2[256];
k = pnum = gnum = 0;
count = 1;
particle = 0;
for(i=0;i<strlen(str);i++){
if(str[i] == '_'){
count++;
}
}
gainen->num = count;
gnum = count/2;
pnum = count/2 - 1;
i = 0;
while(str[i]){
i++;
if(str[i] == '_'){
--count;
strncpy(buf,&str[k],i-k);
buf[i-k] = 0;
particle = get_jyoshi(buf);
if(particle){
gainen->particle[pnum] = particle;
pnum--;
k = i + 1;
}
else{
strncpy(&gainen->basic_gainen[gnum],&str[k],i-k);
gainen->basic_gainen[gnum][i-k]=0;
k = i + 1;
gnum--;
}
}
}
if(count == 1){
while(str[i])
i++;
strncpy(&gainen->basic_gainen[gnum],&str[k],i-k);
gainen->basic_gainen[gnum][i-k]=0;
}
return 1;
}
int get_jyoshi(char* name){
if(strcmp(name,"の")==0) {
return 1;
}
else{
return 0;
}
}

補足日時:2009/11/20 12:45
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!