C++ 在数组中替换重新加载的元素

C++ 在数组中替换重新加载的元素,c++,algorithm,data-structures,rcpp,C++,Algorithm,Data Structures,Rcpp,我一直试图用一个特定的公式替换数组中多次出现的元素。确切地说,在数组值x已经出现k次时,我需要用x +(k-1)/ 2替换x的所有出现。例如,假设2已发生2次,然后将所有出现的2替换为2.5 我这样做的想法是保持一个与输入长度相同的数组作为一个标志,以检查是否检查了某个特定元素。这需要O(n^2)时间。代码如下 NumericVector replaceRepetedValues(NumericVector x){ logicalVector flag(x.size()); for(

我一直试图用一个特定的公式替换数组中多次出现的元素。确切地说,在数组值x已经出现k次时,我需要用x +(k-1)/ 2替换x的所有出现。例如,假设2已发生2次,然后将所有出现的2替换为2.5

我这样做的想法是保持一个与输入长度相同的数组作为一个标志,以检查是否检查了某个特定元素。这需要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;
       }
     } 
   }
}
NumericVector替换重复值(NumericVector x){
logicalVector标志(x.size());

对于(int i=0;i您可以使用hashmap(
std::unordered_map
)在O(N)时间内获取计数。类似于:

std::vector<int> x = buildMyVector();
std::unordered_map<int, int> counts;
for(int val : x)
   counts[val]++;
但是,由于x是一个
向量
,因此将始终使用整数除法;也就是说,在您的示例中,您不会得到2.5,您只会得到两个。如果您想要2.5,您需要将
向量
更改为
向量
(或
浮点
)。但这可能会打乱您的比较(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);
}
std::矢量输出;
输出保留(x.size());
用于(int val:x)
{
双newVal=静态_转换(val);
int count=计数[val];
if(count>1)//技术上可以跳过此操作,因为(1-1)/2是0
newVal+=(计数-1.0)/2.0;
输出。推回(newVal);
}

您可以使用hashmap(
std::unordered_map
)在O(N)时间内获得计数。类似于:

std::vector<int> x = buildMyVector();
std::unordered_map<int, int> counts;
for(int val : x)
   counts[val]++;
但是,由于x是一个
向量
,因此将始终使用整数除法;也就是说,在您的示例中,您不会得到2.5,您只会得到两个。如果您想要2.5,您需要将
向量
更改为
向量
(或
浮点
)。但这可能会打乱您的比较(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);
}
std::矢量输出;
输出保留(x.size());
用于(int val:x)
{
双newVal=静态_转换(val);
int count=计数[val];
if(count>1)//技术上可以跳过此操作,因为(1-1)/2是0
newVal+=(计数-1.0)/2.0;
输出。推回(newVal);
}

您的问题是什么?为什么不先计算x?然后重新启动并用基于此计数的公式替换每个x。这不是O(n^2)如果你想减少内存使用量,考虑一个整数数组来记录每个元素的出现次数。“RedAlert,我想现在的问题是clear@PaulMcKenzie,计数是用O(N^2)时间计算的。但哈希映射似乎在O(N)时间内完成了计算。谢谢您的帮助。:)你的问题是什么?为什么不先得到一个x的计数?然后重新启动并用基于此计数的公式替换每个x。这不是O(n^2)如果你想减少内存使用量,考虑一个整数数组来记录每个元素的出现次数。“RedAlert,我想现在的问题是clear@PaulMcKenzie,计数是O(N^2)计算所花费的时间。但哈希映射似乎在O(N)中起作用时间。谢谢你的帮助。:)谢谢你这是一个优雅的解决方案。这不是问题,我可以用浮点向量得到输出。所以需要混乱的交叉类型比较。我不明白。即使在第一个阶段也没有任何交叉类型比较solution@kaz在第一个解中,假设val为2,2在向量中出现两次在这种情况下,你想用2.5替换每个2,但你不能,因为x是向量-,它只会把它降回2。有各种各样的方法来处理这个问题,但你比我更能判断哪个是最好的。谢谢你,这是一个优雅的解决方案。这不是一个问题,我可以得到浮点向量的输出。所以需要混乱的跨类型比较。我不明白。即使在第一个阶段也没有任何跨类型比较solution@kaz在第一个解决方案中,假设val为2,2在向量中出现两次。在这种情况下,您说过要用2.5替换每个2,但您不能,因为x是
向量
——它只会将它放回2。这里有各种各样的方法来处理这个问题,但你比我更能判断哪一个是最好的。