字符串的常见操作:
(1)单词的逆序:
(2)字符串的逆序:
(3)字符串与数字的相互转化:
(4)删除字符串中的指定元素:O(N)
(5)字符串的循环右移:
(6)字符串是否对称以及最大对称子串问题:
(7)求取字符串中出现多次(2次及其以上)的最大子串:
(8)规定字符的大小顺序,来给字符串来排序;
--------------------------
(一)单词的逆序:
(1)范例
如:I come from beijing.变成 beijing. from come I
(2)方法一:
1)思想:全盘逆序+部分逆序;
2)步骤:第一步全盘置换该语句成:.gnijieb morf emoc i。第二步进行部分翻转,如果不是空格,则开始翻转单词。
3)代码实现:
#include <iostream>
using namespace std;
int main ()
{
int num=-12345,i=0,j=0,flag=0,begin,end;
char str[]="i come from beijing.";
char temp;
j=strlen(str)-1;
//第一步是进行全盘翻转
while(j>i)
{
temp=str[i];
str[i++]=str[j];
str[j--]=temp;
}
//第二步进行部分翻转
i=0;
while(str[i])
{
if(str[i]!=' ')
{
begin=i;
while(str[i] && str[i]!=' ')
i++; //找到str[i]为空格符
i=i-1; //空格符回退一个
end=i;
}
while(end>begin) //部分翻转
{
temp=str[begin];
str[begin++]=str[end];
str[end--]=temp;
}
i++;
}
cout<<"string:"<<str<<endl;
}
精简一些:
void reverse(char str, int i ,int j)
{
while(j>i)
{
temp=str[i];
str[i++]=str[j];
str[j--]=temp;
}
}
int main ()
{
int num=-12345,i=0,j=0,flag=0,begin,end;
char str[]="i come from beijing.";
char temp;
j=strlen(str)-1;
//第一步是进行全盘翻转
reverse(str, i, j)
//第二步进行部分翻转
i=0;
while(str[i])
{
if(str[i]!=' ')
{
begin=i;
while(str[i] && str[i]!=' ')
i++; //找到str[i]为空格符
i=i-1; //空格符回退一个
end=i;
if (start < end) {
reverse(str, start, end);
}
}
i++;
}
cout<<"string:"<<str<<endl;
}
(3)方法二:
1)思想:
将字符串切割为多个单词,然后将单词放入到一个数组中,然后从数组的尾部开始输出。
2)示例图如下:
-------
(二)整数与字符串的相互转换:
(1)将字符串转换为整数;
1)思想:
例如有一个字符串"1234",依次将每一个字符转换为相应的数字(str[i]-'0'),然后乘以10累加;
如果字符串首字符标示的是一个负数,即str[0]=='-'。那么此时应该设置一个符号判断标示位(用来判断以后得到的整数是否需要乘-1),并把要处理的字符数组下标设置为1。
2)代码实现:
int str_to_int(char * str){
int isNeg=0;//判断是否有负号,=1,则有负号,=0则没有负号
int num=0;//返回十进制数
int i=0;
if('-'==str[0]){
i=1;
isNeg=1;
}
while(str[i]!='\0'){
num=num*10+(str[i]-'0');
i++;
}
if(isNeg==1){
num*=-1;
}
return num;
}
(2)整数转化为字符串:
1)思想:
123除10取模,得到数字3,此时商为12。再将12除10取模,得到数字2,商为1。这样,我们可以得到字符串“321”,接着进行一次逆序即可得到想要的字符串。
同样,如果该整数小于0,我们需要人为地将其变成正数,再进行取模运算!
2)代码实现:
void int_to_str(int num, char * str){
char strtemp[10];//存储num的逆序字符串;
int isNeg=0;//判断num是正,还是负
int i=0;
if(num<0){
num=0-num;
isNeg=1;
}
do{
strtemp[i++]=(num%10)+'0';
num/=10;
}while(num>0);
if(1==isNeg){
strtemp[i]='-';
}
int j=0;
while(i>=0){//将逆序的字符串放到str中
str[j]=strtemp[i];
j++;
i--;
}
str[j]='\0';
//一定要注意字符串的结束标识。
}
-----
(三)删除字符串中的元素:
(1)删除字符串中的数字:
1)举例:
删除字符串中的数字并压缩字符串。如字符串"abc123de4fg56"处理后变为"abcdefg"。时间
2)代码实现:
/*时间复杂度为O(N)*/
char* delete_digits(char* str)
{
char* i = str; // i for cursor, j for the first digit char;
char* j = str;
while(*i != '\0')
{
if (*i<'0' || *i>'9')
{
*j++ = *i++;
}
else
{
++i;
}
}
*j ='\0';//注意串的结束标识
return str;
}
(2)从时间复杂度为O(n),删除字符串中的多个字符。
1)举例:
如:字符串为"abcabde",删除字符串为"aba",即删除字符a,b,所以删除后为"cde".
2)思想:
利用位图的思想,
1.建立一个位图数组,然后初始化各个以字符为下标的的元素对应位置为0。
2.遍历删除数组,然后将以删除数组元素为下标的bit置为1.
(即位图中,元素值为1 的下标是要删除的字符)
3.遍历原字符串中的 所有元素,然后将该元素为下标,查看位图数组中相应的位是1还是0.
3)代码实现:
/*时间复杂度为 O(N);*/
void Remove_chars(char str[], char remove[])
{
int remove_arr[256];
for(int i=0; i<256; ++i)
remove_arr[i] = 0;
for(int i=0; remove[i]; ++i)
remove_arr[remove[i]] = 1;
int i = 0;
for(int j=0; str[j]; ++j)
{
if(!remove_arr[str[j]])
str[i++] = str[j];
}
str[i]='\0';
}
--------
(四)字符串的逆序:
/*将字符串array[start,end]逆序*/
void reverse(char * array ,int start ,int end){
char temp;
while(start<end){
temp=array[start];
array[start]=array[end];
array[end]=temp;
start++;
end--;
}
}
------
(五)字符串的循环右移:
(1)举例:
如字符串“abcde”,向右循环2位,则变成字符串“deabc”
(2)方法一:
1)思想:
部分逆序+全部逆序;
如:“abcde”向右循环右移2位,先将前三位逆序得到“cba”,后两位逆序得到“ed”,
然后“cbaed”整体逆序得到“deabc”.
(3)方法二:
扫描字符串构造一个循环链表,0号元素,作为循环链表的起始头,然后循环链表向后移动len(str)-shiftLen长度,
然后断开,此时的链表的顺序就是所求的顺序。
(4)方法三:
1.将所有字符串入队列。
2.将前len(str)-shiftLen个元素出队列,出完队列的同时再插入到队尾。
如:初始化“abcde”如队,则队中为“abcde”,然后len(str)-shiftLen=5-2=3;
然后a出队,插入到队尾,队列变成 “bcdea”,然后b出队并插入到队尾,然后c出队并插入到队尾。
--------
(五)字符串是否对称 以及求取最大的对称子串问题:
(1)字符串是否对称问题:
/*
symmetry ['sɪmɪtrɪ] 对称;
判断str[start,end]是否对称
*/
int isSymmetry(char * str,int start,int end) {
while(start<end){
if(str[str]!=str[end])
break;
else {
str++;
end--;
}
}
if(start>=end) return 1;
else return 0;
}
(2)查找字符串str中的最大对称子串,及其长度。
1)分析:
查找最大对称子串,应该从最大长度开始,找到则返回。不可以从最小的开始。
2)代码实现:
char * max_SubSymmetryStr(char * str, int length){
char* subString=(char *) malloc(sizeof(char)*length);
int Symmetry;//判断是否对称
for(int len=length;len>0;len--){
for(int j=0;j+len-1<length;j++){
//j,j+len-1分别是长为len的字符串的首字符和最后一个字符的下标。
subString=str.subString(j,j+len-1);
//获取str的从j到j+len的子串。
Symmetry=isSymmetry(subString ,0,len-1);
if(1==Symmetry)
return subString;
}
}
}
方法二如下:
http://blog.csdn.net/legend050709/article/details/39104783
----
(7):已知字母序列[d, g, e, c, f, b, o, a],请实现一个函数针对输入的一组字符串 input[] = {"bed", "dog", "dear", "eye"},按照字母顺序排序并打印。本例的输出顺序为:dear, dog, eye, bed。
1)思想:
1.根据字母序列,建立一个hashTable,比如说d,g,e,c,b,o,a分别对应1,2,3,4,5,6,7,8,字母的 比较大小就变成了对应的hash值的比较大小。
2.编写一个两个字符串,根据字母序列的比较大小函数;
3.然后所有的字符串就可以排序了。