matlab中怎么查找一个向量中第一个非零元素的位置 如P=[0;1;2] 第一个非零元素的位置为2,在mbtlab中怎么

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了matlab中怎么查找一个向量中第一个非零元素的位置 如P=[0;1;2] 第一个非零元素的位置为2,在mbtlab中怎么相关的知识,希望对你有一定的参考价值。

matlab中怎么查找一个向量中第一个非零元素的位置 如P=[0;1;2] 第一个非零元素的位置为2,在mbtlab中第 2 个

参考技术A find(p,1) 参考技术B pp=find(P~=0);
pp(1)本回答被提问者采纳
参考技术C 写一个M函数如何 ?似乎没有简单的语句。

C ++有效查找向量中第一个最近的匹配值?

【中文标题】C ++有效查找向量中第一个最近的匹配值?【英文标题】:C++ efficient finding of the first nearest matching value in a vector? 【发布时间】:2018-09-22 21:23:27 【问题描述】:

给定未排序的向量 6.0, 3.02, 4.2, 5.3 并给出阈值 0.1,如何在 C++ 中的给定阈值内有效地找到值 3(例如)的第一个匹配项? 我目前的实现如下,但复杂度为 O(n)。如果可能,我想将其改进为 O(log n)。提前非常感谢

std::vector<double> array = 6.0, 3.02, 4.2, 5.3;  
double val = 3 // the to be found value within the array above
double thresh = 0.1; // max threshold of the matching value
double found; // the matching value
for (int i = 0; i < array.size(); i++)
    if ( abs(array[i] - val) < thresh)
        found = array[i];
    

输出应该是 3.02,因为它是在允许的阈值 0.1 内给定数组中第一个最接近 3 的匹配项

编辑:如果我能负担得起预先对向量进行排序,我该如何将上述搜索重新实现为 O(log n)?谢谢

【问题讨论】:

我认为不先对数组进行排序就不可能击败 O(n) 如果数组未排序或以任何方式特别组织,则必须扫描所有元素。 数据作为向量给出?如果是这样,就没有运气 顺便说一句,如果您使用 C 库中的一个,请注意 abs(),它会将数字四舍五入为 int 您的问题与实现不匹配 - 您的算法会找到 "val 的 0.1 内的第一个现有值",而不是 "将现有值关闭到 @ 987654325@" 【参考方案1】:

您正在执行线性搜索,肯定是O(n)。然而,不幸的是,对于未排序的数组/向量,这是最快的搜索算法。

因此,要获得更快的结果,您需要先对向量进行排序。 预先执行一次,否则生成的代码实际上会比线性搜索慢。std::sort() 相当有效 - 尽管有一些更快的排序算法,如果你想找到一个.根据您的需要,请确保您实际上是在原地或在新变量中存储已排序的向量。 您不希望对数据进行多次排序。

然后,您可以使用二进制搜索算法来定位该值。 std::lower_boundstd::upper_bound 可能会满足您的需求(感谢 Eric 的说明)。否则,如果您使用标准二进制搜索,即使未找到完全匹配,它也会将您置于查看两个或三个值的范围内,其中一个绝对是您的匹配项。

现在,正如 Eric 在 cmets 中指出的那样,排序确实比线性搜索花费更多,所以如果您只搜索该数据集一次,那么您已经有了最有效的方法。


编辑:在 cmets 中,OP 描述了有时需要向向量添加新数据。这是一个很容易解决的问题:只需使用二分搜索查找新值在 sorted 向量中的位置,然后将其插入到那里。

【讨论】:

排序是O(n log n),所以除非你能预先支付这个费用,否则最好不要排序。 是的,我明白了,但我会澄清这一点。 如果只搜索一次,不要排序。这是规则。 “使用二分搜索算法” - std::lower_boundstd::upper_bound 会在这里完成这项工作 @user3134575 这实际上是一个需要解决的简单问题:在插入过程中使用二分搜索。不要将值粘贴在末尾,而是首先找到它所属的位置,然后将其插入那里。【参考方案2】:

正如其他人所难过的那样,如果不对数组进行排序,您将无法比 O(n) 搜索做得更好。

如果我们先对数组进行排序,我们可以进行二分查找并采用新的策略。

我们需要找出数组中第一个满足 (array[pos] >= (value - threshold) ) 的值。如果我们能找到这样的值,那么我们检查它是否在 [值 - 阈值,值 + 阈值] 范围内。如果是我们返回它,否则我们不返回。

下面是我将如何使用 C++ 实现排序。

#include <vector>
#include <algorithm>
#include <math.h>
#include <limits>
#include <iostream>
#include <iterator>

double binarySearch(std::vector<double>& array, const double value, const double threshold) 

    // I assume here that the array is sorted ...
    // If I cannot find it, I will return infinity (:

    double returnValue = std::numeric_limits<double>::infinity();

    std::vector<double>::iterator it = std::lower_bound(array.begin(), array.end(), value - threshold);

    if(it != array.end() ) 
    
        if(fabs(*it - value) <= threshold ) returnValue = *it;
    

    return returnValue;




int main() 

    std::vector<double> array = 6.0, 3.02, 4.2, 5.3;    
    double val = 3.0;
    double threshold = 0.1;

    // Sorting the array
    std::sort(array.begin(), array.end() );
    double res = binarySearch(array, val, threshold);

    if(res != std::numeric_limits<double>::infinity() )
    
        std::cout << res << std::endl;
    
    else std::cout << "Desired value not found" << std::endl;

    return 0;

【讨论】:

【参考方案3】:

我认为这是不可能的。您可以改进排序数组中的搜索的最佳方法是使用二分搜索O(log(n))。但是在未排序的数组中,您最终必须遍历所有数组项,这是 O(n)

【讨论】:

二分排序还是二分查找?

以上是关于matlab中怎么查找一个向量中第一个非零元素的位置 如P=[0;1;2] 第一个非零元素的位置为2,在mbtlab中怎么的主要内容,如果未能解决你的问题,请参考以下文章

matlab基本函数find

MATLAB中查找数组中的非零元素用啥函数

Matlab如何提取非零元素

matlab中如何求两直线交点?

matlab中怎么求数组中非零元素的个数

用先前的非零值替换向量中的所有零