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_bound
或 std::upper_bound
可能会满足您的需求(感谢 Eric 的说明)。否则,如果您使用标准二进制搜索,即使未找到完全匹配,它也会将您置于查看两个或三个值的范围内,其中一个绝对是您的匹配项。
现在,正如 Eric 在 cmets 中指出的那样,排序确实比线性搜索花费更多,所以如果您只搜索该数据集一次,那么您已经有了最有效的方法。
编辑:在 cmets 中,OP 描述了有时需要向向量添加新数据。这是一个很容易解决的问题:只需使用二分搜索查找新值在 sorted 向量中的位置,然后将其插入到那里。
【讨论】:
排序是O(n log n),所以除非你能预先支付这个费用,否则最好不要排序。 是的,我明白了,但我会澄清这一点。 如果只搜索一次,不要排序。这是规则。 “使用二分搜索算法” -std::lower_bound
或 std::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中怎么的主要内容,如果未能解决你的问题,请参考以下文章