【问题标题】:Check if a vector member is found between two matching elements检查是否在两个匹配元素之间找到向量成员
【发布时间】:2014-12-26 23:51:37
【问题描述】:

所以,我有一个奇怪的问题。我有一个校验和向量,本质上是按时间排序的,我正在寻找两个匹配校验和之间的任何校验和。换句话说,如果我们有:

std::vector < std::string > checksums = {"foo","bar","baz","foo"};

我希望它按顺序报告 FALSE、TRUE、TRUE、FALSE。

鉴于每个校验和都需要与每个 /other/ 校验和进行检查,我该如何有效地执行此操作?用于识别重复元素的哈希表示例 here 可能是难题的一部分,但它的作用与我正在寻找的相反。

【问题讨论】:

  • 用于此的简单算法将具有二次复杂度。你觉得这太过分了吗?
  • 使用哈希表查找重复元素,并将向量索引作为表中的值。然后,当您检测到重复项时,您可以将TRUE 放入结果中,以获取两者之间的所有索引。
  • @Barmar 听起来可行;我怀疑哈希表会是答案,但我在很大程度上(可悲地)对它们一无所知。你能举个例子吗?
  • 为什么第二个输出元素为 TRUE?似乎“bar”不在介于“foo”和“baz”之间?
  • 呃。这不是关于它是否在“foo”和“baz”之间。这是真的,因为它在两个“foo”总和之间。

标签: c++ vector


【解决方案1】:

我将概述一个基本方法:

std::map<std::string, size_t> position;

for (size_t i=0; i<checksums.size(); ++i)
{
     std::map<std::string, int>::iterator prev=position.find(checksums[i]);

     if (prev == position.end())
     {
         position.insert(std::make_pair(checksums[i], i));
     }
     else
     {
         size_t j=prev->first;
         positions.erase(prev);

         // Everything between index #j and index #i
     }
}

我还没有测试这是否可以编译,如果没有,那是某个地方的小错字。

您没有指定如何处理模棱两可的情况。即 {"foo", "bar", "baz", "foo", "foobar", "foo"} 的列表——无论您是在寻找第一个和第二个 foo 之前的条目,还是第一个和第三个 foo。当然,我提出的解决方案是假设前者,但为后者调整它不会太难。

此外,还可以对算法进行一些进一步的改进。例如,可以将查找/比较/插入操作组合成一个操作。如何做到这一点,将是你的家庭作业。提示:查看 std::map::insert() 的返回值。

编辑:这仅查找匹配范围。本质上,将结果转换为假/真值向量并不是很复杂。您可以将向量初始化为所有 false 值,当您找到匹配范围时,将 j 之后和 i 之前的每个元素设置为 true。

【讨论】:

  • FWIW 我会在 foo1 和 foo2 以及 foo3 和 foo4 之间寻找东西,但不是 foo2 和 foo3。我将在此基础上工作,看看它会把我带到哪里;作为一个起点,它肯定比我现有的混乱组合要好得多......不,只是混乱。
  • 考虑用无序地图替换地图,因为它通常更快。
  • 它也只是>=C++11,我平台的一个限制是C++11还是相当新的。但这是一个很好的建议,当 11 的使用更加集成时,我会进行调查 :)
  • 我发布的代码示例不需要任何更改即可找到 foo1-foo2 和 foo3-foo4。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多