按奇偶校验排序数组结果不稳健
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了按奇偶校验排序数组结果不稳健相关的知识,希望对你有一定的参考价值。
我是一个新的程序员,我试图按他们的平价排序一个整数向量 - 在偶数前加上偶数。奇数或偶数内部的顺序无关紧要。例如,给定输入[3,1,2,4],输出可以是[2,4,3,1]或[4,2,1,3]等。下面是我的c ++代码,有时我幸运的是,矢量得到了正确的排序,有时却没有。我导出奇数和偶数向量,它们看起来是正确的,但当我试图将它们组合在一起时,它只是搞砸了。有人可以帮我调试吗?
class Solution
public:
vector<int> sortArrayByParity(vector<int>& A)
unordered_multiset<int> even;
unordered_multiset<int> odd;
vector<int> result(A.size());
for(int C:A)
if(C%2 == 0)
even.insert(C);
else
odd.insert(C);
merge(even.begin(),even.end(),odd.begin(),odd.end(),result.begin());
return result;
;
如果您在赔率之前只需要偶数值而不是完整的排序我建议您使用std::partition
。你给它两个迭代器和一个谓词。谓词返回true
的元素将出现在其他元素之前。它就地工作,应该非常快。
像这样的东西:
std::vector<int> sortArrayByParity(std::vector<int>& A)
std::partition(A.begin(), A.end(), [](int value) return value % 2 == 0; );
return A;
因为merge
函数假定两个范围已排序,这在合并排序中使用。相反,你应该只使用insert
的vector
函数:
result.insert(result.end(), even.begin(), even.end());
result.insert(result.end(), odd.begin(), odd.end());
return result;
无需创建三个单独的向量。由于您已在结果向量中分配了足够的空间,因此该向量也可用作最终向量,以存储子向量,存储分离的奇数和偶数。
使用矢量(在封面下是一个数组)的值是为了避免插入和移动。数组/向量很快,因为它们允许从一开始就作为偏移立即访问内存。利用这个!
代码只是保留下一个奇数和偶数索引的索引,然后相应地分配正确的单元格。
class Solution
public:
// As this function does not access any members, it can be made static
static std::vector<int> sortArrayByParity(std::vector<int>& A)
std::vector<int> result(A.size());
uint even_index = 0;
uint odd_index = A.size()-1;
for(int element: A)
if(element%2 == 0)
result[even_index++] = element;
else
result[odd_index--] = element;
return result;
;
利用您不关心偶数或奇数本身的顺序这一事实,您可以使用一种非常简单的算法来就地对数组进行排序:
// Assume helper function is_even() and is_odd() are defined.
void sortArrayByParity(std::vector<int>& A)
int i = 0; // scanning from beginning
int j = A.size()-1; // scanning from end
do
while (i < j && is_even(A[i])) ++i; // A[i] is an even at the front
while (i < j && is_odd(A[j])) --j; // A[j] is an odd at the back
if (i >= j) break;
// Now A[i] must be an odd number in front of an even number A[j]
std::swap(A[i], A[j]);
++i;
--j;
while (true);
请注意,上面的函数返回void,因为向量是就地排序的。如果你想要返回输入向量的排序副本,你需要在函数内部定义一个新的向量,并在每个++i
和--j
之前复制元素(当然不要使用std::swap
但是复制元素交叉相反;同样,通过A
作为const std::vector<int>& A
)。
// Assume helper function is_even() and is_odd() are defined.
std::vector<int> sortArrayByParity(const std::vector<int>& A)
std::vector<int> B(A.size());
int i = 0; // scanning from beginning
int j = A.size()-1; // scanning from end
do
while (i < j && is_even(A[i]))
B[i] = A[i];
++i;
while (i < j && is_odd(A[j]))
B[j] = A[j];
--j;
if (i >= j) break;
// Now A[i] must be an odd number in front of an even number A[j]
B[i] = A[j];
B[j] = A[i];
++i;
--j;
while (true);
return B;
在上述两种情况下(就地或非现场),函数具有复杂度O(N),N是A
中的元素数量,比用于排序N个元素的一般O(N log N)好得多。这是因为这个问题实际上并没有太多分类 - 它只是从奇数中分离出来。因此,无需调用完整的排序算法。
以上是关于按奇偶校验排序数组结果不稳健的主要内容,如果未能解决你的问题,请参考以下文章