替换空格和清除空格

本文转自http://www.2cto.com/kf/201307/230059.html

一、替换空格

请实现一个函数,把字符串中的每个空格替换成“%20”。例如输入“We are happy.",则输出”We%20are%20happy."

分析:在空间复杂度尽可能低的情况下,不允许开辟一个新的数组来存放替换空格后的字符串。如果从前往后替换字符串,那么保存在空格后面的字符串肯定会被覆盖。假设字符串的长度为n。对每个空格字符,需要移动后面O(n)个字符,因此对含有O(n)个空格字符的字符串而言总的时间复杂度是O(n^2),明显不可取。

思路:我们考虑从后往前进行替换,时间复杂度降为O(n)。

(1)首先遍历一遍字符串,找出字符串的长度以及其中的空格数

(2)根据原字符串的长度和空格数求出最后新的字符串的长度

(3)设置两个指针分别指向原字符串和新字符串的末尾位置

(4)如果原字符串的指针指向的内容不空,则将内容赋值给新指针指向的位置;否则从新指针开始向前赋值“02%”

(5)直到两个指针相等时表明字符串中的所有空格已经替换完毕

C++代码:

#include "stdafx.h"   
#include <iostream>   
using namespace std;  
   
//将字符串str中的空格替换为"%20"   
void ReplaceBlank(char *str)  
{  
   int nOldLength = strlen(str);//计算字符串的长度   
   
   //遍历字符串,求出其中空格的个数   
   int nCountOfBlank = 0;  
   char *p = str;  
   while (*p != '\0')  
   {  
       if (*p == ' ')  
       {  
           ++nCountOfBlank;  
       }  
       ++p;  
   }  
   
   int nNewLength = nOldLength + nCountOfBlank * 2;//新字符串的长度   
   int nOldIndex = nOldLength - 1;  
   int nNewIndex = nNewLength - 1;  
      
   while(nOldIndex != nNewIndex)  
   {  
       if (str[nOldIndex] != ' ')  
       {  
           str[nNewIndex--] = str[nOldIndex];  
       }  
       else 
       {  
           str[nNewIndex--] = '0';  
           str[nNewIndex--] = '2';  
           str[nNewIndex--] = '%';  
       }  
       --nOldIndex;  
   }     
}  
   
int _tmain(int argc, _TCHAR* argv[])  
{  
    char str1[50] = "We are happy.";  
    ReplaceBlank(str1);  
    cout << str1 << endl;  
   
    char str2[50] = "   We are happy.    ";  
    ReplaceBlank(str2);  
    cout << str2 << endl;  
   
    char str3[50] = "";  
    ReplaceBlank(str3);  
    cout << str3 << endl;  
   
    char str4[50] = "    ";  
    ReplaceBlank(str4);  
    cout << str4 << endl;  
   
    system("pause");  
    return 0;  
}  
#include "stdafx.h"
#include <iostream>
using namespace std;
 
//将字符串str中的空格替换为"%20"
void ReplaceBlank(char *str)
{
   int nOldLength = strlen(str);//计算字符串的长度
 
   //遍历字符串,求出其中空格的个数
   int nCountOfBlank = 0;
   char *p = str;
   while (*p != '\0')
   {
       if (*p == ' ')
       {
           ++nCountOfBlank;
       }
       ++p;
   }
 
   int nNewLength = nOldLength + nCountOfBlank * 2;//新字符串的长度
   int nOldIndex = nOldLength - 1;
   int nNewIndex = nNewLength - 1;
    
   while(nOldIndex != nNewIndex)
   {
       if (str[nOldIndex] != ' ')
       {
           str[nNewIndex--] = str[nOldIndex];
       }
       else
       {
           str[nNewIndex--] = '0';
           str[nNewIndex--] = '2';
           str[nNewIndex--] = '%';
       }
       --nOldIndex;
   }   
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    char str1[50] = "We are happy.";
    ReplaceBlank(str1);
    cout << str1 << endl;
 
    char str2[50] = "   We are happy.    ";
    ReplaceBlank(str2);
    cout << str2 << endl;
 
    char str3[50] = "";
    ReplaceBlank(str3);
    cout << str3 << endl;
 
    char str4[50] = "    ";
    ReplaceBlank(str4);
    cout << str4 << endl;
 
    system("pause");
    return 0;
}

二、清除空格

请事先一个函数,把字符串中的每个空格清除。例如输入“We are happy.",则输出”Wearehappy."

分析:较为简单,直接从头到尾进行清除。

(1)设置两个指针p1和p2初始状态都指向字符串的首字符

(2)若p2指向的元素不空,则将p2指向的内容赋给p1,然后都指向下一个元素;否则为空格,则p2指向下一元素。

(3)直到p2指向字符串末尾“\0”时清除空格结束。

C++代码:

#include "stdafx.h"   
#include <iostream>   
using namespace std;  
   
//清除字符串str中的空格,从前往后遍历   
void DeleteBlank(char *str)  
{  
    if (str == NULL)  
    {  
        return;  
    }  
   
    char *p1 = str;  
    char *p2 = str;  
   
    while (*p1 != '\0')//注意此处应该是p1,不是p2,因为'\0'仍然需要赋给p1   
    {  
       if (*p2 != ' ')  
       {  
           *(p1++) = *(p2++);  
       }  
       else 
       {  
           p2++;  
       }  
    }     
}  
   
int _tmain(int argc, _TCHAR* argv[])  
{  
    char str1[50] = "We are happy.";  
    DeleteBlank(str1);  
    cout << str1 << endl;  
   
    char str2[50] = "   We are happy.    ";  
    DeleteBlank(str2);  
    cout << str2 << endl;  
   
    char str3[50] = "";  
    DeleteBlank(str3);  
    cout << str3 << endl;  
   
    char str4[50] = "    ";  
    DeleteBlank(str4);  
    cout << str4 << endl;  
   
    system("pause");  
    return 0;  
}  
#include "stdafx.h"
#include <iostream>
using namespace std;
 
//清除字符串str中的空格,从前往后遍历
void DeleteBlank(char *str)
{
    if (str == NULL)
    {
        return;
    }
 
    char *p1 = str;
    char *p2 = str;
 
    while (*p1 != '\0')//注意此处应该是p1,不是p2,因为'\0'仍然需要赋给p1
    {
       if (*p2 != ' ')
       {
           *(p1++) = *(p2++);
       }
       else
       {
           p2++;
       }
    }   
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    char str1[50] = "We are happy.";
    DeleteBlank(str1);
    cout << str1 << endl;
 
    char str2[50] = "   We are happy.    ";
    DeleteBlank(str2);
    cout << str2 << endl;
 
    char str3[50] = "";
    DeleteBlank(str3);
    cout << str3 << endl;
 
    char str4[50] = "    ";
    DeleteBlank(str4);
    cout << str4 << endl;
 
    system("pause");
    return 0;
}

三、清除多余空格

给定字符串,删除开始和结尾处的空格,并将中间的多个连续的空格合并成一个。例如输入“    We     are       happy.  ”,则输出“We are happy.”

分析:同样是从前往后遍历,但需要定义一个bool变量标记是否保存一个空格。初始化时被设置为fasle,这样开始阶段的空格都不会被保存,当碰到一个非空格字符时,保存该字符,然后将标记设置为true,表示会保存字符串中的第一个空格。经过上述几步操作,可以保证字符串结尾要么是空字符,要么是非空格字符。如果是空格字符,则将其设置为"\0",如果不为空格字符,则在其后面加上"\0"。

C++代码:

#include "stdafx.h"   
#include <iostream>   
using namespace std;  
   
//清除字符串str中多余的空格,从前往后遍历   
void DeleteRedundantBlank(char *str)  
{  
    if (str == NULL)  
    {  
        return;  
    }  
   
    char *p1 = str;  
    char *p2 = str;  
    bool keepBlank = false;//记录空格是否保存      
   
    while (*p1 != '\0')//注意此处应该是p1,不是p2,因为'\0'仍然需要赋给p1   
    {         
        if (*p2 != ' ')  
        {  
            *(p1++) = *(p2++);  
            keepBlank = true;  
        }  
        else 
        {  
            if (keepBlank)  
            {  
               *(p1++) = *(p2++);  
               keepBlank = false;  
            }  
            else 
            {  
               p2++;  
            }             
        }         
    }  
   
    int nlen = strlen(str);  
    if (str[nlen - 1] == ' ')  
    {  
        str[nlen - 1] = '\0';  
    }  
    nlen = strlen(str);  
}  
   
int _tmain(int argc, _TCHAR* argv[])  
{  
    char str1[50] = "We are happy.";  
    DeleteRedundantBlank(str1);  
    cout << str1 << endl;  
    cout << strlen(str1) << endl;  
   
    char str2[50] = "   We    are    happy.    ";  
    DeleteRedundantBlank(str2);  
    cout << str2 << endl;  
    cout << strlen(str2) << endl;  
   
    char str3[50] = "";  
    DeleteRedundantBlank(str3);  
    cout << str3 << endl;  
   
    char str4[50] = "    ";  
    DeleteRedundantBlank(str4);  
    cout << str4 << endl;  
   
    system("pause");  
    return 0;  
}  
#include "stdafx.h"
#include <iostream>
using namespace std;
 
//清除字符串str中多余的空格,从前往后遍历
void DeleteRedundantBlank(char *str)
{
    if (str == NULL)
    {
        return;
    }
 
    char *p1 = str;
    char *p2 = str;
    bool keepBlank = false;//记录空格是否保存   
 
    while (*p1 != '\0')//注意此处应该是p1,不是p2,因为'\0'仍然需要赋给p1
    {       
        if (*p2 != ' ')
        {
            *(p1++) = *(p2++);
            keepBlank = true;
        }
        else
        {
            if (keepBlank)
            {
               *(p1++) = *(p2++);
               keepBlank = false;
            }
            else
            {
               p2++;
            }           
        }       
    }
 
    int nlen = strlen(str);
    if (str[nlen - 1] == ' ')
    {
        str[nlen - 1] = '\0';
    }
    nlen = strlen(str);
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    char str1[50] = "We are happy.";
    DeleteRedundantBlank(str1);
    cout << str1 << endl;
    cout << strlen(str1) << endl;
 
    char str2[50] = "   We    are    happy.    ";
    DeleteRedundantBlank(str2);
    cout << str2 << endl;
    cout << strlen(str2) << endl;
 
    char str3[50] = "";
    DeleteRedundantBlank(str3);
    cout << str3 << endl;
 
    char str4[50] = "    ";
    DeleteRedundantBlank(str4);
    cout << str4 << endl;
 
    system("pause");
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值