我在逻辑上颠倒字符串中的元音有什么问题?

问题描述 投票:0回答:2

我尝试用leetcode解决problem这要求程序员反转给定字符串中的元音。当我用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;
   }
 };

出于某种原因,当输入的是“新订单开始时,罗马时代就孕育了罗文娜。”在pc 0x000000405efb的地址0x7ffd4a543ab0上有一条错误消息AddressSanitizer:stack-buffer-overflow。当我尝试调试时,我发现,第一个while循环变得无限。但是,当我将字符串结果替换为char result [len]时,我的代码运行正常。

我的方法有什么问题?谢谢hago

c++ string algorithm reverse
2个回答
1
投票

您不能将下标运算符用于空字符串来更改其值。因此,您的程序具有未定义的行为。

请注意,在任何情况下,您都不会颠倒字符串中的元音。您正在尝试使用给定字符串的元音反向创建新字符串。但这不是同一回事。

我可以建议以下解决方案。:)

#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'未包含在元音组中。


0
投票

您的解决方案是正确的,但有一个简单的错误。

声明string result;时,此变量的大小为0。因此,每当您尝试将字符放置在某个位置(即result [0],result [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--;
}
© www.soinside.com 2019 - 2024. All rights reserved.