【问题标题】:C++ check if item is in a array [duplicate]C ++检查项目是否在数组中[重复]
【发布时间】:2014-02-17 13:30:56
【问题描述】:

在 c++ 中,我有一个数组,我正在尝试检查数组中是否存在某个元素。这是我的数组:

string choices[3] = {"a", "b", "c"}

如果用户输入存在于数组中,我希望它打印出 true,因此如果用户输入“b”,那么它将打印 true 并给我数组索引。这就像 in 或 find 的 Python 版本。我知道我可以使用 for 循环遍历所有元素,但是有没有更有效的方法?谢谢。

【问题讨论】:

  • 看看std::find
  • 没有什么比循环更有效的了(除非对数组进行排序或以其他方式构建以帮助搜索);但是有像std::find 这样的算法可能比循环更简洁。
  • 我不认为你想要一个字符串数组。因为你得到了数组的所有缺点而没有任何优点,因为字符串仍然需要复制和运行时构造。要么使用 const char 指针数组来获得效率,要么使用字符串向量来获得安全和便利。

标签: c++ memory-efficient


【解决方案1】:

要查找索引,您可以使用以下代码:

int x = std::distance(choices, std::find(choices, choices + 3, "b"));

这里,distancefind 方法可以在 <algorithm> 标头中找到。

【讨论】:

  • 由于类型不匹配,此示例的模板参数推导将失败。您需要使用choices + 0 而不是choices
  • 我更喜欢std::begin(choices)std::end(choices)。注意如果x等于choices的大小,choices不包含"b"
【解决方案2】:

您可以使用标头<algorithm> 中声明的标准算法std::find 它解决了两个任务。它可以判断一个字符串是否存在于容器中,它可以提供第一个找到的元素的索引。

如果您只需要确定一个字符串是否存在于容器中,您可以使用标准算法std::any_of

这两种算法都具有线性复杂度。

如果容器(例如数组)是有序的,那么您可以使用标准算法std::binary_search 来确定容器中是否存在字符串。

一个演示标准算法std::find用法的例子

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

int main()
{
   std::string choices[] = { "a", "b", "c" };

   std::cout << "Enter a string: ";

   std::string s;
   std::cin >> s;

   auto it = std::find( std::begin( choices ), std::end( choices ), s );

   bool in_array = it != std::end( choices );

   std::cout << "String "\" << s << "\" is present in the array = " 
             << std::boolalpha << in_array << std::endl;
   if ( in_array ) 
   {
      std::cout << "It is " << std::distance( std::begin( choices ), it ) 
                << " element in the array" << std::endl;
   }
}

如果您需要更复杂的条件来搜索容器中的元素,您可以使用标准算法 std::find_if,它接受谓词作为参数。

【讨论】:

    【解决方案3】:

    std::find 如果找到,则返回指向数组中元素的迭代器,否则返回结束迭代器:

    auto const last = std::end(choices);
    auto const pos = std::find(std::begin(choices), end, "b");
    if (last != pos) {
        // Use pos here.
    }
    

    如果你不需要对元素做任何事情,那么你可以使用any_of:

    if (std::any_of(std::begin(choices), std::end(choices),
                    [](std::string const& s) { return "b" == s; })
    {
        // "b" is in the array.
    }
    

    这两个函数都只是内部循环,它们不会比手写循环快。如果您的数组已排序,那么您可以使用std::lower_bound 而不是std::findstd::binary_search 而不是std::any_of

    【讨论】:

      【解决方案4】:

      除非以某种方式订购物品,否则没有更有效的方法。考虑到您要查找的元素理论上可​​以位于任何索引处,包括您要检查的最后一个索引。

      如果您想有效地找到它,请使用std::set。然后您可以使用set::count(item) &gt; 0 来确定@​​987654323@ 是否在集合中。

      此外,在 python 中,当您测试一个项目是在列表item in [itemA, itemB, itemC] 还是在元组item in (itemA, itemB, itemC) 中时,它有效地对所有元素进行循环。只有当你使用python的setfrozenset时,这个搜索才会非常快。

      如果您不想自己编写 O(n) 循环,我建议使用函数 std::find,如果您想要更快的查找,建议使用 std::set 类。

      【讨论】:

        猜你喜欢
        • 2012-03-31
        • 1970-01-01
        • 2017-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-09
        相关资源
        最近更新 更多