一道特殊的回文字符串处理问题

来源:互联网 发布:淘宝店铺装修方案ppt 编辑:程序博客网 时间:2024/05/17 06:10

.特殊之处在于:

1.仅考虑字母的回文,而输出保留字符串中的非字母字符

2.大小写均视为相等。

举例说明:He says: Madam! I'm Adam!

输出将为——Madam! I'm Adam


这道题一开始给我带来了很大的困扰,本来考虑的是在判断回文的过程中,过滤掉非字母的角标。但是这个思路的程序边界条件太过复杂,最终我还是放弃了。(参见第二段程序,失败的部分我也贴上来已做记录)


后来受到启发,首先对字符串做一个预处理,建立一个char * pre[],来存放s[]中判断为字母的部分的地址。然后通过对pre[]中回文的判断,来确定回文的左右角标。

具体程序如下,其中的注释记录了在寻找Bug过程中的种种问题。这对于以后的学习有很大帮助!

#include<iostream>#include<string.h>using namespace std;const int N=500;char s[N];void tst(char a){cout<<a<<';';}void printpalin(){//预处理,过滤掉非字符。char* pre[N];int pre_i=0;for(int j=0;j<sizeof(s)-1;j++){if(isalpha(s[j])){pre[pre_i++]=&s[j];//存放原来的地址}}//预处理完毕。通过指针操作s中数字。int left,right,i=1;//边界溢出了!!经过无数次的条数:原因竟然是sizeof(pre)=2000,这是我没有想到的。因为这个错误,耽误了好长好长时间!while(i<pre_i){int move=0;left=i-1;right=i+1;while(left>=0&&right<pre_i&&(*pre[left]==*pre[right]||(*pre[left]==*pre[right]+'a'-'A')||(*pre[left]==*pre[right]+'A'-'a'))){left--;right++;move++;}if(move){right--;for(char* j=pre[++left];j<=pre[right];j++)//末端处理不好,总是会多输出和下一个字母间的符号。//原来是因为把'--'写在了for循环里,造成了被执行多次!!!这点要注意!这个程序里各种BUG,都是意外的。//其实也很简单,边界条件考虑还是不周全!对sizeof还是不熟练。cout<<*j;cout<<'\n';}//另一种情况,对称字符串。move=0;left=i-1;right=i;while(left>=0&&right<pre_i&&(*pre[left]==*pre[right]||(*pre[left]==*pre[right]+'a'-'A')||(*pre[left]==*pre[right]+'A'-'a'))){left--;right++;move++;}if(move){right--;for(char* j=pre[++left];j<=pre[right];j++)cout<<*j;cout<<'\n';}i++;}}int main(){FILE *fin;fin=fopen("input.txt","rb");s[N]=fscanf(fin,"%s",s);printpalin();getchar();}
很高兴最后这个程序没有BUG了,对于二重指针的理解也有了一些。

可见解决问题前一定要考虑好方法,下面的程序是一个失败的例子。我尝试理清其中的思路,但是最后不得不放弃。因为这段程序实在是太烂&乱了……

想法是好的,但是BUG实在太多了,可能会尝试会改一改这段,让它能正常运行。

#include<iostream>#include<string.h>using namespace std;const int N=500;char s[N];void tst(char a){cout<<a<<';';}void ifpalin()//我觉得我应该用预处理。。。。。。!!!!!!已然不想写了,数据结构的重要性!{int left,right,i=0;while(s[i]){//tst('A');//寻找第一个非符号点。while(!isalpha(s[i])){i++;//tst('B');}left=i-1;right=i+1;while(s[left]&&(!isalpha(s[left]))&&right<sizeof(s)){left--;//tst('C');}//寻找标点左边第一个非符号点。while(s[right]&&(!isalpha(s[right]))&&left>=0){right++;//tst('D');}//寻找右边第一个非符号点。if(isalpha(s[right])&&isalpha(s[left]))//必须是左右都有才能判断。{while(s[left]==s[right]&&left>=0&&right<sizeof(s)){//tst('E');while(left>=0&&!isalpha(s[left--]));while(right<=sizeof(s)&&!isalpha(s[right++]));//写在while里可以多加一次}if(left!=(i-1)&&left!=right){for(int j=++left;j<right;j++)cout<<s[j];cout<<'\n';}}i++;//两种情况。用两次。不能用if简化,没想好一串aaaaaaaaaaa时怎么处理}}int main(){FILE *fin;fin=fopen("input.txt","rb");s[N]=fscanf(fin,"%s",s);ifpalin();getchar();}



0 0