为满足条件的特定 int 搜索向量的有效方法?

Posted

技术标签:

【中文标题】为满足条件的特定 int 搜索向量的有效方法?【英文标题】:Efficient methods of searching vectors for specific int's that meet a condition? 【发布时间】:2017-01-16 12:30:25 【问题描述】:

我正在尝试编写一个有效的操作来搜索向量,具体确定三个 int 的存在(A1、A2、A3),​​其中 A1 > A2 && A2

所以给定 A 5,3,1,2,3,输出的运算:[3,1,2], [3,2,3],[5,1,3], [5, 1,2]

显而易见的方法是使用三个嵌套循环:

int my_function()

  std::vector<int> A 3,5,3,1,2,3;
  for(auto IT1 = A.begin(); IT != A.end(); IT1++)
  
    for(auto IT2 = IT1 + 1; IT2 != A.end(); IT2++)
    
      for(auto IT3 = IT2 + 1; IT3 != A.end(); IT3++)
      
        if(*IT1 > *IT2 && *IT3 > *IT2)
        
          //Do stuff
        
      
    
  

显然这是非常低效的,是否有任何已知的方法可以在单个循环中执行诸如此类的操作?还是比三个嵌套循环更有效?

【问题讨论】:

您可以将*IT1 &gt; *IT2 移出IT3 循环。 A2 &gt; A2?你沃特? 您想要任何、全部还是第一个有效的三元组? @Jarod42 所有有效的三元组 在这种情况下,你会遇到 O(NNN), 【参考方案1】:

如果你想找到所有这样的三元组,没有什么是渐近更快的,因为这样的三元组的数量可以达到O(N^3)

UP:不过,如果你能以某种方式保证没有那么多这样的三元组(假设你有T = o(N^3)),你可以编写一个更有效的算法。

让我们遍历数组的所有元素并尝试将当前元素放在三元组的中间。为此,我们需要维护两组有序的值:当前值左侧的所有值之一,以及右侧的第二个值。代码如下:

// Initialization
std::multiset<int> left;                      // empty set
std::multiset<int> right(A.begin(), A.end()); // set of all elements in A
// Iterations
for (int x : A) 
    right.erase(x);
    for (auto l = left.rbegin(); l != left.rend() && *l > x; ++l) 
        for (auto r = right.rbegin(); r != right.rend() && *r > x; ++r) 
            // Do stuff with triplet *l, x, *r.
        
    
    left.insert(x);

这种解决方案的复杂度是O(T + NlogN),如果T 很小,它比O(N^3) 小很多。缺点是三元组的处理顺序不同。

【讨论】:

嗨,O(N^3) 是什么意思? @LorenceHernandez 这是时间复杂度的大写法,见bigocheatsheet.com @LorenceHernandez 表示程序执行的操作数与 N^3 成正比。也就是说,如果 N 翻倍,则程序运行时间通常会乘以 8。通常,根据特定的程序和硬件,对于 N 高达数百到数千的这种渐近是可以的。严格定义见en.wikipedia.org/wiki/Big_O_notation

以上是关于为满足条件的特定 int 搜索向量的有效方法?的主要内容,如果未能解决你的问题,请参考以下文章

映射列满足特定条件的字典中的值

仅当满足特定条件时,JQuery 才会自动完成

Python:解决找到满足特定条件的组合的问题

JavaScript常用数组元素搜索或过滤的四种方法

JavaScript常用数组元素搜索或过滤的四种方法

JavaScript常用数组元素搜索或过滤的四种方法