Я пытался решить проблему в 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 на ПК 0x000000405efb. Когда я попытался отладить, я обнаружил, что первый цикл while становится бесконечным. Но когда я заменяю строковый результат на char result [len], мой код работает нормально.

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

0
hago 11 Фев 2020 в 19:25

2 ответа

Лучший ответ

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

Когда вы объявляете 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() для добавления символа single в строку. Это общая сложность 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
Faruk Hossain 11 Фев 2020 в 17:35

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

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

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

#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' не входит в набор гласных.

1
Vlad from Moscow 11 Фев 2020 в 17:07