编写一个 c++ 程序,用于查找字符串中使用的元音数

Write a c++ program that finds the number of vowels used in an string

本文关键字:字符串 查找 用于 程序 c++ 一个      更新时间:2023-10-16

编写一个 c++ 程序来查找字符串中使用的元音数。

对于上述问题,我编写了一个程序如下:

int main()
{   
char x[10];
int n,i,s=0;
cout<<"Enter any stringn";
cin>>x;
n=strlen(x);
for(i=0;i<n;++i)
{
if(x[i]=='a'||x[i]=='e'||x[i]=='i'||x[i]=='o'||x[i]=='u')
{
s=s+1;
}
}
cout<<s;
return 0;
}

程序的输出为:

输入任意字符串
大象
3

在"大象"中,有三个地方使用元音,但使用的元音总数是2(e和a)而不是3

我要求改进程序,以便它计算元音总数并打印总数。(例如,如果是大象,它必须给 2)

创建另一个具有 5 个索引的 array(),例如

vowels[5] = array(0,0,0,0,0);

然后做如果否则,用每个元音,并添加

if(x[i] == 'a') vowels[0] =1;
elseIf(x[i] == 'e') vowels[1] =1;

等,然后检查元音数组是否设置为 1 或 0,并且只计数,这些是 5。

int count=0;
foreach vowels as item {
if(item == 1) count++
}
return count;

最简单的解决方案是插入您看到的每个元音 到std::set中,size并在您 做。

看在上帝的份上,使用表查找来确定是否 某物是元音(并将逻辑放在单独的函数中, 因此,当您需要处理"有时是y"时,您可以更正它 部分)。

或者,不使用标准算法:

int charCount[UCHAR_MAX + 1];
//  and for each character:
++ charCount[static_cast<unsigned char>( ch )];

(当然,如果你使用C++,你会读到字符 进入一个std::string,并迭代它,而不是 几乎可以保证缓冲区溢出。

然后,只需查看表中的每个元音,并计数 那些具有非零计数的:

int results = 0;
std::string vowels( "aeiou" );  //  Handling the sometimes "y" is left as an exercise for the reader.
for ( auto current = vowels.begin(); current != vowels.end(); ++ current ) {
if ( charCount[static_cast<unsigned char>( *current )] != 0 ) {
++ results;
}
}

当然,这些天真地实施的都无法处理 大写和小写正确(其中"E"和"e"相同 元音);使用tolower( static_cast<unsigned char>( ch ) )意志 解决这个问题。

编辑:

由于其他人正在提出解决方案(仅部分 正确):

bool
isVowel( unsigned char ch )
{
static std::set<int> const vowels{ 'a', 'e', 'i', 'o', 'u' };
return vowels.find( tolower( ch ) ) != vowels.end();
}
int
main()
{
std::string text;
std::cout << "Enter any word:";
std::cin >> text;
std::set<unsigned char> vowelsPresent;
for ( unsigned char ch: text ) {
if ( isVowel( ch ) ) {
vowelsPresent.insert( tolower( ch ) );
}
}
std::cout << vowelsPresent.size() << std::endl;
}

将元音的定义分离为单独的函数是 在编写良好的代码中实际上是必不可少的,而且在 至少,您需要掩盖差异以防万一。 (此代码还 关于"y"问题的双关语,这将使isVowel几个 难度要高出几个数量级。 它还忽略字符 在基本字符集之外,因此"naïve"将报告两个 不同的元音。

集合已经消除了重复项,因此与其在遇到元音时计算元音,不如将它们添加到集合中。然后,在最后,通过查询集合的大小来计算 [非重复] 元音的数量。

#include <set>
#include <string>
#include <iostream>
int main()
{   
std::string x;
int n = 0;
std::set<char> vowels;
std::cout << "Enter any stringn";
std::cin >> x;
n = x.size();
for (int i = 0; i < n; ++i)
if (x[i] == 'a' || x[i] == 'e' || x[i] == 'i' || x[i] == 'o' || x[i] == 'u')
vowels.insert(x[i]);
std::cout << vowels.size() <<'n';
}

现场演示

g++-4.8 -std=c++11 -O2 -Wall -pedantic -pthread main.cpp && echo "elephant" | ./a.out
输入任意字符串
2

请注意,我还用std::string交换了您对固定大小数组的使用,这样当有人碰巧输入超过 9 个字符时,您就不会面临危险情况的风险。

我发现解决此问题的一种非常简单的方法是使用map <char, int>. 这将允许您进行配对,由char索引,即。元音,并将整数计数器连接到它们。

#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
map <char, int> vowels;
int n,i,s=0;
string x;
cout<<"Enter any stringn";
cin>>x;
for(i=0;i< x.length();++i)
{
if(x[i]=='a'||x[i]=='e'||x[i]=='i'||x[i]=='o'||x[i]=='u')
{
vowels[x[i]]++;
}
}
for (map<char,int>::const_iterator print = vowels.begin(); print != vowels.end(); ++print){
cout << print -> first << " " << print -> second << endl;
}
return 0;
}

对于字符串elephant我们将得到以下输出:

a 1
e 2

通过说vowels[x[i]]++;我们将找到的元音添加到我们的地图中,如果它还没有被添加,并将其配对int增加一。 因此,当我们找到第一个e时,它将向地图添加e并将其计数器增加 1。 然后它将继续,直到找到下一个e并看到它已经索引了该索引,因此它只需将计数器增加到 2。 这样,我们将避免重复的问题。 当然,如果你想得到一个位数,我们可以打印出我们地图的大小:

cout << vowels.size() << endl;

好的。轮到我了。为了处理大写和小写,我们转换为下限:

std::string x("Elephant");
std::transform(x.begin(), x.end(), x.begin(), std::function<int(char)>(std::tolower));

现在删除重复项:

std::sort(x.begin(), x.end());
std::unique(x.begin(), x.end());

现在数元音。我希望在语言环境中有一些特定的东西,但唉......没关系,我们可以创建自己的。有点复杂,但不过分:

struct vowel : public std::ctype<char>
{
static const mask* make_table()
{
static std::vector<mask> v(classic_table(), classic_table() + table_size);
v['a'] |= upper;
v['e'] |= upper;
// etc.
return &v[0];
}
vowel(std::size_t refs = 0) : ctype(make_table(), false, refs){}
};

虽然我确信您可以创建自己的,但无法完全弄清楚如何通过 cpp首选项的文档进行,所以我说小写元音是大写的。通过前面对 std::to lower 的调用,这应该是安全的。

有了这个,我们可以轻松地使用它,例如:

int i = std::count_if(x.begin(), x.end(), [](const char c)
{ 
return std::isupper(c, std::locale(std::locale(""), new vowel)); 
});
std::cout << "Number of vowels:" << i << std::endl;

然而,我对这两个std::locale彼此并不特别满意。

我能想到的最简单的解决方案是代表每个元音以及它们是否已被计算的布尔数组。

bool vowelCounted[5] = { false };

现在,当你数元音时:

if (x[i]=='a' && !vowelCounted[0]) {
vowelCounted[0] = true;
s += 1;
} else if (x[i]=='e' && !vowelCounted[1]) {
vowelCounted[1] = true;
s += 1;
} 

只需对所有 5 个元音重复此结构。

可读性可以通过使用enum而不是索引的01234来提高可读性...但是您使用的是名为x[]s的变量,所以可能没问题......

如果您使用其中一个标准容器(vectorlist)将元音添加到其中,请执行与现在相同的检查,如果存在,则将其删除。当你完成得到剩余元素的数量时,你的答案将是元音的原始计数减去剩余元素。

试试这个

for( string text; getline( cin, text ) && text != "q"; )
{
set< char > vowels;
copy_if( begin(text), end(text), inserter( vowels, begin(vowels) ), 
[]( char c ) { return std::char_traits< char >::find( "aeiou", 5, c ) != nullptr; } );
cout << "the string [" << text << "] contains " << vowels.size() << " vowels" << endl;
}

您需要包含字符串,iostream,set,算法和迭代器。 你想用上面的"AEIOU"做什么?

你可以创建这个:

std::vector< char> vowels;

并将您在遍历字符串时遇到的所有元音放入其中:

if(x[i]=='a'||x[i]=='e'||x[i]=='i'||x[i]=='o'||x[i]=='u')
vowels.push_back( x[i]);

然后,您可以对此进行排序并消除重复项:

std::sort( vowels.begin(), vowels.end());
std::vector< char> vowels_unique( vowels.size());
std::vector< char>::iterator it;
it = std::unique_copy( vowels.begin(), vowels.end(), vowels_unique.begin());
vowels_unique.resize( std::distance( vowels_unique.begin(), it));

更好的是,使用 set 属性 - 它包含唯一的数据,如下所示:

std::set< char> unique_vowels;
if(x[i]=='a'||x[i]=='e'||x[i]=='i'||x[i]=='o'||x[i]=='u')
unique_vowels.insert( x[i]);
//...
int unique = unique_vowels.size();

C++ 代码片段:

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

int main()
{
char s[100];
int cnt;
cnt=0;
cin>>s;
for(int i=0;s[i];i++)
{
char c =s[i];
if(s[i]=='A' || s[i] =='E' || s[i]=='I' ||s[i]=='O'|| s[i]=='U')   cnt++;
else if(s[i]=='a' || s[i] =='e' || s[i]=='i'||s[i]=='o' || s[i]=='u')  cnt++;
}
cout<<cnt<<endl;
return 0;
}

使用std::find()std::transform()的版本:

#include <string>
#include <iostream>
#include <algorithm>
using std::string;
using std::cout;
using std::cin;
using std::getline;
using std::transform;
int main()
{
cout << " Type sentence: ";
string sentence;
getline(cin, sentence);
transform(sentence.begin(), sentence.end(), sentence.begin(), toupper);
string vowels = "AEIOU";
size_t vowCount = 0;
for (int i = 0; i < vowels.length(); ++i)
{
if (sentence.find(vowels[i], 0) != string::npos)
{
++vowCount;
}
}
cout << "There is " << vowCount << " vowels in the sentence.n";
return 0;
}

优点

  • std::find()只搜索给定元音的第一次出现,因此没有对给定字符串的其余部分进行迭代
  • 使用std优化算法

缺点

  • std::transform()转换每个小写字母,而不考虑其"元音">
#include<iostream>   //std::cout
#include<string>     //std::string
#include<cctype>     //tolower()
#include<algorithm>  //std::for_each
using namespace std;
int main()
{
string s;
getline(cin, s);
int count = 0;
for_each(s.begin(), s.end(), [&count](char & c) //use of lambda func
{
c = tolower(c); //you can count upper and lower vowels
switch (c)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
count++;
break;
}
});
cout << count << endl;
return 0;
}
#include<iostream>
using namespace std;
int main()
{
char vowels[5] = {'a','e','i','o','u'};
char x[8] = {'e','l','e','p','h','a','n','t'};
int counts[5] = {0,0,0,0,0};
int i,j;
for(i=0;i<8;i=i+1)
{
for(j=0;j<5;j=j+1)
{
if(x[i]==vowels[j])
{
counts[j] = counts[j] + 1;
}
}
}
for(i=0;i<5;i=i+1)
{
cout<<counts[i]<<endl;
}
return 0;
}

由于我使用的是"大象"的例子,所以我只是初始化了它。

如果仍然可以进行任何修改,请对其进行编辑并使其更加用户友好。