字符串类型题从基础到进阶总结
字符串很大的一个特点是其结尾的‘\0’,很多设字符串的基础问题都是从此出发思考的。
如果你对字符串还不是特别熟练,或者想找一些相关的题目练练手,推荐可以做做洛谷的“字符串”题单。
基础篇:
下面我总结的题型,基础篇主要是对字符串的一些基本操作,基本没有算法,考研的是你如何用尽可能少的代码实现要求,而不是通过五六十行甚至一百多行才解决。故基础篇侧重的是优化。
一:
/**********
【习题7.275】假定字符串s中可能含有字符'*'。请编写函数,
若字符串s的尾部连续的'*'多于n个,则删除多余的'*'。例如,
若s="*****A*BCDE**F*******"且n=4,则调用函数后,字符串
s="****A*BCDE**F****";若n≥7,则字符串s中的内容不变。
注意:函数中不得调用C语言提供的字符串函数。
**********/
既然要删除尾部连续的*,那就直接从尾部开始循环咯,没必要从头开始,还要判断是不是尾部,自己给自己挖坑。什么?你真的去删除星号了?直接在尾端置0不就好了
void func(char s[], int n)
{
int i;
int count = 0;
for ( i=strlen(s)-1; s[i]=='*'; i-- )
count++;
s[strlen(s)-(count-n)] = 0;
}
二:
/**********
【习题7.335】假设字符数组a中存放了按由小到大连续存放的
字符构成的字符串(后跟一个'\0'作为结束符)。编写函数,
删去字符串中所有重复的字符(各自只保留一个),并使得保
留的字符仍构成一个字符串(连续存放,'\0'作为结束符)。
函数返回a中保留的字符串长度。例如,若a中的字符串值为:
AAABBCDFFFHHHKLMMM
则删除重复字符之后,函数返回值为9,a中的字符串值为:
ABCDFHKLM
**********/
这也是一个删除型的题目,一开始我的想法是把重复的字母直接由后面的字符串左移覆盖实现,的确可以,但要注意的是要把结尾的’\0’也跟着一起移动,不然会出现
ABCDFHKLMMMMMMM
的情况,即最后的字母被”拉长“了。
但这并不是最优的做法,因为如果字符串很长,重复单元很多,每次你都要全部左移,有点要命。时间复杂度有点高的吓人。
其实按照人的思路来思考,如果我们考试遇到这个题目,我们会在草稿纸上另起一行,然后眼镜扫过这个字符串,每个相同的字母我们只记录一次在这一行中。嗯,我们可以另起一个数组,但其实没必要,直接在原数组操作就好。
int func(char a[])
{
int i,t=1;
for ( i=0; t<strlen(a); t++ )
{
if ( a[i] == a[t] )
continue;
else
++i,a[i]=a[t]
}
a[i+1] = 0;
return strlen(a);
}
三:
/**********
【习题7.355】假定字符串s中可能含有字符'*'。请编写函数,
将字符串s中前导'*'全部移到字符串的尾部。例如,若s的串
值为***A*BC*DEF*G**,移动后,串值应为A*BC*DEF*G*****。
注意:不得调用C语言提供的字符串函数。
**********/
这道题我们又要请到我么的老朋友了,移位覆盖大法,这个方法我们解决了在一个数组中删除一个元素的问题,这道题也是,我们要删除前面的星号。注意代码的简洁和优化。
void func(char s[])
{
int num;
int i;
for ( i=0; s[i]=='*'; i++ );
num = i--;
for ( i=num; i<strlen(s); i++ )
s[i-num]=s[i];
for ( i=0; i<num; i++ )
s[strlen(s)-num+i]='*';
}
四:
下面的两道基础题都是字符串应用相关的了
/**********
【习题7.345】假设字符数组s中存放了一行字符串,含有由小写
字母组成的若干单词,单词之间由若干个空格隔开(串的开头没
有空格)。编写函数,统计一行字符串中单词的个数,并作为函
数值返回。
**********/
这道题可能很多人都做过了,但可能每个人的方法都不一样,下面我给一个简便的方法,即检索是否是空格+字母,若是即为新单词(首个单词除外),用bool而不是用int其实有那么一点点的空间优化吧,毕竟bool可只有一个字节呢,一般用这个”符号位“的小技巧时都设boo,在大数据可能会有优势~
int func(char s[])
{
bool mark=0;
int sum=0;
int i;
for ( i=0; s[i]!=0; ++i )
{
if ( s[i] == ' ' )
mark = 0;
else
if ( mark == 0 )
++sum, mark=1;
}
return sum;
}
五、
题目描述
笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼。但是他找到了一种方法,经试验证明,用这种方法去选择选项的时候选对的几率非常大!
这种方法的具体描述如下:假设maxn
是单词中出现次数最多的字母的出现次数,minn
是单词中出现次数最少的字母的出现次数,如果maxn-minn
是一个质数,那么笨小猴就认为这是个Lucky Word
&#