optimal

更新时间:2022-11-27 10:14:26 阅读: 评论:0


2022年11月27日发(作者:rl是什么意思啊)

OptimalSolution(4)--字符串问题(1)简单

⼀、判断两个字符串是否互为变形词

问题:给定两个字符串str1和str2,如果str1和str2中出现的字符种类⼀样且每种字符出现的次数也⼀样,那么str1与str2互为变形词。

举例:str1=“123”,str2=“231”,返回true。str1=“123”,str2=“2331”,返回fal。

思路:如果str1和str2长度不同,直接返回fal。如果长度相同,假设出现字符的编码值在0~255之间,那么先申请⼀个长度为256的整

型数组map。map[a]=b代表字符串编码为a的字符出现了b次。初始始map都为0。然后遍历str1,统计每种字符出现的数量,⽐如遍历到字

符‘a’,则令map[97]++,这样map就成了str1中每种字符的词频统计表。然后遍历str2,没遍历⼀个字符都在map中把词频减去1,如果减少

之后的值⼩于0,直接返回fal。如果遍历完str2,map中也没出现负值,返回true。

publicbooleanisDeformation(Stringstr1,Stringstr2){

if(str1==null||str2==null||()!=()){

returnfal;

}

char[]chas1=Array();

char[]chas2=Array();

int[]map=newint[256];

for(inti=0;i<;i++)map[chas1[i]]++;

for(inti=0;i<;i++){

if(map[chas2[i]]--==0)returnfal;

}

returntrue;

}

判断两个字符串是否互为变形词

⼆、字符串中数字⼦串的求和

题⽬:给定⼀个字符串str,求其中全部数字串所代表的数字之和。其中:1.忽略⼩数点字符,例如“A1.3”,其中包含两个数字1和3。2.

如果紧贴数字⼦串的左侧出现字符‘-’,当连续出现的数量为奇数时,则数字视为负,连续出现的数量为偶数时,则数字视为正。例如“A-

1BC--12”,其中包含-1和12

解法:(1)⽣成三个变量,整型变量res表⽰⽬前的累加和;整型变量num表⽰当前收集到的数字;布尔型变量posi,表⽰如果把num

累加到res⾥,num是正还是负。初始时,res=0,num=0,posi=true。(2)如果遍历到的字符cha是‘0’~‘9’,则cha-‘0’的值记为cur,posi表

⽰cur的符号。例如:str=“123”,初始时num=0,posi=true。则num=0*10+1,num=1*10+2,num=12*10+3。假设str=“-123”,那么

posi=fal,此时num=0*10+(-1),num=-1*10+(-2),num=-12*10+(-3),因此有num=num*10+(posi?cur:-cur)(3)如果遍历到的字符

cha不是‘0’~‘9’,说明前⼀阶段的数已经明确是num了,因此先令res+=num,然后令num=0。此时如果cha不是‘-’,令posi=true。如果cha

是‘-’,此时看cha的前⼀个字符,如果cha的前⼀个字符也是‘-’,则posi=!posi;否则令posi=fal。(4)还需要注意的是,由于res+=num

发⽣在⾮数字字符之前,如果字符串最后⼀位是数字字符,就使得最后⼀个num⽆法加到res上,因此最后还需要res+=num。

publicintnumSum(Stringstr){

if(str==null)return0;

char[]charArr=Array();

intres=0;

intnum=0;

booleanposi=true;

intcur=0;

for(inti=0;i<;i++){

cur=charArr[i]-'0';

if(cur<0||cur>9){

res+=num;

num=0;

if(charArr[i]=='-'){

if(charArr[i-1]=='-'){

posi=!posi;

}el{

posi=fal;

}

}el{

posi=true;

}

}el{

num=num*10+(posi?cur:-cur);

}

}

res+=num;

returnres;

}

字符串中数字⼦串的求和

三、去掉字符串中连续出现k个0的⼦串

题⽬:给定⼀个字符串str和⼀个整数k,如果str中正好有连续的k个‘0’字符出现时,把k个连续的‘0’字符去除,返回处理后的字符串。

解法:(1)⽣成两个变量。整型变量count表⽰⽬前连续个‘0’的数量;整型变量start表⽰连续出现连续个‘0’的开始位置。初始

时,count=0,start=-1(2)如果cha是字符‘0’,令start=start==-1?i:start,即如果start不等于-1,说明之前就已经处在连续的‘0’的阶

段,所以start不变,count++(3)如果cha不是‘0’,如果count等于k,说明之前发现的连续k个‘0’可以从start位置开始去掉,如果不等于,说

明之前发现的连续的‘0’的数量不是k个,因此不能去掉,最后令count=0,start=-1。(4)如果str是以‘0’结尾的,可能会出现最后⼀组k个连

续的‘0’没有去掉的情况,所以要检查⼀下count是否等于k。

注意:下⾯这段代码中,chas[start++]=0;表⽰的是,ASCII码表中0表⽰null,因此如果str“a0000b000c00”,k=4,则结果为“a

b000c00”

if(count==k){

while(count--!=0){

chas[start++]=0;

}

}

完整代码:

publicStringremoveKZeros(Stringstr,intk){

if(str==null||k<1)returnstr;

char[]chas=Array();

intcount=0,start=-1;

for(inti=0;i<;i++){

if(chas[i]=='0'){

count++;

start=start==-1?i:start;

}el{

if(count==k){

while(count--!=0){

chas[start++]=0;

}

}

count=0;

start=-1;

}

}

if(count==k){

while(count--!=0){

chas[start++]=0;

}

}

f(chas);

}

去掉字符串中连续出现k个0的⼦串

四、判断两个字符串是否互为旋转词

题⽬:如果⼀个字符串str,把字符串str前⾯任意的部分挪到后⾯形成的字符串叫做str的旋转词。例如str=“12345”,则str的旋转词

为“12345”,“23451”,“34512”,“45123”和“51234”

解法:如果a和b的长度不⼀样那么返回fal。如果a和b长度⼀样,先⽣成变量Stringb2=b+b,然后看b2中是否包含字符串a。例

如,a=“cdab”,b=“abcd”,那么b2=“abcdabcd”,则b2[0...3]、b2[1...4]、b2[2...5]、b2[3...6]、b2[4...7]都是b的旋转词。即如果⼀个字符串b的

长度为N,在通过b⽣成的b2中,任意长度为N的⼦串都是b的旋转词,⽽且b2中包含字符串b的所有旋转词。(可以通过KMP算法实现时间

复杂度为O(N))

publicbooleanisRotation(Stringa,Stringb){

if(a==null||b==null||()!=()){

returnfal;

}

Stringb2=b+b;

ns(a);

}

判断两个字符串是否为旋转词

五、替换字符串中连续出现的指定字符串

问题:给定三个字符串str、from和to,把str中所有from的⼦串全部替换成to字符串,对连续出现from的部分要求只替换成⼀个to字符

串。

例如:str=“123abc”,from=“abc”,to=“4567”,返回“1234567”。str=“123abcabc”,from=“abc”,to=“X”,返回“123X”

思路:把str中from部分所有位置的字符编码设为0(即空字符),例如str=“12abcabca4”,from=“abc”,处理后str为

[‘1’,‘2’,0,0,0,0,0,0,‘a’,‘4’],然后把不为0的区域拼在⼀起,连续为0的部分⽤to代替,即“12”+to+“a4”

解法:(1)⽣成整型变量match,表⽰⽬前匹配到from字符串的什么位置,初始时,match=0(2)如果str[i]==from[match]。如果

match是from的最后⼀个字符的位置,说明str中发现了from字符串,则从i位置向左的M个位置,都把字符编码设为0,M为from的长度,然后

令match=0,如果match不是from最后⼀个字符的位置,令match++,继续遍历str的下⼀个字符串(3)如果str[i]!=from[match],说明匹配失

败,令match=0,(4)拼接字符串。

注意:对于连续的0的区域的处理⽅式

if(chas[i]==0&&(i==0||chas[i-1]!=0)){

res=res+cur+to;

cur="";

}

完整代码:

publicStringreplace(Stringstr,Stringfrom,Stringto){

if(str==null||from==null||("")||("")){

returnstr;

}

char[]chas=Array();

char[]chaf=Array();

intmatch=0;

for(inti=0;i<;i++){

if(chas[i]==chaf[match++]){

if(match==){

clear(chas,i,);

match=0;

}

}el{

match=0;

}

}

Stringres="";

Stringcur="";

for(inti=0;i<;i++){

if(chas[i]!=0){

cur=cur+f(chas[i]);

}

if(chas[i]==0&&(i==0||chas[i-1]!=0)){

res=res+cur+to;

cur="";

}

}

if(!(""))res=res+cur;

returnres;

}

publicvoidclear(char[]chas,intend,intlen){

while(len--!=0){

chas[end--]=0;

}

}

替换字符串中连续出现的指定字符串

六、字符串的统计字符串

题⽬1:给定⼀个字符串str,返回str的统计字符串,例如,“aaabbadddffc”的统计字符串为“a_3_b_2_a_1_d_3_f_2_c_1”

解法:(1)如果str为空,那么统计字符串不存在(2)如果str不为空,⽣成String类型的变量res表⽰统计字符串,整型变量num代表当

前字符的数量。初始时res只包含str[0],同时num=1(3)从str[1]开始遍历,如果str[i]==str[i-1],说明当前连续的字符str[i-1]还没结束,令

num++。(4)如果str[i]!=str[i-1],说明到str[i-1]已经结束,令res=res+“_”+num+“_”+str[i],然后令num=1(5)当遍历结束时,最后的字符还

没有放⼊res,所以令res=res+“_”+num

publicStringconcat(Strings1,Strings2,Strings3){

returns1+"_"+s2+(("")?s3:"_"+s3);

}

publicStringgetCountString(Stringstr){

if(str==null||("")){

return"";

}

char[]chs=Array();

Stringres=f(chs[0]);

intnum=1;

for(inti=1;i<;i++){

if(chs[i]!=chs[i-1]){

res=concat(res,f(num),f(chs[i]));

num=1;

}el{

num++;

}

}

returnconcat(res,f(num),"");

}

返回字符串的统计字符串

题⽬2:给定⼀个字符串的统计字符串cstr,再给定⼀个整数index,返回cstr所代表的原始字符串上的第index个字符。

解法:(1)⽣成布尔型变量stage,stage为true时表⽰要遇到字符,为fal表⽰要遇到字符统计。字符型变量cur表⽰在上⼀个遇到字

符阶段时,遇到的是cur字符。整型变量num,表⽰在上⼀个遇到连续字符统计的阶段,字符出现的数量。整型变量sum,表⽰⽬前遍历到

cstr的位置相当于原字符串什么位置。初始时,stage=true,cur=0(空字符),num=0,sum=0(2)以cstr=“a_100_b_2_c_4”,index=105

为例,遍历完str[0]='a'后cur=‘a’;遇到str[1]='_',stage=!stage;表⽰接下来⼏个字符表⽰出现次数,依次为num=1,num=10,num=100;

然后是下划线,此时stage=!stage,表⽰要遇到的是字符;遇到str[6]='b',即⼀个新的字符出现了,此时sum+=num,即sum=100,也就是

原字符串有100个a,由于100<105,因此继续遍历;...每次遇到⼀个新字符,都把上⼀个num加到sum上,如果sum已经到达index,那么就

返回上⼀个字符cur。

注意:num=num*10+chs[i]-'0';将字符串因此转换成整数

publicchargetCharAt(Stringcstr,intindex){

if(cstr==null||("")){

return0;

}

char[]chs=Array();

booleanstage=true;

intsum=0;

intnum=0;

charcur=0;

for(inti=0;i<;i++){

if(chs[i]=='_'){

stage=!stage;

}elif(stage){

sum+=num;

if(sum>index){

returncur;

}

num=0;

cur=chs[i];

}el{

num=num*10+chs[i]-'0';

}

}

returnsum+num>index?cur:0;

}

根据统计字符串及索引范返回原字符串中的字符

七、字符串的调整与替换

问题1:给定⼀个字符类型的数组chas,chas右半区全是空字符,左半区不含有空字符。将左半区左右的空格字符替换成“%20”,假设

chas右半区⾜够⼤,可以满⾜替换所需要的空间。例如“abc空字符”,替换后左半区为“a%20b%20%20c”

解法:(1)先遍历⼀次,可以得到两个信息,chas的左半区长度记为len,左半区空格记为num,即空格被“%20”替换后长度为

len+2*num。(2)从左半区的最后⼀个字符开始倒着遍历,同时将字符复制到新长度的最后的位置,并依次向左倒着复制。遇到空格就依

次把“0”、“2”和“%”进⾏复制。

注意:1.⼀个for⽅法可以同时得到len和num,这种技巧值得学习。2.从右往左倒着遍历。

publicvoidreplace(char[]chas){

if(chas==null||==0){

return;

}

intnum=0;

intlen=0;

for(len=0;len<&&chas[len]!=0;len++){

if(chas[len]==''){

num++;

}

}

intj=len+num*2-1;

for(inti=len-1;i>-1;i--){

if(chas[i]!=''){

chas[j--]=chas[i];

}el{

chas[j--]='0';

chas[j--]='2';

chas[j--]='%';

}

}

}

问题2:给定⼀个字符类型的数组chas,其中只含有数字字符和“*”字符,想将“*”字符挪到chas的左边,数字字符挪到chas的右边。例

如“12**345”,调整后为“**12345”。

解法:和问题1⼀样,依然是从右往左复制,遇到数字直接复制,遇到“*”不复制,当把数字字符复制完,把左半区全部设置成“*”即可。

注意:for(;j>-1;){chas[j--]='*';}这种表达。

publicvoidmodify(char[]chas){

if(chas==null||==0){

return;

}

intj=-1;

for(inti=-1;i>-1;i--){

if(chas[i]!='*'){

chas[j--]=chas[i];

}

}

for(;j>-1;){

chas[j--]='*';

}

}

⼋、反转字符串

问题1:给定字符类型数组chas,在单词键做依序调整。例如:“doglovespig”为“piglovesdog”。“I'mastudent.”为“'m”

解法:先把chas整体逆序,在把每个单词逆序。例如:“gipvolgod”→“piglovesdog”

注意:不能⽤String提供给你的rever⽅法,要⾃⼰实现才⾏。

publicvoidrever(char[]chas,intstart,intend){

chartmp=0;

while(start

tmp=chas[start];

chas[start]=chas[end];

chas[end]=tmp;

start++;

end--;

}

}

整体⽅法:注意for循环⾥⾯对于双指针l和r的使⽤技巧,这种⾼级表达要关注。

publicvoidrorateWord(char[]chas){

if(chas==null||==0){

return;

}

rever(chas,0,-1);

intl=-1;

intr=-1;

for(inti=0;i<;i++){

if(chas[i]!=''){

l=i==0||chas[i-1]==''?i:l;

r=i==-1||chas[i+1]==''?i:r;

}

if(l!=-1&&r!=-1){

rever(chas,l,r);

l=-1;

r=-1;

}

}

}

问题2:给定字符类型数组chas和整数size,把⼤⼩为size的左半区整体移到右半区。例如“ABCDE”且size=3,则“DEABC”

解法1:先把chas[0...size-1]部分逆序,再把chas[size...N-1]部分逆序,最后把chas整体逆序。

publicvoidrorate1(char[]chas,intsize){

if(chas==null||size<=0||size>=){

return;

}

rever(chas,0,size-1);

rever(chas,size,-1);

rever(chas,0,-1);

}

九、找到指定的新类型字符

问题:新类型字符是长度为1或者2的字符串。表现形式为:仅⼀个⼩写字母;⼤写+⼩写;⼤写+⼤写。给定字符串str,找出第k个的新

类型字符串。例如:str=“aaABCDEcBCg”,当k=7时,返回“Ec”。

思路:str=“aaABCDEcBCg”可以被拆成“a”,“a”,“AB”,“CD”,“Ec”,“BC”,“g”。k=7时,uNum=5;k=4时,uNum=2;k=10

时,uNum=2。

解法:(以⼩写字母为分隔符)从k-1位置开始,向左统计连续出现的⼤写字母的数量uNum,遇到⼩写字母就停⽌。如果uNum为奇

数,str[k-1...k]就是要找的;如果uNum为偶数且str[k]是⼤写字母,str[k...k+1]就是要找的;如果uNum为偶数且str[k]是⼩写字母,则str[k]是要

找的。

注意:if((uNum&1)==1)⽤来判断uNum是奇数还是偶数

publicStringpointNewChar(Strings,intk){

if(s==null||("")||k<0||k>=()){

return"";

}

char[]chas=Array();

intuNum=0;

for(inti=k-1;i>=0;i--){

if(!rCa(chas[i])){

break;

}

uNum++;

}

if((uNum&1)==1){

ing(k-1,k+1);

}

if(rCa(chas[k])){

ing(k,k+2);

}

f(chas[k]);

}

本文发布于:2022-11-27 10:14:26,感谢您对本站的认可!

本文链接:http://www.wtabcd.cn/fanwen/fan/90/30379.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:helpful
下一篇:already
标签:optimal
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图