替换数组中的重复元素

时间:2014-05-12 19:26:14

标签: c++ algorithm data-structures rcpp

我一直在尝试用特定的公式替换数组中多次出现的元素。确切地说,考虑到在数组中x已经发生了k次,我需要用x +(k-1)/ 2替换x的所有出现。例如,说2发生了2次,然后用2.5替换所有发生的2。

我这样做的想法是维护一个与输入相同长度的数组作为标志,以检查是否检查了特定元素。这需要O(n ^ 2)时间。代码如下。

NumericVector replaceRepetedValues(NumericVector x){
   logicalVector flag(x.size());
   for(int i=0;i<x.size();i++){
     int count=0;
     std::vector<int> index;

     for(int j=i+1;j<x.size();j++){
      if(x[i]==x[j]){
       count++;
       index.push_back(j);           
      }
     }
     if(count>0){
       for(std::vector<int>::iterator it=index.begin();it!=it.end();it++){
         x[*it]=x[*it]+(count-1)/2;
       }
     } 
   }
}

这个问题有效吗?

1 个答案:

答案 0 :(得分:4)

您可以使用散列图(std::unordered_map)在O(N)时间内获得计数。类似的东西:

std::vector<int> x = buildMyVector();
std::unordered_map<int, int> counts;
for(int val : x)
   counts[val]++;

然后第二次O(N)操作可以进行更新:

for(int& val : x)
{
   int count = counts[val];
   if(count > 1) // could technically skip this since (1 - 1) / 2 is 0
      val += (count - 1) / 2;
}

但是,由于x是vector<int>,因此总是使用整数除法;即你的例子中你不会得2.5,你只会得到两个。如果您需要2.5,则需要将vector<int>更改为vector<double>(或float)。这可能会使你的比较陷入困境(应该是2.0000000001 == 2.0?),所以你需要重新思考如何处理它。如果输入始终是int但输出可以是double,则可能是:

std::vector<double> output;
output.reserve(x.size());

for(int val : x)
{
   double newVal = static_cast<double>(val);
   int count = counts[val];
   if(count > 1) // could technically skip this since (1 - 1) / 2 is 0
      newVal += (count - 1.0) / 2.0;
   output.push_back(newVal);
}