0
点赞
收藏
分享

微信扫一扫

字符串的扩展操作22


字符串的扩展操作2:


(1)编写一个方法,将字符串中的空格全部替换为"%20".不允许开辟额外的内存空间。
如:"Mr John Smith"替换为"Mr%20John%20Smith";


1)分析:
对字符串(或数组)的操作,通常从字符串的尾部开始编辑,从后往前反向操作,不必担心会覆盖原来的数据。
如:memecpy的函数实现。


2)步骤:
1.先扫描一个字符串,计算出字符串中的空格数;
2.反向编辑字符串,将空格用%20替换。


3)代码实现:

void replaceSpaces(char* str,int length){

int spaceCount=0;

int newLength;

int i;



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

if(str[i]==' ')

spaceCount++;

}



newLength=length+spaceCount*2;//空格为一个字符,%20为3个字符。

str[newLength]='\0';//注意设置串的结束标识;



for(i=length-1;i>=0;i--){//反向扫描



if(' '==str[i]){

str[newLength-1]='0';

str[newLength-2]='2';

str[newLength-3]='%';

newLength=newLength-3;

}

else{

str[newLength-1]=str[i];

newLength=newLength-1;

}

}



}


-------


(2)基本的字符串压缩功能。如果压缩后的字符串没有变短,则返回以前的字符串,否则返回压缩后的字符串。
比如:字符串"aabccccaaa"变成"a2b1c4a3";


1)方法一:

public String compressStr(String str){

String myStr="";

char pre=str.charAt(0);

int count=1;



for(int i=1;i<str.length();i++){

if(str.charAt(i)==pre){

count++;

}

else{

myStr+=pre+""+count;

pre=str.charAt(i);

count=1;

}

}

return myStr+pre+count;//注意最后一组重复字符还未放到压缩字符中。

}



缺点:字符串的拼接部分的时间复杂度为O(n^2);
---
2)优化:使用StringBuffer;

String compressStr(String str){

int size=countCompression(str);//计算压缩后的 长度;

if(size>str.length())

return str;



StringBuffer mystr=new StringBuffer();

char pre=str.charAt(0);

int count=1;



for(int i=1;i<str.length();i++){

if(pre==str.charAt(i)){

count++;

}else{

mystr.append(pre);

mystr.append(count);

pre=str.charAt(i);

count=1;

}

}



mystr.append(pre);

mystr.append(count);

return mystr.toString();

}



/*计算压缩后的字符串的长度*/

int countCompression(String str){

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

return 0;



int size=0;//size为压缩后的字符串长度。

int count=1;//count为某个字符出现的个数

char pre=str.charAt(0);



for(int i=1;i<str.length();i++){

if(pre==str.charAt(i)){

count++;

}

else{

size=size+1+String.valueOf(count).length();

//将count转为字符串,再计算字符串的长度,再加上一个字符的长度。

pre=str.charAt(i);

count=1;

}

}



size=size+1+String.valueOf(count).length();

return size;

}




----
3)优化,不使用StringBuffer;


String compressStr(String str){

int size=countCompression(str);

if(size>str.length())

return str;



char* array=new char[size];//将压缩后的字符串存入到数组中;

int curIndex=0;//curIndex为数组中的当前索引。



char pre=str.charAt(0);

int count=1;



for(int i=1;i<str.length();i++){

if(pre==str.charAt(i))

count++;

else{

curIndex=setChar(array,pre,count,curIndex);//根据pre,count重新更新curIndex;

pre=str.charAt(i);

count=1;

}

}



index=setChar(array,pre,count,curIndex);

return String.valueOf(array);

}



int setChar(char* array,char c ,int count,int index){

array[index]=c;

index++;



char* cnt=String.valueOf(count).toCharArray();

//将count转换为String,在转为char数组。



for(char x:cnt){

array[index]=x;

index++;

}

return index;

}



----------



(3)若M*N矩阵中某个元素为0,则将其所在的行与列清零。


1)陷阱:
直接遍历整个矩阵,如果遇到某个元素的值为0,则将其所在的行与列清零。陷阱是,在读取被清零的行与列时,以及变成了0,所以最终整个矩阵都会变成0。


2)方法一:
建立一个矩阵,第一次扫描标记0元素的位置,在第二次扫描时,将0元素所在的行与列清零。
空间复杂度为O(M*N)


3)方法二:
将元素值为0的行与列清零,值需要建两个数组,分别记录下它的行号,与列号,即可。
时间复杂度为O(M+N);


实现:

public void setZeros(int ** matrix){

boolean[] row=new boolean[matrix.length];//行数组

boolean[] column=new boolean[matrix[0].length];//列数组



for(int i=0;i<matrix.length;i++){

for(int j=0;j<matrix[0].length;j++){

if(0==matrix[i][j]){

row[i]=true;

column[j]=true;

}

}

}//记录值为0的元素所在的行与列。




for(int i=0;i<matrix.length;i++){

for(int j=0;j<matrix[0].length;j++){

if(row[i] || column[j])

matrix[i][j]=0;

}

}

}




-------


(4)给定两个字符串str1和str2,判断str1是否由str2旋转而来。
如:waterbottle是由erbottlewat旋转而来。


1)分析:
str1如果是由str2旋转而来,满足2个条件;
1.str1与str2的长度相同。
2.str2是str1+str1子串。(+表示连接符)


2)代码实现:

public boolean isRotation(String str1,String str2){

int len1=str1.length();



if(len1==str2.length() && len1>0){

String str1str1=str1+str1;

return isSubString(str1str1,str2);

}

return false;


}



---------------

举报

相关推荐

0 条评论