【问题标题】:find the most similar value between two vectors in C++在 C++ 中找到两个向量之间最相似的值
【发布时间】:2018-10-05 21:17:26
【问题描述】:

我有两个已排序的向量,我想找到向量1 中与向量2 中另一个值的差异(距离)最小的值的索引。但是,我的以下代码可以完成这项工作,因为我使用的向量总是排序的,我觉得大多数情况下还有另一种更有效的方法来做同样的事情。任何指南?提前致谢。

#include<iostream>
#include<cmath>
#include<vector>
#include<limits>
std::vector<float> v1{2,3,6,7,9};
std::vector<float> v2{4,6.2,10};
int main(int argc, const char * argv[]) 
{    
    float mn=std::numeric_limits<float>::infinity();
    float difference;
    int index;
    for(int i=0; i<v1.size(); i++){
        for(int j=0; j<v2.size(); j++){
            difference = abs(v1[i]-v2[j]);
            if(difference < mn){
                mn= difference;
                index = i;
            }
        }
    }
    std::cout<< index; 
    // 2 is the wanted index because |6-6.2| is the smallest distance between the 2 vectors 
    return 0;
}

【问题讨论】:

    标签: c++ algorithm performance


    【解决方案1】:

    确实,有一种更快的方法。您只需将 v1 中的元素与 v2 中较小或相等的元素或第一个较大的元素进行比较。基本上,这个想法是有两个迭代器ij,如果v2[j] &lt; v1[i] 则推进j,否则推进i。这是一个可能的实现:

    for (int i = 0, j = 0; i < v1.size(); i++) {
        while (true) {
            difference = std::abs(v1[i] - v2[j]);
            if (difference < mn) {
                mn = difference;
                index = i;
            }
    
            // Try the next item in v1 if the current item in v2 is bigger.
            if (v2[j] > v1[i])
                  break;
    
            // Otherwise, try the next item in v2, unless we are at the last item.
            if (j + 1 < v2.size())
                    j++;
            else
                    break;
        }
    }
    

    虽然它仍然看起来像一个双循环,但它最多只计算 v1.size() + v2.size() 次的差异,而不是 v1.size() * v2.size() 次。

    【讨论】:

    • 带有if (v2[j] &gt; v1[i]) i++; else j++; 的单个循环(更类似于您对基本思想的描述,带有一些代码来满足数组的末端)会更容易理解 IMO。
    • 不是这么简单的,你还需要检查你没有跑出边界。但你是对的,它可以只用一个循环语句重写。
    猜你喜欢
    • 1970-01-01
    • 2017-08-22
    • 2018-09-30
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    • 2018-07-15
    • 1970-01-01
    相关资源
    最近更新 更多