【问题标题】:Easier way for multiple if-else tests多个 if-else 测试的更简单方法
【发布时间】:2019-10-08 13:15:48
【问题描述】:

我有一个字符串,如果字符串值与给定的一组单词匹配,我想执行if 语句(比如猿、吃、睡眠、芒果......)

我能做到:-

if(name=="ape" || name=="eat".............)

有没有更简单的方法可以做到这一点?

我只想使用 if-else。

【问题讨论】:

  • 你有多少字?您希望匹配区分大小写吗?
  • 我有 10 个字,是的,我需要区分大小写。

标签: c++ algorithm c++11 if-statement


【解决方案1】:

声明一个单词数组,然后使用标准算法std::findstd::any_of

例如

const char * words[] =
{
    "ape", "eat", "sleep", "mango"
}; 

if ( std::find( std::begin( words ), std::end( words ), name ) != std::end( words ) )
{
   //...
}

如果您要声明一个排序数组,那么您可以使用标准算法std::binary_search

这是一个演示程序

#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>

int main() 
{
    const char * words[] =
    {
        "eat", "ape", "mango", "sleep" 
    };

    std::string name( "mango" );

    if ( std::binary_search( std::begin( words ), std::end( words ), name ) )
    {
        std::cout << name << " is a correct name\n";
    }

    return 0;
}

它的输出是

mango is a correct name

或者将单词放在标准容器中,例如std::set,然后使用容器的查找方法。

【讨论】:

  • 这需要线性时间搜索。请改用std::unordered_set
  • @MohammadZeineldeen - 对于有限且小的值集合,任何集合实现的开销都将超过线性搜索的成本。
  • @MohammadZeineldeen 整个数组适合缓存行,二进制搜索是对数时间。
  • 他的问题看起来很笼统,因为他说“给定一组单词”
【解决方案2】:

如果您只想将其保留为 ifelse 而不添加任何内容,则没有。

否则,您可以使用std::unordered_set,用这些词填写并使用find()

【讨论】:

    【解决方案3】:
    for(auto pattern: {"ape", "eat"}) {
       if(name == pattern) {
          // all the consequences here
          break;
       }
    }
    

    或者,在热路径上,您可以使用哈希集之类的东西:

    static const std::unordered_set<std::string> words{"ape", "eat"};
    if(words.find(name) != words.end()) {
    }
    

    只要确保它是static const,就不会每次都重新初始化它。如果您有一组真正的大量模式可供允许,那可能会更好。

    【讨论】:

    • 您也可以使用if(words.count(name)) 来节省一些输入。
    【解决方案4】:

    您可以使用 unordered_set 字符串并搜索名称。 像这样的:

     #include <iostream>
     #include <unordered_set>
     #include <string>
     #include <algorithm>
    
     int main()
     {
         std::unordered_set<std::string> values = { "ape", "stuff", "dude" };
    
    
         std::string name = "ape";
    
         if (std::find(std::begin(values), std::end(values), name) != std::end(values)) {
             std::cout << "found it";
         } else {
             std::cout << "no found it";
         }
    
         return 0;
     }
    

    感谢 Sombrero Chicken 提到 unordered_set。我默认为矢量。 可能有一些带有 constexpr unordered_set 的 C++17/C++20 版本。但我把这个留给别人。

    【讨论】:

    • 没有constexpr unordered_set。所有容器,减去std::array,都使用分配器,这意味着在 constexpr 上下文中不允许使用新的分配器。
    • @NathanOliver AFAIK 有提议允许 constexpr 容器。虽然目前不可用,但对于 C++ 版本是可能的。
    【解决方案5】:

    如果您不关心性能但想要最少的代码,请构建一个 std::string,其中包含由不同分隔符分隔的所有单词,包括开头和结尾。然后std::string::find()你的搜索词也包裹在分隔符中:

    static const std::string words("^ape^stuff^dude^");
    if (words.find("^"+name+"^") != words.npos)
        std::cout << "found it";
    

    或者放弃 const std::string 并使用 clib 中的 strstr

    【讨论】:

      猜你喜欢
      • 2013-09-10
      • 1970-01-01
      • 1970-01-01
      • 2013-06-26
      • 2012-03-31
      • 1970-01-01
      • 2016-07-11
      • 2018-12-13
      • 2021-03-07
      相关资源
      最近更新 更多