【题型总结】字符串类型题从基础到进阶总结

本文总结了字符串类型的题目,从基础到进阶,包括基础篇的字符串操作和进阶篇的动态规划问题。基础篇涵盖删除操作和字符串特性,进阶篇涉及动态规划解题策略,如最长回文子序列问题。文章强调动态规划在解决字符串问题中的应用,并提供了相关题目和代码示例。
摘要由CSDN通过智能技术生成

字符串类型题从基础到进阶总结

字符串很大的一个特点是其结尾的‘\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&#

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值