字符串的常见操作



字符串的常见操作:


(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.然后所有的字符串就可以排序了。
 

 

 

 




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值