1

给定一个这样的数组:

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

数组长度可能大于 1,000。

如果元素的值不合适,如大于10,则应替换为合适的值。在这种情况下,通过线性插值计算适当的值。

例如:

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

新数组应为:

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

为了做到这一点,我必须知道不合适元素的开始和结束索引

开始和结束索引应为 (2,2) 表示“11”和 (4,5) 表示“24, 13”

我试过了for loop。但效率不高。然后我搜索IPP API并没有得到结果。:(

有更好的主意吗?

谢谢你的帮助, :)。

顺便说一句IPP API将是一个更好的选择。

更新:

示例代码:

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;
}

更新2:感谢您的所有帮助。但基于这些问题的答案:Speed access a std::vector by iterator vs by operator[]/index? 为什么使用迭代器而不是数组索引?,两种形式(for vs iterator)的效率几乎相同。所以iterator可能还不够好。

我通常使用SIMD诸如IPP API优化选项。但我没有弄明白,因为所有findAPI 只获得指定元素的第一次出现

如果有一天我弄清楚了,我会更新解决方案。:)

4

3 回答 3

1

如果要搜索特定值,并替换向量中符合特定条件的项目,则可以使用 transform() 在一行中完成。

replace_if() 也可以使用,但鉴于您对问题的模糊描述,我不知道替换值是否需要根据原始值而变化(replace_if 需要一个恒定的替换值)。所以现在让我们使用 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());
}

基本上,结构用作函数对象。对于 intVector 中的每个项目,函数对象将对该数字进行操作。如果数字与条件匹配,则转换并返回数字,否则返回原始数字。

由于您没有真正阐明更改数字的标准是什么,因此这种方法为您的问题的解决方案提供了更大的灵活性。您需要做的就是填写我在结构中打开的两个函数Transformer,然后事情应该可以正常工作。

如果您的需求更复杂,可以扩展函数对象 Transformer 以包含成员变量,或者简单地说,可以像您想要的那样复杂。

还请记住,如果您正在为这些事情计时,请为发布、优化构建计时。不要计时“调试”或未优化的构建。

于 2014-04-17T15:58:13.810 回答
0

我不确定您所说的“不适当元素的开始和结束索引”是什么意思,所以我假设您只是指index

在这里使用向量将是一个好方法:

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.
}

你明白了。使用vector,它应该会让你的事情变得更容易。随意搜索/插入/获取索引/删除/等。

于 2014-04-17T15:33:45.063 回答
0

如果将数字存储在 std::vector 中,则可以通过迭代器迭代数组。一旦找到满足条件并需要删除的元素,就可以将其删除,同时将迭代器分配给下一个元素。这将是最有效的方法:

这是您的代码的样子:

std::vector<int> intVector;
for(auto it = intVector.begin(); it != intVector.end(); ++it)
{
    if (*it > 10)
    {
        it = intVector.erase(it);
    }
}
于 2014-04-17T15:46:24.387 回答