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

palindrome(回文:始めから(通常通り)読んでも、終わりから(通常と逆に)読んでも同じ読み方をする分列)を判断するプログラムを作成したいのですが
条件が...
Input : 英語のアルファベットもしくは数字から成り立っているstring
(ただし、大文字小文字の区別はしなくても良い)
必ず stackを 利用して作成。 (連結リストを使う)
abba -> palindrome
Aba -> palindrome
Abcd123 -> not palindrome

Output : 入力された stringが palindromeなのか判別してその結果を出力する。

なのですが、プログラミングが得意な方どなたかご教授お願いします><

質問者からの補足コメント

  • つらい・・・

    今は連結リストのところを学んでいるので
    それを使わないといけないみたいです(泣)

    No.1の回答に寄せられた補足コメントです。 補足日時:2016/10/04 00:00

A 回答 (4件)

以下のようにしてください。


sample1.c
-------------------------------------------
#include <stdio.h>
#include <string.h>
int main(void)
{
char buff[4096];
int i;
int len;
int hantei = 1;
printf("Input data=>");
gets(buff);
len = strlen(buff);
//先頭から順に1文字ずつ取り出し、比較する文字をおしりから1文字ずつ取り出す
for (i = 0; i < len;i++){
//文字が不一致なら回文でない(大文字小文字は無視するため大文字にして比較する)
if (toupper(buff[i]) != toupper(buff[len-i-1])){
hantei = 0;
break;
}
}
if (hantei == 1){
printf("palindrome\n");
}else{
printf("not palindrome\n");
}
return 0;
}
---------------------------------------------------------------------

sample2.c
------------------------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct data {
char item;
struct data *next;
struct data *back;
} DATA;
//開始ポインター
DATA start;

//最後のデータを取得する
DATA *get_last_data( void )
{
DATA *p = &start;
while(p->next != NULL){
p = p->next;
}
return p;
}
//リストの最後へデータを登録する
void push_data(char item)
{
DATA *last;
DATA *p = malloc(sizeof(DATA));
if (p == NULL){
printf("malloc error\n");
exit(10);
}
//最後のデータ取得
last = get_last_data();
//nextの付け替え
last->next = p;
//最後のデータ登録
p->item = item;
p->next = NULL;
p->back = last;
}
//リストの最後からデータを取り出す
char pop_data( void )
{
char item;
DATA *last;
DATA *prev;
last = get_last_data();
item = last->item;
//1つ前のデータのnextをNULLに設定
prev = last->back;
prev->next = NULL;
//最後のデータを解放
free(last);
return item;
}
int main(void)
{
char buff[4096];
int i;
int len;
char item;
int hantei = 1;
//リストの開始設定
start.next = NULL;
start.back = NULL;
start.item = 0x00;
printf("Input data=>");
gets(buff);
len = strlen(buff);
//先頭から1文字ずつスタックに登録
for (i = 0; i < len;i++){
push_data(buff[i]);
}
//先頭から順に1文字ずつ取り出し、比較する文字をスタックから1文字ずつ取り出す
for (i = 0; i < len;i++){
item = pop_data();
//文字が不一致なら回文でない(大文字小文字は無視するため大文字にして比較する)
if ( toupper(buff[i]) != toupper(item) ){
hantei = 0;
break;
}
}
if (hantei == 1){
printf("palindrome\n");
}else{
printf("not palindrome\n");
}
return 0;
}
-------------------------------------------

sample3.c
-------------------------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct data {
char item;
struct data *next;
} DATA;
//開始ポインター
DATA start;

//最後のデータを取得する
DATA *get_last_data( void )
{
DATA *p = &start;
return p->next;
}
//リストの最後へデータを登録する
void push_data(char item)
{
DATA *last;
DATA *p = malloc(sizeof(DATA));
if (p == NULL){
printf("malloc error\n");
exit(10);
}
//最後のデータ取得
last = get_last_data();
//最後のデータの付け替え
start.next = p;
//最後のデータ登録
p->item = item;
p->next = last;
}
//リストの最後からデータを取り出す
char pop_data( void )
{
char item;
DATA *last;
DATA *prev;
last = get_last_data();
item = last->item;
//最後のデータの付け替え
start.next = last->next;
//最後のデータを解放
free(last);
return item;
}
int main(void)
{
char buff[4096];
int i;
int len;
char item;
int hantei = 1;
//リストの開始設定
start.next = NULL;
start.item = 0x00;
printf("Input data=>");
gets(buff);
len = strlen(buff);
//先頭から1文字ずつスタックに登録
for (i = 0; i < len;i++){
push_data(buff[i]);
}
//先頭から順に1文字ずつ取り出し、比較する文字をスタックから1文字ずつ取り出す
for (i = 0; i < len;i++){
item = pop_data();
//文字が不一致なら回文でない(大文字小文字は無視するため大文字にして比較する)
if ( toupper(buff[i]) != toupper(item) ){
hantei = 0;
break;
}
}
if (hantei == 1){
printf("palindrome\n");
}else{
printf("not palindrome\n");
}
return 0;
}
-------------------------------------------------

sample1.cはリストを使わない方法です。
非常にすっきりしていますが、リストを使うことが今回の前提なので、参考程度にしてください。
(回文の判定でリストを使うことがいかに無意味かを知るにはよい材料になるかと)

sample2.cは双方向(next,back)のリストを使っています。双方向のリストを使うことが主な目的なら
この方法になりますが、冗長的です。

sample3.cは単方向(nextのみ)で、かつスタックとして使用することに特化しています。
単方向(nextのみ)で、かつスタックとして使うことが前提ならこの方法になります。
尚、sample2はデータ件数(=入力文字数)が非常に多くなると(約1万件以上)、劇的に遅くなります。
画面から入力する文字数は100桁程度で十分なので、その範囲で使用するには問題ありません。

3つのプログラムは、すべて同じ結果になります。
以下、実行例です。
Input data=>abBa
palindrome

Input data=>abcdegsd3457
not palindrome
    • good
    • 0

要するに、No.1の方のおっしゃる「後ろから読んだ場合」をスタックを使って表現すればいいわけですよね。


たとえば"12345"という文字列を1文字ずつスタックに入れて、
1文字ずつ順番に読み出したらどんな語順になるか。
これで答えはほとんどわかったと思います。
    • good
    • 0

あなたがなにを疑問としているのかがまったくわからない.

    • good
    • 0

単純に入力された文字列が、前から読んだ場合と後ろから読んだ場合で比較して全て一致すれば、


palindromeと判断すればよいかと思うのですが、いかがでしょうか?
「必ず stackを 利用して作成。 (連結リストを使う)」・・・このようにしないとだめですか?
この回答への補足あり
    • good
    • 0

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

このQ&Aを見た人はこんなQ&Aも見ています