字符串中的空格


1.清除空格

       編寫一個程序,把字符串中的每個空格清除掉。例如輸入“We are happy.”,則輸出“Wearehappy.”。

  • 編程思路

        由於字符串的內存分配方式是連續分配的。我們從字符串當中刪除一個空格字符時,需要把后面所有的字符往前移動一個字節的位置。但如果每次刪除都需要移動字符串后面的字符的話,對於一個長度為n 的字符串而言,刪除一個空格字符的時間復雜度為O(n) 。而對於本題而言,有可能要刪除的空格字符的個數是n ,因此該方法就刪除而言的時間復雜度為O(n2) 。

        事實上,我們並不需要在每次刪除一個空格的時候都去移動后面所有的字符。我們可以設想,當一個空格需要被刪除的時候,我們把它所占的位置讓它后面的字符來填補,也就相當於這個空格被刪除了。具體方法為:

        (1)定義兩個指針p1和p2,p2用於遍歷原始字符串,p1用於指向結果字符串中當前賦予的非空格字符。初始狀態都指向字符串首字符。

        (2)如果p2指向的元素不為空格,那么將p2指向的內容賦值給p1,然后p1和p2指向下一個元素;如果p2指向的內容為空格,那么p2指向下一個元素,p1保持不動。

        (3)直到p2指向字符串末尾的“\0”時,清除空格結束。

  • 源程序及運行結果

#include<iostream>

using namespace std;

int main()

{

    char str[81];

    cin.getline(str,80,'\n');   

    //設置兩個指針指向數組首元素

    char *p1=str;

    char *p2=str;

    while(*p1!='\0')

    {

        if(*p2!=' ')  //如果p2指向不為空格,則將p2指向內容復制給p1指向

            *p1++=*p2++;

        else   //如果p2指向為空格,則p2指針向前移動一格。

            p2++;

    }

    cout<<str<<endl;

    return 0;

}

 

        上例刪除字符串中的所有空格,在實際應用中,有時空格需部分保留,如字符串中的多個連續空格,則保留1個。這樣,可以將這個問題進行擴展,對給定字符串,刪除開始和結尾處的空格,並將中間的多個連續的空格合並成一個。

2.清除多余空格

        編寫一個程序,對給定的字符串,刪除開始和結尾處的空格,並將中間的多個連續的空格合並成一個。例如輸入"  We   are   happy.   ",則輸出"We are happy."

  • 編程思路

        因為需要刪除開始和結尾處的空格,而字符串中間的空格又需要保存一個,因此需要進行另外的處理。可以通過設置一個標識位來進行處理,定義一個bool變量flag表示是否保存一個空格,如果flage=true表示保存一個空格,如果flag=false則不保存空格。初始化的時候將flag設為false,這樣開始階段的空格都不會被保存,當碰到一個不為空格的字符時,保存該字符,然后設置flag=true表明會保存后面待掃描的字符串中的第一個空格,這樣在碰到第一個空格時就能夠保存。

       按上面的操作方法,掃描結束后,目標字符串的結尾要么是非空格字符,要么是一個空格字符,這樣進行一次判斷就好了,如果是空格字符,這將該空格設為“\0”,如果不為空格字符,則在其后面加上“\0”。

  • 源程序及運行結果

#include<iostream>

using namespace std;

int main()

{

    char str[81];

    cin.getline(str,80,'\n');   

    int index=0;

    bool flag=false;

    for(int i=0;str[i]!='\0';i++)

    {

        if(str[i]!=' ')       // 如果遍歷到的是非空格字符,則進行賦值

        {

            str[index++]=str[i];

            flag=true;     // 表示允許保存一個空格

        }

        else if(flag)       // 如果允許有一個空格

        {

            str[index++]=str[i];

            flag=false;

        }

    }

    if(index>0&&str[index-1]==' ')      //處理字符串最后的多余空格

    {

        str[index-1]='\0';

    }

    else

    {

        str[index]='\0';

    }

    cout<<str<<endl;

    return 0;

}

 

       在網絡編程中,如果URL參數中含有特殊的字符,如空格、“#”等,導致服務器端無法識別時,就把這些特殊的字符轉換成可以識別的字符。轉換規則是:%加上十六進制的ASCII碼,例如空格的ASCII碼是32(16進制為0x20),就被替換成%20。

3.替換空格

      編寫一個程序,把字符串中的每個空格替換成“%20”。例如輸入“We are happy.”,則輸出“We%20are%20happy.”。

  • 編程思路

       將長度為1的空格替換為長度為3的“%20”,字符串的長度會變長。如果另外開辟一個新的數組來存放替換空格后的字符串,那么這個問題非常容易解決。設置兩個指針分別指向新舊字符串首元素,遍歷原字符串,如果碰到空格就在新字符串中填入“%20”,否則就復制原字符串中的內容。但這種新開辟數組保存結果字符串的做法,會造成空間的浪費。

        如果在原字符串后面有足夠多的空余空間,可以在原來的字符串上做替換。下面來探討替換的方法。

       因為把空格替換為”%20“,每次替換多2個字符,因此在可以統計出原來字符串的長度和其中空格的總個數后,計算出結果字符串的長度為“原字符串長度 + 2*空格數 ”。

       替換操作從后往前進行,思路為:遇到非空格,直接搬到后面;遇到空格,替換為“%20”。 直到待插入位置指針和原字符串的掃描指針的位置重合。具體過程描述為:

      (1)首先遍歷原字符串str,統計出原字符串的長度strlen以及其中的空格數量blanknum。

      (2)根據原字符串的長度和空格的數量,求出結果字符串的長度newlen,即newlen=strlen+blanknum*2。

      (3)定義兩個指針p1和p2分別指向原字符串和結果字符串的末尾位置,即p1=str+strlen、 p2=str+newlen。

      (4)如果p1指向內容不為空格,那么將內容直接賦值給p2指向的位置,且p2指針前移;如果p1指向內容為空格,那么從p2指向位置開始賦值“02%”。

      (5)p1指針前移。

      (6)直到p1==p2時,表明字符串中的所有空格都已經替換完畢。

      例如,按上述操作過程,將字符串“Hello world ”中的空格進行替換的操作如圖1所示。

圖1  空格替換操作過程

  • 源程序及運行結果

#include<iostream>

using namespace std;

int main()

{

    char str[81];

    cin.getline(str,80,'\n');   

    int strlen=0;

    int blanknum=0;

    int i=0;

    //求字符串長度和空格數量

    while(str[i]!='\0')

    {

        strlen++;

        if(str[i]==' ')

            blanknum++;

        i++;

    }

    int newlen=strlen+blanknum*2;//求新字符串長度

    if(newlen>=80)

    {

        cout<<"替換后,串超過了預定義的長度。"<<endl;

              return 0;

       }

    //設置兩個指針指向新舊數組末尾

    char *p1,*p2;

       p1=str+strlen;       p2=str+newlen;

    //當上面兩個指針指向同一個元素則表明沒有空格

    while(p1>=str && p2>p1)

    {

        if(*p1==' ')

        {

            *p2='0'; p2--;

            *p2='2'; p2--;

            *p2='%'; p2--;

        }

        else

        {

            *p2=*p1;  p2--;

        }

        p1--;

    }

    cout<<str<<endl;

    return 0;

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM