又见回文
Time Limit: 1000MS Memory limit: 65536K
题目描述
“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。现在呢,就是让你判断输入的字符串是否是回文串。
输入
有多组输入,每行输入一串字符,保证字符串长度不会大于 100000,字符串由大小写英文字母和空格组成,以字符串“2013”作为结束标志。
输出
每行输出一个字符串,如果输入是回文串,输出“YES”,否则输出“NO”(注意:判断的时候空格是不作判断的,详见样例)。
示例输入
aaaa ggg g lozxvxoMJBCHsTXooXTsHCBJMoxvxzol i am a good acmer 2013
示例输出
YES YES YES NO
提示
来源
示例程序
#include<iostream>
#include<string>
#include<string.h>
using namespace std;
int main()
{
string c;
int n;
while(getline(cin,c,'\n'))
{
int flag=0;
int pos=0;
if(c=="2013")break;
while(pos!=-1)
{
pos=c.find(" ",0);
if(pos==-1)break;
c.erase(pos,1);
}
//cout<<c<<endl;
/*for(int i=0;i<strlen(c);i++)
{
if(c[i]==' ')
{ //低效的清除空格法,会T.L.E的
for(int j=i;j<strlen(c);j++)
{
c[j]=c[j+1];
}
}
}*/
n=c.size()/2;
for(int i=0;i<n;i++)
{
if(c[i]!=c[c.size()-1-i])
{
flag=1;
break;
}
}
if(flag)cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
return 0;
}
以上就是A了的情形,下面是一个WA的,比较一下:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int main()
{
int n;
while (1)
{
char c[100009]={0},a[100009]={0},ch=0;//定义了一个字符来存连续串之间的空格,但没有考虑到同时出现两个分隔符的情况
while (1) //如果以空格结尾,最后是' ','\n',不会出结果,而是继续等输入
{
if (ch=='\n'||a[0]=='\n')break;
cin>>a;
strcat(c,a);
ch=getchar();
if (ch=='\n'||a[0]=='\n')break;
}
cout<<c<<endl;
int flag=0;
if (!strcmp(c,"2013"))break;
n=strlen(c)/2;
/*for(int i=0;i<strlen(c);i++)
{
if(c[i]==' ')
{
for(int j=i;j<strlen(c);j++)
{
c[j]=c[j+1];
}
}
}*/
for (int i=0;i<n;i++)
{
if (c[i]!=c[strlen(c)-1-i])
{
flag=1;
break;
}/*cout<<c[i]<<"\t"<<c[strlen(c)-1-i]<<endl;*/
}
if (flag)cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
return 0;
}
PS:比较两次的代码,两次的思路不同。下面的:一行被空格分成很多串,每一串分别接入char a[ ],再将a中的字符串赋给总串c但分隔符不一定只是一个空格,所以这种方法会在输入时产生错误。上面的:一次就接一整行,接进来后处理这一行,收空格。仅比较一个处理好的字符串(无空格)毫无技术含量,就不再多说。
本题中用到的字符串处理函数总结:
(1) strlen(char*)、char*.size()这两个分别是"string.h"和"string"两个头文件里的函数,作用都是求出字符串的长度(不算字符数组中的串结束符)这个长度其实是串结束符所在位置的下标数字,也是不算结束符的字符总数。(以下函数的头文件见注)
(2) strcmp(char* c1,char* c2)这个函数非常有用,它的作用是比较两个字符串,并输出它们的大小关系:
<1>输出大于0:c1大于c2。
<2>输出等于0:c1等于c2。
<3>输出小于0:c1小于c2。
(3) strcat(char* c1,char* c2)它的作用是将字符串c2缀在字符串c1的后面,使之成为一个字符串。但有个前提:c1必须足够大,装得下它自己和c2,否则会访问到非法内存,导致程序非正常关闭。
(4) strrev(char* c)这个函数在本题中没有用到,但仔细一想,大大的有用。它的作用是将一个字符串反转,直接strrev(原串)得到反串再strcmp(原串)即可省去一大堆代码。但似乎有些编译器没有收这个函数,扼杀了一小部分人偷懒的愿望。
(5) strcpy(char* c1,char* c2)这个也没用到,它的作用是将字符串c2 copy到字符串c1,直接从c1[0]开始粘,粘到c2的结束符'\0'为止,也就是说,strcpy()之后,c1中只剩下c2了,这时如果输出c1,那么输出的完全是c2的内容。这个函数的限制与strcat()的一样,详见(3)。
(6) strupr(char*)将串中所有小写字母转换成大写。//昨天刚用了一次,人家OJ的编译器不认,TT。
(7) strtol(char *str, char **endptr, int base)具体用法见Strtol()详解。
(8) strstr(char* c1,char* c2)这个函数的作用是判断字符串c2是否是字符串c1的子串,若是,返回在c1中c2首次出现的指针;否则返回空指针。(判断子串很有用的一个函数,具体详见空指针。
(9) strspn(char* c1,char* c2)作用:返回字符串中第一个不在指定字符串中出现的字符下标,就是从哪里开始不一样的。
(10) strset(char* c1,char c)作用:把字符串c1中的所有字符都设置成字符c。特别注意:strset(s,c); 把字符串s中的所有字符都设置成字符c,但是s本身尚未赋值,也就是说没有字符串结束标志'\0',但是该函数执行时将直到发现'\0'才停止,这就会出现问题,干涉到其他变量(并有不可知性),一般情况下紧邻定义的变量在内存中也是连续的,很容易受到影响。解决办法: 调用strset()函数之前要为其赋值,例如char c[4]=“”;还可以设前n个字符。