Сторнирование элементов строки, разделенной пробелами, возвращает строку большего размера, чем оригинал - PullRequest
1 голос
/ 09 октября 2019

Весело в C ++ на CodeWars, пытаясь обратить буквы слов в строке, слова, разделенные пробелами, т.е. «Здравствуйте, мой друг» -> «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

Есть идеи?

Ответы [ 2 ]

2 голосов
/ 09 октября 2019

Скорее всего, в вашей строке появятся непечатаемые «символы», так как вы пытаетесь получить доступ с конца строки.

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

Здесь вы устанавливаете переменную равнойдлина слова, а затем эта переменная используется, чтобы прочитать один байт после конца строки. Данные, хранящиеся здесь, представляют собой байт NUL, который существует для того, чтобы std::string можно было использовать для создания соответствующей строки в стиле C без копирования ее данных.

Я полагаю, что вы также заканчиваетес пробелом в конце вашей строки, добавив еще один дополнительный символ.

1 голос
/ 09 октября 2019

Существует гораздо более простой способ реализации функции 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;
}

Живая демоверсия

...