每日一題11:替換字符串中的空格

用指定的字符或字符串替換某個字符串中出現的所有空格,當用字符替換字符是,自然是很簡單的,但是當使用字符串替換字符時,如果還是從前往後遍歷,遇到指定字符就將其後所有字符往後移出足夠空間的話,當字符串中的空格很多時,反覆的移動字符會帶來性能上的損失。但是如果是從後往前遍歷呢?可以先遍歷一次原字符串,得到字符串中空格的個數,然後就可以計算出實際需要的空間,再假設原字符串所在緩衝區有足夠空間(否則新建一個緩衝區從前往後遍歷就行了,這裏說的是在不新建緩衝區的情況下做這件事),那麼就可以計算出每個字符最後的位置,到算法中可以用一個指針q指向替換後字符串的最後一個字符(也就是字符串結束符)所在的位置,指針p指向原字符串的最後一個字符(字符串結束符),然後兩個指針向前遍歷,如果p指向的字符爲空格,那麼就將替換字符串從後向前填充到q指向的位置(該過程中p不動,q繼續向前,第一次遍歷後所做的計算保證q不會追上p),然後兩個指針繼續向前遍歷。這樣就得到一個O(N)的算法了。

#include "stdafx.h"
#include <iostream>
using namespace std;

const int bufsize = 1024;

void Replace(char** str, char target_char,const char* replace_str)
{
    int replace_str_len = strlen(replace_str);
    char* p = *str;
    int target_char_fre = 0;
    int str_len = 0;
    while(*p)
    {
        if(*p == target_char) ++target_char_fre;
        ++str_len;
        ++p;
    }
    int extend_count = target_char_fre * (replace_str_len - 1);
    char * q = p + extend_count;
    int j = 0;
    while(j <= str_len)
    {
        if(*p != target_char)
            *q-- = *p--;
        else
        {
            const char* r = &replace_str[replace_str_len - 1];
            int i = 0;
            while(i < replace_str_len)
            {
                *q-- = *r--;
                ++i;
            }
            --p;
        }
        ++j;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    char * str = new char[bufsize];
    strcpy(str," wo shi zhong guo ren!");
    Replace(&str,' ',"%20");
    cout<<str<<endl;
    return 0;
}

這裏寫圖片描述
如果從一個方向走不通,那就換個方向試試!這種方法還可以用於數組的插入等類似的情景中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章