我写了一段代码,可以从c++中删除字符串中的所有元音,但由于某种原因,它没有删除一个特定输入的元音'o'
:zjuotps
。
代码如下:
#include<iostream>
#include<string>
using namespace std;
int main(){
string s;
cin >> s;
string a = "aeiouyAEIOUY";
for (int i = 0; i < s.length(); i++){
for(int j = 0; j < a.length(); j++){
if(s[i] == a[j]){
s.erase(s.begin() + i);
}
}
}
cout << s;
return 0;
}
当我输入:zjuotps
我得到的输出是:zjotps
4条答案
按热度按时间jmp7cifd1#
这是一种使用C++标准库的更简洁的方法:
编辑:
正如@RemyLebeau指出的,可以使用c++20中引入的
std::erase_if
,答案变成了一行代码:pxq42qpu2#
您可以通过将匹配字符添加到新的
string
对象来开发解决方案。如果input
对象中的字符与remove
对象中的字符不匹配,则eliminate()
方法将字符写入result
对象。7hiiyaii3#
在这里的代码中,为了可读性,我将
s
替换为input_str
,将a
替换为vowels
:上述代码的问题在于,每次删除输入字符串中的字符时,都应该跳出元音
j
循环,并在输入字符串中 * 相同的i
位置 * 重新开始,再次检查j
循环中的所有元音。这是因为擦除一个字符会左移所有位于右侧的字符,这意味着同一个i
位置现在将包含一个新的字符进行检查,因为它只是从一个位置左移到该位置。错误地允许i
递增意味着您跳过该新字符以检查相同的i
位置,从而在字符串中留下第二个元音(例如,如果两个元音在一行中)。下面是对问题中的直接代码的修复:但是,还有许多其他更好的方法可以做到这一点。我会在下面介绍一些。我个人认为this most-upvoted code difficult to read。它需要额外的研究和查找的东西做这么简单的事情。所以,我将展示一些替代方法来回答这个问题。
方法1:复制非元音字符到新字符串:
所以,这里有一个替代的,简单的,更可读的方法,你只需扫描输入字符串中的所有字符,检查字符是否在元音字符串中,如果不是,你将其复制到输出字符串,因为它不是元音:
只是算法:
完整的可运行示例:
输出:
方法2:删除输入字符串中的元音字符:
或者,您可以像最初尝试的那样就地删除元音字符。但是,如果字符被擦除,你不能增加输入字符串的索引
i
,因为擦除元音字符会左移字符串中剩余的字符,这意味着我们需要在下一次迭代中再次检查 * 相同的 * 索引位置,以便读取下一个字符。请参阅下面评论中的注解。只是算法:
完整的可运行示例:
输出:
方法三:高速C型阵列:就地修改输入字符串
我借用了我之前回答的“方法1”的方法:在C中删除数组元素
如果你曾经处于需要高速的情况下,我敢打赌这可能是最快的方法之一。它使用C风格的字符串(char数组)。它扫描输入字符串,检测任何元音。如果它看到一个不是元音的char,它会将它复制到输入字符串的最左边,从而就地修改字符串,过滤掉所有元音。完成后,它将在新位置中空终止输入字符串。如果你最后需要一个C++
std::string
类型,我在完成后从C字符串创建一个。只是算法:
完整的可运行示例:
输出:
另请参阅:
1.[C语言中类似的答案]从数组中删除元素
js5cn81o4#
试试这个简单的方法
我可以看到这有点混乱,裸着我。空值用于终止字符串。对于常规的C风格字符串,空值意味着“结束”,但C字符串是类std::string的示例,该类是C标准库的一部分。Std::string可以包含空字符。
所以std::string可以在其中包含嵌入的空字符,但C- string不能这样做,因为它在第一个空字符处结束。