【问题标题】:How to match the contents of two arrays in C++如何在 C++ 中匹配两个数组的内容
【发布时间】:2013-09-24 07:10:01
【问题描述】:

我有两个单独的单词数组,例如:

array1 = word1, word2, word3
array2 = word4, word5, word6

我正在尝试根据用户输入(将是 2 个单词)匹配两个数组。 例如,你输入“word1 word6”,程序给你 x。您输入“word3 word4”,程序会为您提供 y。每个数组中不需要/不应该匹配(因此输入“word1 word3”不应该给出错误以外的任何内容)。

现在,我正在考虑使用string::find 来查找输入字符串中每个数组的内容。然而,在那之后,我被困在如何获取这些结果(如果有的话)并将它们相互匹配。

例如,我会input.find(contents of array1),如果发现了什么,就取那个array1[x],并查看通过同一输入中的单独行找到的与array2[x] 的组合是否匹配第三个可能组合列表。如果是这样,我会根据它是哪个组合来拆分响应。

我知道如果我只有一个可能匹配的列表并在输入字符串中找到 that 会更容易。但我想将这两组单词分开,因为代码会更灵活(而且我会通过这种方式学到更多)。

希望有人能给我一些关于如何进行的提示吗?

【问题讨论】:

  • 当你说“例如,你输入“word1 word6”,程序给你x”时,我不明白'x'是什么意思。下一句同样的问题:)
  • 您的意思是 WORD 是无符号短字吗?
  • 抱歉,我的意思是一般结果 - 在这种情况下,我可能会根据用户输入的两个单词的集合来执行一些函数。
  • 一开始你写的是“数组”,然后你写的是创建一个临时的“列表”,最后你写的是“两组词”。请注意,这是 3 种不同类型的容器。
  • 我实际上对数组和向量之间的区别有点困惑。我所需要的只是单词的“列表”(字典定义,而不是 C++ 类型:P)。我会为此使用向量,但启发我进行此“练习”的朋友提到了数组,所以我认为它们也可以使用。真的很抱歉造成混乱,因为我说我是新手,所以我可能会毫无意义地使用 C++ 术语!

标签: c++ arrays string set containers


【解决方案1】:

C++ 对这类问题有一个特殊的结构,称为“映射”

typedef std::map< std::pair< std::string, std:: string >, int > MyMapType;
MyMapType my_map;

例如,上面是一个给定一对字符串的映射返回一个 int。当然,并非所有可能的字符串对都需要包含在映射中:

my_map[std::make_pair("A", "B")] = 42;
my_map[std::make_pair("A", "C")] = 99;
my_map[std::make_pair("B", "D")] = 103;

要查看是否存在特定对,您可以使用map::find

MyMapType::iterator i = my_map.find(std::make_pair(x, y));
if (i == my_map.end()) {
    std::cout << "Pair is not defined\n";
} else {
    // Pair is present
    std::cout << "Associated value is " << *i << "\n";
}

【讨论】:

  • +1 因为基于OP的附加cmets,这其实是他要找的
【解决方案2】:

最简单的选择不是使用std::set_intersection 来获取公共元素。不过,您确实需要排序的输入。

  int first[] = {5,10,15,20,25};
  int second[] = {50,40,30,20,10};

  it=std::set_intersection (first, first+5, second, second+5, v.begin());

将产生一个包含 20 个元素的向量:10 和 20。(根据链接)。

【讨论】:

    【解决方案3】:
    据我了解:
    • 你有 2 组词,
    • 来自用户的 2 句话和
    • 你想知道这两个词是否包含在这些集合中,但不是来自同一个集合

    那么你可能会这样做:

    inline const bool isIn(const std::set<std::word>& s, const std::string& e) {
        return s.find(e) != s.end();
    }
    
    ...
    
    std::set<std::string> wordSet1, wordSet2;
    std::string word1, word2; // <-- from the user
    ...
    if (isIn(wordSet1, word1) && isIn(wordSet2, word2)) {
        // success
    }
    else if (isIn(wordSet2, word1) && isIn(wordSet1, word2) {
        // success
    }
    else {
        // fail
    }
    

    但由于std::set::find 的复杂度为 O(log n) 并且这种方法调用了 4 次,所以它不是很有效。另请注意,如果顺序定义明确,即word1 必须来自wordSet1word2 必须来自wordSet2,则应省略第二个条件(else if)。

    如果订单定义明确并且您需要多次查找这些对,那么创建一个包含所有可能组合的临时std::set&lt; std::pair&lt;std::string, std::string&gt; &gt; 可能是更合理的方法,但既然您写道:“我知道如果我只有一个可能匹配的列表会更容易......但我想将两组单词分开“,这可能不是你想要的。

    我希望这会有所帮助。

    【讨论】:

      【解决方案4】:

      存储您喜欢的单词并将可搜索的组合放入布隆过滤器中。

      最一般形式的伪代码...:

      插入:

      for words in wordArray:
          bloomFilter.add( words.hash() )
      

      搜索:

      found = false
      if bloomFilter.contains( searchedForWords.hash() ):
          if originalWordList.contains( words )
              found = true
      

      关于布隆过滤器的一些注意事项:

      1. 查找内容非常快。
      2. 使用良好、快速的哈希函数。网上有很多
      3. 它会产生误报(X 在过滤器中,而实际上不在)
      4. 它不能生成假阴性(X 不在过滤器中)
      5. 当布隆过滤器说过滤器中有东西时,您必须查看原始源数据以确保它确实存在。

      我将此方法与一个应用程序防火墙一起使用,该防火墙旨在将色情和相关垃圾从网络中隔离开来,与存储在传统地图或哈希表中相比,它将特定代码加速了 400 多倍。

      【讨论】:

        猜你喜欢
        • 2019-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多