反转由空格分隔的字符串元素将返回比原始字符串更大的字符串

Reversing elements of a string delimited by spaces returns a larger string than the original

本文关键字:字符串 返回 原始 元素 空格 分隔      更新时间:2023-10-16

在CodeWars 的 C++ 中玩得开心,试图反转字符串中单词的字母,即由空格分隔的单词。"你好,我的朋友" --> "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

有什么想法吗?

您最终可能会在字符串中使用不可打印的"字符",因为您正在尝试访问字符串的末尾。

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

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

我相信你最终也会在字符串的末尾添加一个空格,再添加一个额外的字符。

有一种更简单的方法来实现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;
}

现场演示