C++ 计算字符串中的元音数
我写了一个程序来计算一个字符串中的元音数,但这不是有效的或优化的代码。 此外,它不会检查大写元音C++ 计算字符串中的元音数,c++,algorithm,C++,Algorithm,我写了一个程序来计算一个字符串中的元音数,但这不是有效的或优化的代码。 此外,它不会检查大写元音 #include<iostream.h> using namespace std; int main() { unsigned int vow_cnt=0; char name[15]= "sijith aeu"; cout<<"Enter a name"<<endl; cin>>name; for(unsigned int i=0;i<strl
#include<iostream.h>
using namespace std;
int main()
{
unsigned int vow_cnt=0;
char name[15]= "sijith aeu";
cout<<"Enter a name"<<endl;
cin>>name;
for(unsigned int i=0;i<strlen(name);i++)
{
if(name[i] == 'a' || name[i] == 'e'||name[i] == 'i'||name[i] == 'o'||name[i] == 'u')
{
vow_cnt++;
}
}
cout<<"vow_cnt"<< vow_cnt << endl;
}
#包括
使用名称空间std;
int main()
{
无符号整数vow_cnt=0;
字符名称[15]=“sijith aeu”;
库特
不要对strlen(name)
进行测试。在循环外计算一次长度
char isvowel[UCHAR_MAX+1] = { 0 }; // or int instead of char, try both
isvowel['a'] = 1;
isvowel['e'] = 1;
isvowel['i'] = 1;
isvowel['o'] = 1;
isvowel['u'] = 1;
isvowel['A'] = 1;
isvowel['E'] = 1;
isvowel['I'] = 1;
isvowel['O'] = 1;
isvowel['U'] = 1;
...
if (isvowel[(unsigned)name[i]]) vow_cnt++;
您还可以尝试让编译器通过使用开关来决定如何进行优化:
switch(name[i]) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
case 'A':
case 'E':
case 'I':
case 'O':
case 'U':
++vow_cnt;
default:
}
再说一次,要么两者都慢。你必须用更真实的数据来测试它,因为“优化”一个只处理一个短字符串的程序是非常徒劳的。无论你做什么,它都是即时的,所以不要浪费你自己的时间。只有当你处理大量数据时,性能才重要,不管是一个大字符串还是很多字符串
ASCII有一个技巧,name[i]
是一个特定的字母(任意一种情况),当且仅当name[i]| 0x20
是该字母(小写)。您可以使用它将大小写标签的数量减半或(小心)查找表的大小减半。这可能会影响性能,也可能不会影响性能
如果您想尝试一种完全不同的方法,看看它是如何执行的,您可以将复杂的逻辑和分支从循环中分离出来:
size_t charcounts[UCHAR_MAX+1] = { 0 };
char *p = name;
while (*p) {
++charcounts[(unsigned)*p];
++p;
}
vow_cnt = charcounts['a'] + charcounts['e'] + ... + charcounts['U'];
对于短字符串,这可能会较慢,因为必须为您测试的每个字符串清除
字符数数组。不过,它有可能会产生大量数据。重要的部分是:
const char *p = name;
while(*p)
switch(*p++)
{
case 'a': case 'e': case 'i': case 'o': case 'u':
case 'A': case 'E': case 'I': case 'O': case 'U':
vow_cnt++;
}
考虑到您的假设,即只有一个EIO u是元音,并且字符串都是小写的,请尝试以下方法:
当然,在unicode中,或者对于每种有不同元音集的语言来说,这将是一个可怕的失败
bool is_vowel(char x) {
// order by probability of occurrence in the target language
// e.g. start with e for English
// nb see comments for further details
return (x == 'e' || ...);
}
std::string foo;
long nbVowels = std::count_if(foo.begin(), foo.end(), is_vowel);
- 主要是清理升级。清理代码->减少bug
- 使用标准算法(查找、计数)
- 使用std::string
- 检查错误
- 使用最新的标题
按流行需求编辑:也许我也应该以适当的样式(?)显示案例转换:)
该链接显示以下输入的输出
krk#!@#^&*
AEIOUÄËÏÖÜÁÉÍÓÚÀÈÌÒÙÂÊÎÔÛðتº
aeiouäëïöüáéíóúàèìòùâêîôûã°øªº
记录在案:
我的新发明更具进取心,它也支持你的自定义角色类型!看:
#include <iostream> // avoid old style MSVC++ header!
#include <algorithm>
#include <iterator>
#include <locale>
#include <string>
template <typename T=char>
struct isvowel
{
bool operator()(T ch) const
{
static std::basic_string<T> vowels("aeiouäëïöüáéíóúàèìòùâêîôûã°øªº"); // etc. for specific languages...
static int _init = 0;
while (!_init++) // not thread safe :)
{
vowels.reserve(vowels.size()*2);
// upper case dynamically based on locale, e.g. AEIOUÄËÏÖÜÁÉÍÓÚÀÈÌÒÙÂÊÎÔÛðتº
std::transform(vowels.begin(), vowels.end(), std::back_inserter(vowels), (int(*)(int)) std::toupper);
}
return vowels.end() != std::find(vowels.begin(), vowels.end(), ch);
}
};
int main()
{
std::setlocale(LC_ALL, "German"); // set relevant locale for case conversions
std::cout << "Enter a name: ";
std::string name;
while (std::cin >> name) // handle errors?
{
size_t vow_cnt = std::count_if(name.begin(), name.end(), isvowel<char>());
std::cout << "vow_cnt: " << vow_cnt << std::endl;
}
return 0;
}
#包括//避免旧式MSVC++头!
#包括根据特定区域设置获取的代码…它将是偶数.Woot。对于类似的内容,我有两个通用函数,您可以将其用于任何用途(甚至是商业用途),第三个是适合您需要的函数(未经测试):
count元音只返回计数。虽然函数本身可以修改为计数任何字符,包括大写和小写等。可能是这样吗
string vowels = "aeiou"
string query = "dsdlfjsdofkpdsofkdsfdfsoedede" ;
int countVowels =0;
for(int i =0 ; i < query.length() ; i++)
{
int j=0;
while(j < vowels.length())
{
if(query[i] == vowels[j++])
{
countVowels++,break;
}
}
}
string元音=“aeiou”
string query=“dsdlfjsdofkpdsofkdsfdfsoede”;
int count元音=0;
for(int i=0;i
首先,一些答案建议使用std::string,我没有。它比使用常规的char[]数组结构慢得多。为了更有效地计算元音,您可以使用字母频率计数,如下所示:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 100; // Or whatever you want it to be.
char x[ MAXN ];
int freq[ 26 + 1 ];
char vowels[ ] = "aeiouy" // Or whatever you want it to be too :D
void fillFrequency() {
for( int i = 0; i <= 26; i ++ ) {
freq[ i ] = 0;
}
int len = strlen( x );
for( int i = 0; i < len; i ++ ) {
freq[ x[ i ] - 'a' ] ++;
}
}
int main() {
cin >> x;
fillFrequency();
int nVowels = strlen( vowels );
int ans = 0;
for( int i = 0; i < nVowels; i ++ ) {
ans += freq[ vowels[ i ] - 'a' ];
}
cout << ans << '\n';
return 0; // That's it! :D
}
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
const int MAXN=100;//或任何您想要的值。
char x[MAXN];
国际频率[26+1];
char元音[]=“aeiouy”//或任何你想要的:D
无效填充频率(){
对于(int i=0;i>x;
填充频率();
int nVowels=strlen(元音);
int ans=0;
for(int i=0;i CUT你证明它是慢的吗?为什么你要优化它?<代码> <代码>应该是<代码> <代码>。也可以考虑使用<代码> STD::String 。@日高看起来不像C。IoString、命名空间、CUT、CIN…@哈罗德Car(15)代替STD::String,Strunor,换句话说,我对回答人们的问题感兴趣,并显示他们的C或C++或两者,无论他们想知道什么。我并不十分关心我的答案是否会在他们的作业作业中给他们评分。所以如果他们说C++,我认为扔高功率C++是很好的。但是,这看起来很像家庭作业,任务可能是人工的(算法复杂性与C++入门课程结合),根据实现,编译器可以优化多个调用到<代码> STLLN(Name)< /C>(gcc是这样做的,strlen
函数被标记为纯函数,在这种特殊情况下,编译器可以证明对strlen(name)
的多次调用的结果都将返回相同的值,从而对注入的临时函数执行一次预先调用,然后仅使用该值)--这是另一个先测量和分析然后关心优化的原因。无论如何,这是一个合理的建议:无论何时,只要知道结果不会改变,就避免调用。看看编译器可以为自己提升strlenstrlen
。name
和vow\u cnt
都是自动变量,这会很有趣ce不可能是别名,因此优化器不难看出它是一个有效的优化。比我的答案更全面,尽管没有完整的“元音肯定不是你想象的那样。”触摸:)@是的。我没有错过它。我选择了不解决它。如果我知道一个地区设施来分类元音,我会使用it@pmr:好吧,我屈服了。你说得对。让代码更有趣
CountVowels(Array,strlen(Array);
string vowels = "aeiou"
string query = "dsdlfjsdofkpdsofkdsfdfsoedede" ;
int countVowels =0;
for(int i =0 ; i < query.length() ; i++)
{
int j=0;
while(j < vowels.length())
{
if(query[i] == vowels[j++])
{
countVowels++,break;
}
}
}
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 100; // Or whatever you want it to be.
char x[ MAXN ];
int freq[ 26 + 1 ];
char vowels[ ] = "aeiouy" // Or whatever you want it to be too :D
void fillFrequency() {
for( int i = 0; i <= 26; i ++ ) {
freq[ i ] = 0;
}
int len = strlen( x );
for( int i = 0; i < len; i ++ ) {
freq[ x[ i ] - 'a' ] ++;
}
}
int main() {
cin >> x;
fillFrequency();
int nVowels = strlen( vowels );
int ans = 0;
for( int i = 0; i < nVowels; i ++ ) {
ans += freq[ vowels[ i ] - 'a' ];
}
cout << ans << '\n';
return 0; // That's it! :D
}