字符串问题(一)

本文详细探讨了字符串问题,包括左旋字符串、字符是否包含、字符串匹配(KMP算法)、编辑距离、最长回文子串、最长公共子串等经典问题。针对每个问题,文章提供了多种解法,如暴力法、动态规划、KMP算法、Manacher算法等,旨在全面展示字符串处理的算法思想和优化技巧。
摘要由CSDN通过智能技术生成

字符串问题

1.左旋问题

2.字符包含问题

3.字符匹配KMP

4.编辑距离

5.最大回文子串,公共子串

6.最大公共子序列,回文子序列,上升子序列

7.基本字符串函数实现

8.大整数的加,,,,

9.合法回文,数字串

10.正则匹配,最长公共前缀,简化路经


1) 左旋字符串

定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部,如把字符串abcdef左旋转2位得到字符串cdefab。请实现字符串左旋转的函数,要求对长度为n的字符串操作的时间复杂度为O(n),空间复杂度为O(1).


思路一、暴力移位法

voidleftshiftone(char *s,int n) {

char t = s[0];

//保存第一个字符

for (int i = 1; i <n; ++i) {

s[i - 1] = s[i];

}

s[n - 1] = t;

}

如此,左移m位的话,可以如下实现:

void leftshift(char*s,int n,int m) {

while (m--) {

leftshiftone(s,n);

}

}


思路二、指针翻转法

#include<iostream>

#include<string>

usingnamespacestd;

voidrotate(string&str,intm) {

if(str.length() == 0 || m <= 0)

return;

intn = str.length();

if(m % n <= 0)

return;

intp1 = 0, p2 = m;

intk = (n - m) - n % m;

//交换p1,p2指向的元素,然后移动p1,p2

while(k--) {

swap(str[p1],str[p2]);

p1++;

p2++;

}

//重点,都在下述几行。

//处理尾部,r为尾部左移次数

intr = n - p2;

while(r--) {

inti = p2;

while(i> p1)

{

swap(str[i],str[i - 1]);

i--;

}

p2++;

p1++;

}

//比如一个例子,abcdefghijk

// p1p2

//当执行到这里时,defghia b c j k

//p2+m出界了,

//r=n-p2=2,所以以下过程,要执行循环俩次。

//第一次:j步步前移,abcjk->abjck->ajbck->jabck

//然后,p1++,p2++,p1a,p2k

//p1 p2

//第二次:defghij a b c k

//同理,此后,k步步前移,abck->abkc->akbc->kabc

}

//在尾部处理作了一点不同的处理优化

voidrotate(string&str,intm) {

if(str.length() == 0 || m < 0)

return;

//初始化p1,p2

intp1 = 0, p2 = m;

intn = str.length();

//处理m大于n

if(m % n == 0)

return;

//循环直至p2到达字符串末尾

while(true){

swap(str[p1],str[p2]);

p1++;

if(p2 < n - 1)

p2++;

else

break;

}

//处理尾部,r为尾部循环左移次数

intr = m - n % m;

while(r--)

//r = 1.

//外循环执行一次

{

inti = p1;

chartemp = str[p1];

while(i < p2)

//内循环执行俩次

{

str[i]= str[i + 1];

i++;

}

str[p2]= temp;

}

}


思路三,三步翻转法

char*invert(char*start,char*end) {

chartmp, *ptmp = start;

while(start != NULL && end != NULL && start < end) {

tmp= *start;

*start= *end;

*end= tmp;

start++;

end--;

}

returnptmp;

}

char*left(char*s,intpos)//pos为要旋转的字符个数,或长度,下面主函数测试中,pos=3

{

intlen = strlen(s);

invert(s,s + (pos - 1));

//如上,X->X^T,abc->cba

invert(s+ pos, s + (len - 1));//如上,Y->Y^T,def->fed

invert(s,s + (len - 1));

//如上,整个翻转,(X^TY^T)^T=YX,cbafed->defabc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值