提问者:小点点

为什么代码没有从输入字符串中删除“u”?


我正在学习C++。 今天我写了一段代码,用来删除字符串中的元音。 它在某些测试中运行良好。 但是这个测试无法从字符串中删除“u”。 我的输入是:tour。 输出为:tur。 但我希望得到类似trtour的输出

代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
    string word;
    getline(cin, word);
    transform(word.begin(), word.end(), word.begin(), ::tolower);  // Converting uppercase to lowercase
    for (int i = 0; i < word.length(); i++)
    {
        if (word[i] == 'a' || word[i] == 'e' || word[i] == 'i' || word[i] == 'o' || word[i] == 'u')
        {
            word.erase(word.begin() + i);  // Removing specific character
        }
    }
    cout << word << endl;

    return 0;
}

我怎么能那么做? 代码中的问题在哪里?


共3个答案

匿名用户

删除字符时,索引i仍在递增,这意味着您将跳过对出现在元音后面的字符的检查。

擦除字符时,需要减少i:

if (word[i] == 'a' || word[i] == 'e' || word[i] == 'i' || word[i] == 'o' || word[i] == 'u')
{
    word.erase(word.begin() + i);  // Removing specific character
    --i;  // make sure to check the next character
}

这是一个演示。

另外,请避免以下2行:

#include <bits/stdc++.h>
using namespace std;

它们是危险的,不应使用。

匿名用户

erase之后,执行i++。 这意味着检查会绕过一个元素。

for循环更改为

for (int i = 0; i < word.length(); )
{
    if (word[i] == 'a' || word[i] == 'e' || word[i] == 'i' || word[i] == 'o' || word[i] == 'u')
    {
        word.erase(word.begin() + i);  // Removing specific character
    } 
    else 
    {
        i++; // increment when no erasion is performed
    }
}

匿名用户

以下是你可以更容易地做到这一点的方法:

#include <algorithm>
#include <array>
#include <cctype>
#include <iostream>
#include <string>

constexpr auto isVowel(unsigned char const ch) noexcept {
  constexpr std::array<unsigned char, 10> vowels{
      'a', 'e', 'i', 'o', 'u',
  };
  return std::find(vowels.begin(), vowels.end(), std::tolower(ch)) !=
         vowels.end();
}

int main() {
  std::string str = "Tour";
  str.erase(std::remove_if(str.begin(), str.end(), isVowel), str.end());
  std::cout << str << '\n';
}