簡體   English   中英

計算字符串中的元音數量

[英]Count no of vowels in a string

我編寫了一個程序來計算字符串中的元音個數,但它不是有效的或優化的代碼。 此外,它不會檢查大寫元音。

#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;
}

考慮到您假設只有aeiou是元音並且您的字符串都是小寫字母,請嘗試以下操作:當然,這在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);
  1. 不要針對strlen(name)測試。 在循環外計算一次長度。
  2. 使用整數數組將字符映射為增量(0或1)。
  3. 忽略點1和2。

不要優化等待一個人輸入姓名然后在該姓名上循環的代碼。 您的效率極低的算法會花費大約99.999%的時間來等待用戶輸入。

  • 主要是清理。 干凈的代碼->更少的錯誤
  • 使用標准算法(查找,count_if)
  • 使用std :: string
  • 檢查錯誤
  • 使用最新的標題

實時觀看:http://ideone.com/E6QJy

根據受歡迎的需求進行編輯 :也許我也應該以適當的樣式(?)顯示大小寫轉換:)鏈接顯示以下輸入的輸出

krk#!@#^&*
AEIOUÄËÏÖÜÁÉÍÓÚÀÈÌÒÙÂÊÎÔÛðتº
aeiouäëïöüáéíóúàèìòùâêîôûã°øªº

作為記錄, 這是我們擁有的

static inline bool isvowel(char ch)
{
        static const std::string vowels("aeiouEAIOU");
        return vowels.end() != std::find(vowels.begin(), vowels.end(), ch);
}

我的新設備更具企業精神,它也支持您的自定義字符類型! 看哪:

#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;
}

現在,如果任何人都可以共享權威代碼來根據特定的語言環境來獲取元音的集合,那就更加麻煩了

只是重要的部分:

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++;
  }

查找表可能會更快:

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 該字母為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'];

對於短字符串,這可能會變慢,因為必須為您測試的每個字符串清除charcounts數組。 但是,它有機會獲得大量數據。

對於這樣的事情,我有兩個泛型函數,您可以將它們用於任何目的(甚至是商業用途),而第三個泛函是適合您的需求的(盡管未經測試):

const bool IsChar(const char Target, const char Source, const bool CaseInsensitive = false)
{
    if(Target == Source){ return true; }
    if(CaseInsensitive)
    {
        if( (Source >= 'A') && (Source <= 'Z') )
        {
            if( (Source+32) == Target ){ return true; }
        }

        if( (Source >= 'a') && (Source <= 'z') )
        {
            if( (Source-32) == Target ){ return true; }
        }
    }
    return false;
}

const bool IsCompareChar(const char C, const char CompareChars[], const bool CaseInsensitive = false)
{
    while((*CompareChars))
    {
        if(IsChar(C,*CompareChars,CaseInsensitive)){ return true; }
        CompareChars++;
    }
    return false;
}

const unsigned int CountVowels(const char Array[], const unsigned int Length)
{
    unsigned int N = 0, NumberOfVowels = 0;
    while(N < Length)
    {
        if(IsCompareChar(Array[N],"aioue",true))
        {
            NumberOfVowels++;
        }
    }
    return NumberOfVowels;
}

但是,鑒於您正在做的事情是要教給您編碼的知識,所以我建議,您可以編寫自己的版本,而不是復制和粘貼給定的代碼,因為針對角色的特定功能要比通用功能更優化。

總的來說,您只能通過以下方式調用它:

CountVowels(Array,strlen(Array);

CountVowels僅返回計數。 盡管可以修改函數本身以計算任何字符,但大寫和小寫等均如此。

也許是這樣嗎?

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;
     }


   } 
}

首先,建議使用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
}

希望對您有幫助:D

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM