将一个字符串中的大写字母删去,在现有知识范围,有以下几种方法
①遍历字符串,找到大写字母,将该大写字母后边的元素(包括\0)全部向前移一位,可将该大写字母删去
#include <>
#include <>
int main(void)
{
int i,j;
char s[81];
gets(s);
//接下来开始遍历字符串
i=0;
while(s[i])
{/*这里用s[i]当条件,而不用字符串的长度
是因为\0也会被移动,因此长度也会发生
改变*/
if(s[i]>='A' && s[i]<='Z')
{
j=i;//若找到大写字母,将s[i]后面所有的字符向前移
while(s[j]=s[j+1]) ++j;
//这里i不自增的原因是:若有两个大写字母挨着,便会跨过一个
}
else ++i;
}
puts(s);
return 0;
} 时间复杂度o(N²)
②遍历字符串,用另一个字符串接守所有非大写字母的字符
#include <>
#include <>
int main(void)
{
int i,j;
char s1[81],s2[81];
//s2用于接收非大写字母字符
gets(s1);
//接下来遍历s1
i=j=0;
while(s1[i])
{
if(!(s1[i]>='A' && s1[i]<='Z'))
s2[j++]=s1[i];//若是非大写,用s2接收
i++;
}
s2[j]=0;//千万不要忘记补0
//将s2复制到s1
i=j=0;
while(s1[i++]=s2[j++]);
puts(s1);
return 0;
} 时间复杂度o(N)
该方法浪费空间换时间,改进该方法,可以不用浪费空间:
将s1在逻辑上看作两个字符串
i=j=0;
while(s1[i])
{
if(!(s1[i]>='A' && s1[i]<='Z'))
s1[j++]=s1[i];
i++;
}
s1[j]=0;
puts(s1);
③用二分法,两个变量一个从前面找大写字母,一个找非大写字母,然后交换
#include <>
#include <>
int main(void)
{
int i,l,j;
char s[81],t;
gets(s);
l=strlen(s);
//
i=0;
j=l-1;
while(i<j)
{
while(!(s[i]>='A' && s[i]<='Z') && s[i]) ++i;
//这里要加一个s[i]做条件否则可能越界
while(s[j]>='A' && s[j]<='Z' && j>-1) --j;
//同样,j也不能越界
if(i<j)//这里要进行判断若字符串为aaaaBB,若不加判断,就会出错
{
t=s[i];
s[i]=s[j];
s[j]=t;
}
}
s[i]=0;/*要在s[i](或者s[j+1])处补零
因为i最后必定停在第一个大写
字母上,j一定停在最后一个非大
字母字符上*/
puts(s);
return 0;
} 时间复杂度o(N)
当然这里可以不用嵌套循环,加上条件判断即可;
i=0;
j=l-1;
while(i<=j)
{
if(!(s[i]>='A' && s[i]<='Z') && s[i])
++i;
else if(s[j]>='A' && s[j]<='Z' && j>-1)
--j;
else
{
t=s[i];
s[i]=s[j];
s[j]=t;
}
}
s[i]=0;