引子
看到不少C语言的基础题目里有一道题目是,如何判断一个英文单词是回文的,
即:asdsa | asddsa之类,其特点是从前往后等价于从后往前的,在这个特定的场景下,
大多数人第一反应就是将前后对应位置的字符进行比较,根据相等性比较结果来判断
该单词是否为回文单词,直至判断最中间的两个字符(奇数个字符时,两个字符是指向同一个)。
例如:
int palindrome(char *str) {
int n=strlen(str);
char *p=str,*q=str+n-1;
while(p < q){
if((*p != *q) && (*p != (char)*(q+32)) && (*p != (char)*(q-32))) return 0;
p++;
q--;
}
return 1;
}
void main(){
char str[100];
printf("Enter a message:");
gets(str); // use scanf for better
if(palindrome(str)) printf("Palindrome\n");
else printf("Not a palindrome\n");
}
扩展
以上是针对一个单词的情况,如果将之推广,判断一个语句是回文的如何实现呢?
例如:asd qqd sa | asdf dsa 或 I am a madam , a ma i ?
如果还依照之前的做法会存在一个问题,因为对称位置的字符不一定对等,因为有标点符号存在
所以在解决这类问题时不能简单的一句比较对应位置的字符就可以多的。
其实只要稍微改动一下就可以了,只要遇到非字母的字符直接忽略,
并沿着当前移动方向继续推进一个字符的位置,重复此类操作直至遇到字母类型的字符才进行比较。
例如:
#include <stdio.h>
#include<string.h>
int palindrome_2(char *str) {
int n=strlen(str);
char *p=str,*q=str+n-1;
while(p < q){
if((*p >= 'a' && *p <='z') || (*p >= 'A' && *p <='Z')){
if((*q >= 'a' && *q <= 'z') || (*q >= 'A' && *q <='Z')){
if((*p != *q) && (*p != (char)*(q+32)) && (*p != (char)*(q-32))) return 0;
else {
p++;
q--;
}
} else q--;
} else p++;
}
return 1;
}
void main(){
char str[100];
printf("Enter a message:");
gets(str); // only use gets, because scanf wil be cuted for blank|tab
if(palindrome_2(str)) printf("Palindrome\n");
else printf("Not a palindrome\n");
}
小结
一个简单的变化,就为解决办法增加了一层判断,看似很少的变化,实则对思考问题的全面性有了提升,
借此给自己一个留个“烂笔头”吧。小玩意,期各位看官指教!
题外篇:由回文的判断引出一个问题,如何将一篇文章倒序呢?
例如:I am a student => student a am I
期待回复中。。。