Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何将整数数组划分为偶数和奇数?_Javascript_Algorithm_Data Partitioning - Fatal编程技术网

Javascript 如何将整数数组划分为偶数和奇数?

Javascript 如何将整数数组划分为偶数和奇数?,javascript,algorithm,data-partitioning,Javascript,Algorithm,Data Partitioning,我想对数组进行分区(例如[1,2,3,4,5,6,7,8]),第一个分区应保留偶数值,第二个分区应保留奇数值(示例结果:[2,4,6,8,1,3,5,7]) 我使用内置的Array.prototype方法两次解决了这个问题。第一种解决方案使用映射和排序,第二种解决方案仅使用排序 我想提出第三种解决方案,它使用排序算法,但我不知道使用什么算法来划分列表。我正在考虑冒泡排序,但我认为它用于我的第二个解决方案(array.sort((el1,el2)=>(el1%2-el2%2)))。。。我看了,但我

我想对数组进行分区(例如
[1,2,3,4,5,6,7,8]
),第一个分区应保留偶数值,第二个分区应保留奇数值(示例结果:
[2,4,6,8,1,3,5,7]

我使用内置的
Array.prototype
方法两次解决了这个问题。第一种解决方案使用
映射
排序
,第二种解决方案仅使用
排序

我想提出第三种解决方案,它使用排序算法,但我不知道使用什么算法来划分列表。我正在考虑冒泡排序,但我认为它用于我的第二个解决方案(
array.sort((el1,el2)=>(el1%2-el2%2))
)。。。我看了,但我不知道在哪里应用检查,如果一个整数是偶数或奇数

在保持元素顺序的情况下,执行此类任务的最佳(线性缩放和阵列增长)算法是什么

let evens = arr.filter(i=> i%2==0);
let odds = arr.filter(i=> i%2==1);
let result = evens.concat(odds);
我相信这是O(n)。玩得开心

编辑: 或者如果你真的关心效率:

let evens, odds = []
arr.forEach(i=> {
if(i%2==0) evens.push(i); else odds.push(i);
});
let result = evens.concat(odds);
Array.prototype.getEvenOdd=函数(arr){
var result={偶数:[],奇数:[]};
if(阵列长度){
对于(变量i=0;i
您可以非常轻松地在O(n)时间内就地完成此操作。从前面的偶数索引开始,从后面的奇数索引开始。然后,遍历数组,跳过第一个偶数块

当你碰到一个奇数时,从末尾向后移动找到第一个偶数。然后交换偶数和奇数

代码如下所示:

var i;
var odd = n-1;
for(i = 0; i < odd; i++)
{
    if(arr[i] % 2 == 1)
    {
        // move the odd index backwards until you find the first even number.
        while (odd > i && arr[odd] % 2 == 1)
        {
            odd--;
        }
        if (odd > i)
        {
            var temp = arr[i];
            arr[i] = arr[odd];
            arr[odd] = temp;
        }
    }
}
vari;
var奇数=n-1;
对于(i=0;i<奇数;i++)
{
如果(arr[i]%2==1)
{
//向后移动奇数索引,直到找到第一个偶数。
而(奇数>i&&arr[奇数]%2==1)
{
奇数--;
}
if(奇数>i)
{
var-temp=arr[i];
arr[i]=arr[奇数];
arr[奇数]=温度;
}
}
}
请原谅任何语法错误。Javascript不是我的强项


请注意,这不会保持相同的相对顺序。也就是说,如果给它数组
[1,2,7,3,6,8]
,那么结果将是
[8,2,6,3,7,1]
。数组已分区,但奇数的相对顺序与原始数组中的不同。

如果您坚持使用就地方法而不是简单的标准
返回[arr.filter(谓词),arr.filter(notPredicate)]
方法,则可以使用两个索引轻松有效地实现,从阵列两侧运行并在必要时交换:

function partitionInplace(arr, predicate) {
    var i=0, j=arr.length;
    while (i<j) {
        while (predicate(arr[i]) && ++i<j);
        if (i==j) break;
        while (i<--j && !predicate(arr[j]));
        if (i==j) break;
        [arr[i], arr[j]] = [arr[j], arr[i]];
        i++;
    }
    return i; // the index of the first element not to fulfil the predicate
}
函数分区平面(arr,谓词){
变量i=0,j=arr.length;

虽然(iAny sort)充其量是
O(nlogn)
,但是如果你想要线性缩放,那么这些并不是最好的选择
sort
?你有没有尝试过使用
过滤器
?为什么要使用它?它有什么用途?为什么要向下投票?我的问题有什么问题吗?@t.J.Crowder in-place,我认为唯一的目的是让它更难用(我的问题是一个家庭作业)嗯,我们可以减少一半的开销。(这也不到位,请参见答案的结尾。)仍然没有到位,正如问题明确要求的那样。除了最后的第三个数组之外,仍然生成两个临时数组。(不是我的dv;我理解,但不会这样做)@T.J.Crowder
i
index
的保留关键字,不是吗?@kind:不,一点也不。它可以是你想要的任何东西。虽然这很有效,但我认为部分目标是使它成为一个稳定的分区,因为示例中的OP指定输出应该与每个T中的输入保持相同的顺序他进行了分区。@PatrickRoberts:我不知道OP在哪里特别指出输出应该是稳定的。他的例子显示了一个稳定的安排,但没有任何东西表明它必须是稳定的。不过,重点是:这不稳定。我会用这些信息更新我的答案。@PatrickRoberts,谢谢,它应该像你说的那样保持分区顺序。抱歉,Jim,我没有明确地编写它。这不是与我的答案相同的逻辑吗?这不会改变分区中项目的相对顺序吗?也就是说,如果给定[1,3,2,4],结果数组将是[4,2,3,1]?@JimMischel是的,这是相同的想法,只有我的实现使用任意谓词,返回数组被分割的位置,因此有更复杂的代码:-)确实交换改变了相对顺序,但我非常确定没有算法能够在
O(n)中实现稳定的重新排序
时间和
O(1)
空间复杂性。我认为你是对的,没有一个O(n),O(1)解决方案是稳定的。这让我想起了一个笑话(?):快速,便宜,好:选择两个。
function partitionInplace(arr, predicate) {
    var i=0, j=arr.length;
    while (i<j) {
        while (predicate(arr[i]) && ++i<j);
        if (i==j) break;
        while (i<--j && !predicate(arr[j]));
        if (i==j) break;
        [arr[i], arr[j]] = [arr[j], arr[i]];
        i++;
    }
    return i; // the index of the first element not to fulfil the predicate
}