将字符串中的所有空格替换为 '%20' (C++)

Replacing all spaces in a string with '%20' (C++)

本文关键字:C++ 替换 字符串 空格      更新时间:2023-10-16

在理解部分代码时遇到一些麻烦;我得到的输出也是错误的。问题是将字符串中的所有空格替换为"%20"。完整代码如下所示;它可以编译,但不能完全按预期运行。

#include <iostream>
#include <string>
using namespace std;
void replaceSpaces(string str){
    //Getting the length of the string, counting the number of spaces 
    int strLen = str.length();
    int i, count = 0;
    for (i = 0; i <= strLen; i++) {
        if(str[i]==' ')
        count++;
    }
    //Determining the new length needed to allocate for replacement characters '%20'
    int newLength = strLen + count * 2;
    str[newLength] = '';
    for (i = strLen - 1; i >= 0; i--) {
        if (str[i] == ' ') {
            str[newLength - 1] = '0';
            str[newLength - 2] = '2';
            str[newLength - 3] = '%';
            newLength = newLength - 3;
        }
        else {
            str[newLength - 1] = str[i];
            newLength = newLength -1;
        }
    }
    cout << str <<endl;
}
int main() {
    string str = "hello jellybean hello";
    replaceSpaces(str);
    return 0;
}

我可能错过了一些明显的东西,但是当分配此行中的新字符串长度时:

int newLength = strLen + count * 2;

在这里,我们将空格数乘以 2,但是如果我们尝试用"%20"替换所有空格,为什么不将其乘以 3?


str[newLength] = '';

此行是否指示字符串中最后一个字符之后的位置被分配了一个空空格?


我也对else声明感到困惑。

 else {
        str[newLength - 1] = str[i];
        newLength = newLength -1;
    }

不确定我是否完全了解何时执行的情况。


编译和运行函数时,如果

string str = "hello jellybean hello";

预期的输出将是hello%20jellybean%

20hello,除了我得到的输出是hello%20jellybean%20h

就时间复杂度而言,由于存在两个独立的for循环,时间复杂度是否为O(n)

我知道我问了很多不同的问题,非常感谢任何答案!

这是

错误的:

str[newLength] = '';

std::string对象根据其大小在内部维护其 NUL 终止符。 你想要

str.resize(newLength);

相反。

int newLength = strLen + count * 2;

说分配空间(稍后),等于字符串的长度,加上找到的空格数乘以 2,这是有道理的。

例如:so glad to help ,应该使用空格所在的插槽进行%,并且每个插槽还需要两个插槽,用于将发挥作用的替换20部分。


这是错误的:

str[newLength] = '';

你看不见吗?您访问字符串边界之外的内存。你的行为就像你实际上分配了等于newLength的空间,但你还没有在代码中的任何位置。

越界访问会导致未定义的行为,这很糟糕。


else 语句仅用于复制非空格字符,但您应该已经放弃该代码(如果它不是您的代码)并从头开始或/并先睹为快:在C++中编码/解码 URL。


至于错误的结果,你应该通过达到那个答案的那个点来知道这是意料之中的。

尝试就地进行修改是很棘手的。创建新字符串要容易得多:

std::string new_string;
for (int i = 0; i < str.length(); ++i) {
    if (str[i] == ' ')
        new_string += "%20";
    else
        new_string += str[i];
}
return new_string;

或者,如果您喜欢范围:

std::string new_string;
for (char ch : str) {
    if (ch == ' ')
        new_string += "%20";
    else
        new_string += ch;
}
return new_string;

您可以将函数中的字符串参数更改为引用,然后就不需要任何新字符串,在代码的其他部分,您可以使用插入函数添加"2"和"0",您只需要将空格转换为"&"。

void replaceSpaces(string &str) {
        size_t strLen = str.length();
        for (int i = 0; i < strLen; i++) {
            if (str[i] == ' ') {
                str[i] = '%';
                str.insert(str.begin() + i + 1, '2');
                str.insert(str.begin() + i + 2, '0');
                strLen += 2;
            }
        }
    }

这很容易;在代码中将examplestring替换为字符串,并像以前一样使用:

#include <iostream> //debug output
#include <string>
using std::string;
using std::cout;
using std::endl;
//the string to convert
string examplestring = "this is the example string for spaces into %20";
int main()
{
    int countspaces = 0; //its faster to fill a known size
    for (auto &x : examplestring)if (x == ' ')countspaces++; //counts spaces
    string newstring; //declare new string
    newstring.resize(examplestring.size() + (countspaces*3)); //pre-set size to make it run faster
    int newstringiterator = 0; //keep track of new string location
    //if ' '(space), place %20 in newstring and add 3 to iteration
    //else just place the letter and iterate
    for (int i=0;i<examplestring.size();i++)
    {
        if (examplestring[i] == ' ') 
        { 
            newstring.insert(newstringiterator, "%20");
            newstringiterator += 3;
        }
        else newstring[newstringiterator++] = examplestring[i];
    }
  //final newstring is the original with %20 instead of spaces. 
  cout << newstring << endl;
  system("PAUSE"); //to read console output
  return 0; //return to zero
}

这将输出 newstring ,这是带有"%20"而不是空格的旧字符串。