在c ++中搜索集合的最有效方法是什么

时间:2013-12-04 23:40:37

标签: c++

例如,遍历一个字符串并计算我可以使用的元音数量

  for (int i=0; (x=inputString[i])!='\0';i++)
    if (x=='a' || x=='e' || x=='i' || x=='o' || x=='u') numVowels++;

在像haskell或erlang这样的函数式语言中我们可以做列表:member(x,“aeiou”)

在某些面向对象的语言中,我可以做一些像[“a”,“e”,“i”,“o”,“u”]。find(x)

在没有x == .. ||的情况下,用C ++执行此操作的最简洁方法是什么x == .. || ...

6 个答案:

答案 0 :(得分:3)

或者

for (auto c: inputString)
{
    c = std::tolower(c);
    if ((c == 'a') || ... (c == 'u'))
    {
        ++numVowels;
    }
}

仅仅因为一种语言允许你在一行中写它并不意味着它更快。

如果你真的,真的想摆脱你可以做的==

#include <stdint.h>

//                    a  b  c  d  e  ....
const uint8_t TABLE[] = { 1, 0, 0, 0, 1, ... };

for (uint8_t c : inputString)
{
   if (std::isalpha(c))
   {
       numVowels += TABLE[std::tolower(c) - 'a'];
   }
}

答案 1 :(得分:3)

inputString.find_first_of("aeiou");

这将为您提供任何匹配元素的第一个索引。您可以在循环中执行此操作以获取所有匹配元素:

size_t idx=0;
do{
    size_t current = inputString.find_first_of("aeiou",idx);
    idx = current;
}
while(current!=string::npos);

答案 2 :(得分:2)

我会用这个:

#include <algorithm>

auto const numVowels = std::count_if(inputString.begin(), inputString.end(),
                       [](char c) { return c == 'a' || /* ... */ || c == 'u'; })

答案 3 :(得分:2)

据我所知,这是“最好”的方式。为了使其更清晰,您可以编写一个仅执行该比较的宏或函数,即bool CheckForVowel(char in)或类似的东西。然后,您可以使用该功能:if(CheckForVowel(x)){...}

答案 4 :(得分:1)

在C ++中,您可以使用std::find()()

std::count_if(str.begin(), str.end(), [](char c) {
        static std::string const vowels("aeiou");
        return vowels.end() != std::find(vowels.begin(), vowels.end(), c);
    });

可悲的是,算法的表示法不支持范围[尚]。如果确实如此,那么该操作可以写得更好一些

ranges::count_if(str, [](char c){ return !ranges::find("aeiou"r, c).empty(); });

其中r是一个合适的用户定义文字,用于生成字符序列范围。

答案 5 :(得分:1)

标题(“最有效”)似乎与问题不匹配(“最干净”)。

鉴于["a","e","i","o","u"].find(x)计为“干净”,我认为最接近的C ++等价物是std::string("aeiou").find(x) != -1

我也要清理循环。如果你坚持输入一个以空字符结尾的字符串,那么:

static const std::string lower_vowels("aeiou");
char x;
while ((x = *inputString++)) {
    numVowels += (lower_vowels.find(x) != -1);
}

如果您将输入更改为std::string,则:

for (char x : inputString) {
    numVowels += (lower_vowels.find(x) != -1);
}

可能不是最有效的,但这是另一个故事。你所拥有的可能非常接近最优。我怀疑你会在没有一些相当难看的代码的情况下击败它,因为你基本上说的是“在优化这些与积分常数的5次比较时,我能比编译器做得更好吗?”