我一直在尝试用特定的公式替换数组中多次出现的元素。确切地说,考虑到在数组中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;
}
}
}
}
这个问题有效吗?
答案 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);
}