ページ 1 / 1
回文判定
Posted: 2011年12月24日(土) 14:57
by keiji
質問失礼します。
今、文字列が回文になっているかどうか
判定するプログラムを作っています。
(回文なら1、違うなら0を返す。)
コード:
int kaibun(char *l, char *r){ //文字列中へのポインタlとrを与える//
if(l == r || r < l) return 1;
if(l[0] == r[0]){
l++; r--;
return sym(l, r);
}
else return 0;
}
こんな感じにしてみたのですが、
これをまた使って、
文字列strの中からn(整数)文字の回文が存在するか調べ、
存在すればその先頭位置へのポインタを返し、無ければNULL
を返す関数をつくっています。
コード:
char nkaibun(char *str, int n){
以降が、なかなか分かりません。
str[0],str[1],...,str[n],....を再帰で順に調べて行こうと思っているのですが、
関数kaibunの使い方が分からず困っております。
ご教授、よろしくお願いします。
Re: 回文判定
Posted: 2011年12月24日(土) 15:03
by beatle
関数symの動作が分からないと関数kaibunの動作が分かりません。
それから、kaibunの引数lとrには具体的に何を渡すのですか?
nkaibun、kaibunの使用例を示していただければ、答えやすくなると思います。
Re: 回文判定
Posted: 2011年12月24日(土) 15:11
by keiji
すみません。
symはkaibun のことです。 書き間違えです。
lとrは任意で、ある文字列の中で
*lと*rを両端とした文字列で判定するプログラムです。
よろしくお願いします。
Re: 回文判定
Posted: 2011年12月24日(土) 15:17
by keiji
例ですが、
(kaibun)
level -> return 1;
(nkaibun)
aiuleveldv ->(n(5とする)文字の文字列の中に回文level(5文字))
が存在 ->その先頭位置へのポインタを返す。
といったかんじです。
分かりにくくてすみません。
Re: 回文判定
Posted: 2011年12月24日(土) 15:17
by keiji
例ですが、
(kaibun)
level -> return 1;
(nkaibun)
aiuleveldv ->(n(5とする)文字の文字列の中に回文level(5文字))
が存在 ->その先頭位置へのポインタを返す。
といったかんじです。
分かりにくくてすみません。
Re: 回文判定
Posted: 2011年12月24日(土) 15:30
by beatle
symはkaibunのことなのですね。ということは関数kaibunは以下の定義となりますね。
コード:
int kaibun(char *l, char *r) //文字列中へのポインタlとrを与える
{
if(l == r || r < l) return 1;
if(*l == *r)
{
l++;
r--;
return kaibun(l, r);
}
else
{
return 0;
}
}
keiji さんが書きました:関数kaibunの使い方が分からず困っております。
というのは、
- kaibunに具体的にどんな引数を渡せばいいのか、戻り値をどうやって使えばいいのかが分からない
(lavelが回文かどうか調べるには、kaibunにはどんな引数を渡せばいいか分かりますか?)
- kaibunに渡す引数や戻り値の使い方は分かるが、kaibunの使い所が分からない
のどちらでしょうか。
Re: 回文判定
Posted: 2011年12月24日(土) 15:34
by keiji
すみません。
関数自体は作ってみましたが、
どちらの方も、あいまいで理解していませんでした。
渡す引数、使いどころ、ifによる条件がよくわからない状態です。
よろしくお願いします。
Re: 回文判定
Posted: 2011年12月24日(土) 15:43
by beatle
渡す引数も分からないのによくあんな再帰関数が書けましたね。脱帽です。
関数を作った人じゃない人が関数の使い方を説明するというよく分からない状況ですが、僕が読み取ったkaibun関数の使い方を書きます。
kaibun関数
- 引数 l 回文かどうかを判定したい文字列の左端文字へのポインタを渡す
- 引数 r 回文かどうかを判定したい文字列の右端文字へのポインタを渡す
- 戻り値 渡されたポインタl, rで表される範囲の文字列が回文ならば真、そうでなければ偽を返す
使用例
コード:
char *str; /* 回文判定したい文字列への先頭ポインタ */
size_t len; /* 回文判定したい文字列の長さ */
/* str, lenに適切な値を設定 */
if (kaibun(str, str + len))
{
/* str, str + lenの範囲にある文字列は回文 */
}
これでkaibun関数の動作と使い方は分かったと思いますので、nkaibunの作り方をもう一度ご自分で考えてみてください。
Re: 回文判定
Posted: 2011年12月24日(土) 15:57
by keiji
すみません。
説明をよく理解してませんでした。
l,rが文字列の両端を指していることは大丈夫です。
それを実際にどう文字列strで使うのかを理解していませんでした。
beatleさんの解説を参考にもう一度考えてみたいと思います。
丁寧な対応ありがとうございます。
Re: 回文判定
Posted: 2011年12月24日(土) 16:08
by beatle
一つ訂正します。
strに判定したい文字列の先頭へのポインタ、lenに判定したい文字数が入っている場合、
コード:
kaibun(str, str + len - 1)
としてください。kaibunの第二引数には、右端文字へのポインタを渡さなければならないので、str + lenから1を引きます。
str + lenだと、右端文字を1文字超えた場所へのポインタになってしまいます。
Re: 回文判定
Posted: 2011年12月27日(火) 23:35
by keiji
コード:
int kaibun(char *l, char *r){
if(l ==r || r<l) return 1;
if(*l == *r) return kaibun(l+1, r+1);
else return 0;
}
dhar *nkaibun(char *str, int n){
if(kaibun(str, str+n-1) == 0){
str++;
return nkaibun(str+1, n);
}
else if(kaibun(str, str+n-1) == 1){
return str;
}
else return NULL;
}
まで自分で書いてみました。
これを更に使って、
与えられた文字列strから最長の回文を探して、文字列として切りだして返す関数を考えています。
コード:
char *mkaibun(char *str) {
int m = strlen(str);
int i;
for(i=m;i>0,i--){
nkaibun(str,i);
if(nkaibun(str,i) != NULL){
int k = i;
break;
}
}
char *c = (char *)malloc(k+1);
c = nkaibun(str,k);
printf("%s", c);
}
とういう感じで考えてみたのですが、
根本的に上手くいかない気がします。
間違っている部分や考え方を指摘していただけないでしょうか?
よろしくお願いします。
Re: 回文判定
Posted: 2011年12月28日(水) 01:42
by keiji
すみません。
自分で考えてみます。
Re: 回文判定
Posted: 2011年12月28日(水) 08:50
by non
keiji さんが書きました:コード:
int kaibun(char *l, char *r){
if(l ==r || r<l) return 1;
if(*l == *r) return kaibun(l+1, r+1);
else return 0;
}
dhar *nkaibun(char *str, int n){
if(kaibun(str, str+n-1) == 0){
str++;
return nkaibun(str+1, n);
}
else if(kaibun(str, str+n-1) == 1){
return str;
}
else return NULL;
}
まで自分で書いてみました。
自分で作りたいというのですから、口出し無用なのでしょうけど・・・・
このプログラムさっぱりわかりません。
Re: 回文判定
Posted: 2011年12月30日(金) 02:07
by かずま
さっぱり分からないまま解決済みになってしまったので、もやもや感が取れません。
そこで、こういうものを作りたかったんだろうと予想して書いてみました。
kaibun() も nkaibun() も末尾再帰なので、簡単にループに変換できます。
なぜ、再帰呼び出しを使ったのか、最初の質問者に聞いてみたいですね。
コード:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int kaibun(char *l, char *r)
{
if (l >= r ) return 1;
if (*l != *r) return 0;
return kaibun(l + 1, r - 1);
}
char *nkaibun(char *str, int n)
{
if (strlen(str) < n) return NULL;
if (kaibun(str, str + n - 1)) return str;
return nkaibun(str + 1, n);
}
char *mkaibun(char *str)
{
int n;
for (n = strlen(str); n > 0; n--) {
char *p = nkaibun(str, n);
if (p) {
char *q = malloc(n + 1);
if (!q) return NULL;
memcpy(q, p, n);
q[n] = '\0';
return q;
}
}
return NULL;
}
int main(void)
{
char *s = "aiuleveldv";
char *t = mkaibun(s);
puts(s);
if (t) {
puts(t);
free(t);
}
return 0;
}