【问题标题】:char array c++ vowelschar 数组 C++ 元音
【发布时间】:2019-11-14 17:55:06
【问题描述】:

我正在尝试制作一个将使用 switch 语句并查看 char 数组的元素是否是元音以及哪个元素的程序,但我被困在如何检查元素上:

int prob2() {
char uName[25] = "";
int voCo = 0;
cout<<"Enter you first and last name, under 25 chars please: ";
cin>>uName;
int i = 0;
while(i <= 25){
switch(i){
    case 1:

    voCo++;
    break;
    case 2:

    voCo++;
    break;
    case 3:

    voCo++;
    break;
    case 4:

    voCo++;
    break;
    case 5:

    voCo++;
    break;
    default:

    break;
}
i++;
}
cout<<"Your first and last name have: "<<voCo<<" vowels in them."<<endl;
return 0;
}

【问题讨论】:

    标签: c++ arrays char switch-statement c-strings


    【解决方案1】:

    你的意思好像是下面这个

    #include <iostream>
    #include <cctype>
    
    using namespace std;
    
    //...
    
    size_t prob2() 
    {
        const size_t N = 25;
        char uName[N] = "";
    
        size_t voCo = 0;
    
        cout<<"Enter you first and last name, under " << N << " chars please: ";
        cin.getline( uName, N );
    
        for ( char *p = uName; *p != '\0'; ++p ) *p = toupper( ( unsigned char )*p );
    
        for ( const char *p = uName; *p != '\0'; ++p )
        {
            switch( *p )
            {
            case 'A':
                voCo++;
                break;
            case 'E':
                voCo++;
                break;
            case 'I':
                voCo++;
                break;
            case 'O':
                voCo++;
                break;
            case 'U':
                voCo++;
                break;
            default:
                break;
            }
        }
    
        cout<<"Your first and last name have: "<<voCo<<" vowels in them."<<endl;
    
        return voCo;
    }
    

    【讨论】:

    • @ChefGladiator 根据他对任务的描述,这是初学者所需要的。:) 重读他的问题。
    • 您可以使用case 的直通功能将所有这些叠加到一个++ 操作中。
    • @tadman 是的,但我试图按原样保留原始代码。
    【解决方案2】:

    你可以试试这样的:

    const std::string vowels = "aeiou";
    
    const std::string name = "martin luther king, jr.";
    const unsigned int name_length = name.length();
    unsigned int vowel_count = 0U;
    for (unsigned int i = 0U; i < name_length; ++i)
    {
      if (vowels.find(name[i]) != std::string::npos)
      {
        ++vowel_count;
      }
    }
    

    不需要switch 声明。这是许多可能的算法或实现之一。

    编辑 1:计数数组
    您还可以使用计数数组:

    unsigned int counts[26] = {0};
    for (unsigned int i = 0U; i < name_length; ++i)
    {
        const c = std::tolower(name[i]);
        if (isalpha(c))
        {
            counts[c - 'a']++;
        }
    }
    const unsigned int vowel count =
        counts['a'] + counts['e'] + counts['i']
      + counts['o'] + counts['u'];
    

    【讨论】:

    • 可能也需要小写操作,因为'A' 也是 alpha。
    • 在编辑 1 中添加了小写转换。
    【解决方案3】:

    首先,将用户交互与解决您的需求的逻辑分离。我认为我们可以放心地假设您可以在这种情况下收集输入并将其保存到字符串中。所以我们不会为此浪费时间。

    我们将专注于开发和测试解决需求的代码。在标准 C++ 中。现在这里是游泳池的深处。代码。

    // mike.h
    #pragma once
    
    // std::string view requires C++17
    #include <string_view>
    
    // always use namespace,to avoid name clashes
    namespace mike {
    
        // make 'sv' the string_view literal available
        using namespace std::string_view_literals;
    
        // declare and define compile time
        // string view literal
        // 'constexpr' guarantees compile time
        // notice the use of 'sv'
        constexpr auto vowels = "eaiouEAIOU"sv;
    
        // compile time function to count literals 
        // again 'constexpr' guarantees compile time
        // inline gurantees we can include this header many times
        // without making accidental duplicates of `count_vowels`
        // 'in_' argument has 'std::string_view' passed by value
        // pass by value is preferred standard C++ method
        // of functions arguments passing
        //  'std::string_view' is standard C++ preferred type
        // to pass strings into functions
        inline constexpr size_t
            count_vowels(std::string_view in_) 
        {
            // return type is size_t
            // we can count very large number of vowels
            // but all at compile time
            size_t rezult{}; 
            // this is C+17 'range for'
            // we cast implicitly references to input elements
            // from, `char const &` to `int const &`
            // cost of that is very likely 0
            for (int const & ch_ : in_)
                for (int const & v_ : vowels)
                    // there is no if() here
                    // we simply add 0's or 1's, to the rezult
                    // false is 0, true is 1
                    // the correct by the book way of coding that is
                    // static cast from bool to int
                    // rezult +=  static_cast<int>( v_ == ch_ ) ;
                    rezult += v_ == ch_  ;
            return rezult;
        }
    
        // runtime speed of this call is 0 (zero)
        // all happens at compile time
        // notice how we pass normal string literal
        // no need to create string_view
        constexpr size_t r1 
            = count_vowels("abra ca dabra");
    
        // no runtime tests necessary
        // `static_assert()` is compile time assert
        // failure message is optional
        static_assert(r1 == 5, 
            "compile time calculation failed, 'abra ca dabra', must contain 5 vowels");
    } // mike ns
    

    希望有很多 cmets。解决方案不使用switch() 语句或if() 语句。得益于标准的 C++ 结构,现代优化编译器编译时代码非常简单、有弹性并且可能非常快。

    解决方案在编译时也有效。这不会阻止您在运行时场景中使用它。虽然,我会再次建议使用本机 char 数组。 std::string 在这里可能是完美的匹配。

    std::string input_ = collect_user_input() ;
    int rezult = count_vowels(input_);
    

    享受标准的 C++ ...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-15
      • 1970-01-01
      • 2020-12-03
      • 2012-10-05
      • 2021-01-26
      相关资源
      最近更新 更多