что не так в моих логи c реверсивных гласных в строке? - PullRequest
0 голосов
/ 11 февраля 2020

Я попытался решить проблему в коде leetcode, который просит программиста обратить вспять гласные в данной строке. Когда я написал свой код в C, он работал нормально и прошел все тестовые случаи. Я попытался написать тот же код на C ++, но для конкретного тестового примера это не удалось.

bool isVowel(char a)
{
    if(a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u')
        return true;
    if(a == 'A' || a == 'E' || a == 'I' || a == 'O' || a == 'U')
        return true;

    return false;
}

class Solution {
public:
    string reverseVowels(string s) {
        int i, j, k;
        int len = s.length();
        j = s.length() - 1;
        i = 0;
        k = 0;
        string result;
        //char result[len];
        if (j < 0)
            return s;
        while(j >= 0) {
            if (isVowel(s[j])) {
                result[k] = s[j];
                k++;
            }
            j--;
        }
    k = 0;
    j = s.length() - 1;

    while (i <= j) {
        if(isVowel(s[i])) {
            s[i] = result[k];
            k++;
        }
        i++;
    }
    return s;
   }
 };

По какой-то причине, когда вводится "Новый порядок начался, Ровена породила еще римский век". появляется сообщение об ошибке AddressSanitizer: переполнение буфера стека по адресу 0x7ffd4a543ab0 при p c 0x000000405efb. Когда я попытался отладить, я обнаружил, что первый раз, когда l oop становится бесконечным. Но когда я заменяю строковый результат на char char [len], мой код работает нормально.

Что не так в моем подходе? Спасибо, ха go

Ответы [ 2 ]

1 голос
/ 11 февраля 2020

Ваше решение правильное, но с простой ошибкой.

Когда вы объявляете string result;, тогда эта переменная объявляется с размером 0. Поэтому всякий раз, когда вы пытаетесь поместить символ в какую-то позицию (то есть, результат [0], результат [1], ...), он обнаруживает, что для этой переменной нет выделенной памяти. Таким образом, он выдает ошибку.

Вместо помещения символа в result, вы можете добавить символ к этой строке.

Таким образом, вы можете написать result = result + s[j];

Привязка кода должна выглядеть следующим образом -

string result = "";
//char result[len];
if (j < 0)
    return s;
while(j >= 0) {
    if (isVowel(s[j])) {
        result = result + s[j];
    }
    j--;
}

Но добавление символа в строку занимает больше времени выполнения.

Кроме того, вы также можете использовать string.push_back() для добавления одиночный символ в строку. Это сложность в целом O(n), n = length of the final string.

string result = "";
//char result[len];
if (j < 0)
    return s;
while(j >= 0) {
    if (isVowel(s[j])) {
        result.push_back(s[j]);
    }
    j--;
}
1 голос
/ 11 февраля 2020

Вы не можете использовать оператор индекса для пустой строки, чтобы изменить ее значение. Поэтому ваша программа имеет неопределенное поведение.

Обратите внимание, что в любом случае вы не меняете гласные в строке. Вы пытаетесь создать новую строку с обращенными гласными из данной строки. Но это не одно и то же.

Я могу предложить следующее решение .:)

#include <iostream>
#include <string>
#include <cstring>
#include <cctype>

class Solution final
{
private:
    static bool isVowel( char c )
    {
        const char *vowels = "AEIOU";

        return  std::strchr( vowels, std::toupper( static_cast<unsigned char>( c ) ) );
    }

public:
    static std::string & reverseVowels( std::string &s )
    {
        auto first = std::begin( s ), last = std::end( s );

        do
        {
            while ( first != last && !isVowel( *first ) ) ++first;

            if ( first != last )
            {
                while ( --last != first && !isVowel( *last ) );
            }

            if ( first != last ) std::iter_swap( first++, last ); 
        } while ( first != last );      

        return s;
    }
};


int main() 
{
    std::string s( "I am trying to write a program in C++" );

    std::cout << s << '\n';

    std::cout << Solution::reverseVowels( s ) << '\n';

    return 0;
} 

Вывод программы:

I am trying to write a program in C++
i am tryong ta wreti o prigram In C++

Обратите внимание, что письмо 'y' не включено в набор гласных.

...