简体   繁体   English

数组(向量)中大于某个值的元素的起始索引和终止索引

[英]starting index and ending index of elements in a array(vector) that are greater than a value

Given a array like this: 给定这样的数组:

{1, 3, 11, 2, 24, 13, 5....}

The array length might be larger than 1,000. 阵列长度可能大于1,000。

If the value of the element is inappropriate, such as larger than 10, it shall be replaced by appropriate value. 如果元素的值不合适,例如大于10,则应将其替换为适当的值。 In this case, the appropriate value is calculated by linear interpolation. 在这种情况下,通过线性插值计算适当的值。

For example: 例如:

Arr = {1, 3, 11, 2, 24, 13, 5....}; Arr = {1,3,11,2,24,13,5 ....};

The new array shall be: 新数组应为:

NewArr = {1, 3, 3+(2-3)/2, 2, 2+(5-2)/3, 2+2*(5-2)/3, 5, ...} NewArr = {1,3,3+(2-3)/ 2,2,2+(5-2)/ 3,2 + 2 *(5-2)/ 3,5,...}

In order to do this, I have to know the starting and ending index of the inappropriate elements. 为此,我必须知道不合适元素的开始和结束索引

The starting and ending index shall be (2,2) indicating the "11" and (4,5) indicating the "24, 13" 起始索引和结束索引应为(2,2)表示“ 11”,而(4,5)表示“ 24、13”

I have tried the for loop . 我已经尝试过for loop But it is not efficient. 但这不是有效的。 Then I searched IPP API and did not get an result. 然后,我搜索了IPP API ,但没有得到结果。 :( :(

Is there a better idea? 有更好的主意吗?

Thanks for your help, :). 谢谢你的帮助, :)。

BTW : IPP API will be a better choice. 顺便说一句IPP API将是一个更好的选择。

Update: 更新:

Sample Codes: 样例代码:

int arr[] = {1, 3, 11, 2, 24, 13, 5....};

/// find the starting index and ending index of inappropriate values
/// (2,2) (4,5).
int i = 0; 
std::map<int,int> Segments;
if(arr[i] > Threshold)
{
    int b = i;
    while(arr[i] > Threshold )
        i ++;
    int e = i;
    Segments.insert(std::map<int,int>::value_type(b,e));
}

/// linear interpolation
for(std::map<int,int>::iterator i = 0; i != Segments.end(); i ++) /// len means the number of inappropriate segments  
{
    //// linear interpolation of each segments
    int b = i->first;
    int e = i->second;
    int num = e - b + 1;
    float step = (arr[e+1]-arr[b-1]) / num; // For short. The case that b=0 or e=len-1 is not considered. 
    for(int j = b; j <= e; j ++)
        arr[j] = arr[j-1] + step;
}

Update2 : Thanks for all your help. Update2 :感谢您的所有帮助。 But based of the answers of these questions: Speed accessing a std::vector by iterator vs by operator[]/index? 但是基于这些问题的答案: 通过迭代器还是通过operator [] / index来快速访问std :: vector? and Why use iterators instead of array indices? 以及为什么使用迭代器而不是数组索引? , the efficients of two forms( for vs iterator) are almost the same. ,两种形式(对于vs迭代器)的效率几乎相同。 So iterator might not be good enough. 因此, iterator可能不够好。

I usually used the SIMD such as IPP API as the optimize option. 我通常使用SIMD例如IPP API作为优化选项。 But I did not figure it out since all the find API only get the first occurrence of the specified element. 但是我没有弄清楚,因为所有的find API仅获得指定元素的第一次出现

I will update the solution if I figure out some day. 如果有一天我会更新解决方案。 :) :)

If you want to search for a particular value, and replace the items from a vector that match a certain criteria, then that can be done in one line using transform(). 如果要搜索特定值,并从向量中替换符合特定条件的项目,则可以使用transform()在一行中完成。

The replace_if() can also be used, but given the vague description of your issue, I don't know if the replacement value needs to vary depending on the original value (replace_if needs a constant replacement value). 还可以使用replace_if(),但是鉴于您问题的描述含糊,我不知道替换值是否需要根据原始值而有所不同(replace_if需要恒定的替换值)。 So let's go with std::transform() for now. 因此,现在让我们使用std :: transform()。

#include <algorithm>
#include <vector>

struct Transformer 
{
   bool ThisNumberNeedsTransformation(int num) { 
     // you fill this in.  Return true if number needs to be changed, false otherwise
   }

   int TransformNumber(int num) {
      // you fill this in.  Return the changed number, given the original number.
   }

   int operator()(int num)
   {
      if ( ThisNumberNeedsTransformation(num) )
          return TransformNumber(num);
      return num;
   }
};

int main()
{
     std::vector<int> intVector;
     //...
     std::transform(intVector.begin(), intVector.end(), intVector.begin(), Transformer());
}

Basically, the struct serves as a function object. 基本上,该结构充当函数对象。 For each of the items in the intVector, the function object will operate on that number. 对于intVector中的每个项目,函数对象都将对该数字进行操作。 If the number matches the criteria, then the number is transformed and returned, else the original number is returned. 如果数字符合条件,则将数字转换并返回,否则返回原始数字。

Since you didn't really clarify what your criteria is to change numbers, this approach gives the solution to your issue more flexibility. 由于您并未真正弄清楚更改数字的标准,因此这种方法为您解决问题提供了更大的灵活性。 All you need to do is fill in the two functions that I left open in the Transformer struct, then things should work correctly. 您需要做的就是填写我在Transformer结构中打开的两个函数,然后一切正常。

If your needs are more complex, the function object Transformer can be expanded upon to include member variables, or just simply put, can be as complex as you want to make it. 如果您的需求更加复杂,则可以扩展功能对象Transformer以包括成员变量,或者只是简单地将其扩展为您想要的复杂程度即可。

Also remember, if you're timing these things, time a release, optimized build . 还请记住,如果您正在安排这些时间 ,请安排发布,优化的构建 Don't time "debug" or unoptimized builds. 不要计时“调试”或未优化的构建。

I'm not exactly sure what you mean by the "starting and ending index of the inappropriate elements", so I'm going to assume you just mean the index . 我不确定“不适当元素的开始和结束索引”是什么意思,所以我将假设您只是指索引

Using a vector here would be a good approach: 在这里使用向量将是一个好方法:

std::vector<int> the_stuff {1, 3, 11, 2, 24, 13, 5, ... };
std::vector<int>::iterator it = the_stuff.begin();

while (it != the_stuff.end()
{
   if (*it > 10) { // do stuff };
   etc.
}

You get the idea. 你明白了。 Use a vector , and it should make things a lot easier for you. 使用vector ,它应该使您更轻松。 search / insert / get indexes / remove / etc. at your leisure. 闲暇时搜索/插入/获取索引/删除/等等。

If you store your number in an std::vector, you can iterate over the array through an iterator. 如果将数字存储在std :: vector中,则可以通过迭代器在数组上进行迭代。 As soon as you find an element that meets your condition and needs to be removed, you can remove it and at the same time assign your iterator to the next element. 一旦找到满足条件并需要删除的元素,就可以删除它,同时将迭代器分配给下一个元素。 This will be the most efficient way: 这将是最有效的方法:

Here is what your code will look like: 您的代码如下所示:

std::vector<int> intVector;
for(auto it = intVector.begin(); it != intVector.end(); ++it)
{
    if (*it > 10)
    {
        it = intVector.erase(it);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM