【问题标题】:Reversing elements of a string delimited by spaces returns a larger string than the original反转由空格分隔的字符串的元素会返回比原始字符串更大的字符串
【发布时间】:2020-02-07 04:05:15
【问题描述】:

在 CodeWars 上尝试反转字符串中单词的字母(由空格分隔的单词,即单词),在 C++ 中获得乐趣。 "Hello my friend" --> "olleH ym dneirf",不会丢失多余的空格。

我的答案未通过测试,但是当我区分我的答案和建议的答案时,没有输出。我还尝试检查原始字符串和反转字符串的长度,它们的长度存在显着差异,具体取决于字符串。但是,当我比较输出时,它们的长度再次相同,并且没有尾随空格。

int main() {

    std::string s("The quick brown fox jumps over the lazy dog.");

    std::cout <<"Old: "<<s<<std::endl;
    std::cout <<"New: "<<reverse(s)<<std::endl;

    //lengths are not the same
    std::cout <<"Length of s: "<<s.length()<<std::endl;
    std::cout <<"Length of reverse(s): "<<reverse(s).length()<<std::endl;

    //check for trailing whitespace
    std::cout <<"Last 5 chars of reverse(s): "<<reverse(s).substr(reverse(s).length() - 6)<<std::endl;
}
std::string reverse(std::string str) {

    std::string word;
    std::string revWord;
    std::string result;
    char space(' ');

    int cursor = 0;
    for(int i = 0; i < str.length(); i++){
        std::string revWord;
        if (str[i] == space || i == str.length() - 1){
            if (i == str.length() - 1)
                i++;
            word = str.substr(cursor, i - cursor);
            for(int j = word.length(); j >= 0; j--){
                revWord.push_back(word[j]);
            }
            word = revWord;
            if(i != str.length() - 1)
                result.append(word + " ");
            cursor = i+1;
        }
    }

    return result;
}

控制台输出:

Old: The quick brown fox jumps over the lazy dog.
New: ehT kciuq nworb xof spmuj revo eht yzal .god 
Length of s: 44
Length of reverse(s): 54
Last 5 chars of reverse(s): .god

有什么想法吗?

【问题讨论】:

  • 您将单词之间的字符加倍。 Fwiw,您的计算中还包括终止符。该控制台输出 不是 我所看到的。我看到:New: ehT kciuq nworb xof spmuj revo eht yzal .god,并注意前导空格和单词之间的双空格。您不只是使用迭代器和std::reverse 仅限于每个单词的任何特殊原因?
  • 那些不是空格,而是\0。但是我的终端也将它们显示为空格。
  • 在我之前的评论中提到,something like this。有点骇人听闻。要做到这一点需要std::findstd::isspace,但你明白了。

标签: c++ string substring reverse


【解决方案1】:

由于您试图访问字符串的末尾,因此您的字符串中可能会出现无法打印的“字符”。

for(int j = word.length(); j >= 0; j--){
    revWord.push_back(word[j]);
}

这里你设置一个变量等于字长,然后这个变量用来读取字符串末尾的一个字节。此处存储的数据是一个 NUL 字节,因此std::string 可以用于生成匹配的 C 样式字符串,而无需复制其数据。

我相信你的字符串末尾也有一个空格,增加了一个额外的字符。

【讨论】:

  • 更具体地说,std::string 在末尾包含一个\0,因此它与 c 字符串兼容。在调试器中可以清楚地看到,在每个反转的单词之前都有一个\0
  • 是的,很好,它不仅仅是任何数据,而是字符串的空终止符。已更新。
【解决方案2】:

有一种更简单的方法来实现您的reverse() 函数,使用std::reverse() 算法来修改原始std::string 对象内联并且根本不使用任何额外的std::string 对象:

std::string reverse(std::string str)
{
    std::string::size_type word_start = 0, word_end;
    std::string::iterator iter = str.begin();

    do
    {
        word_end = str.find(' ', word_start);
        if (word_end == std::string::npos)
        {
            std::reverse(iter + word_start, str.end());
            break;
        }
        std::reverse(iter + word_start, iter + word_end);
        word_start = str.find_first_not_of(' ', word_end + 1);
    }
    while (word_start != std::string::npos);

    return str;
}

Live demo

【讨论】:

    猜你喜欢
    • 2020-02-08
    • 2010-10-19
    • 1970-01-01
    • 2018-12-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多