c# – 如何在适当的位置重新排序数组以将偶数索引项放在奇数之前?

c# – 如何在适当的位置重新排序数组以将偶数索引项放在奇数之前?,第1张

概述我有一个排序数组,我想重新排序,以便先前甚至索引的项目在开头,然后是奇数索引项目. 例如:[a,b,c,d,e,f] => [a,c,e,b,d,f]. 我也将(另外)想要做相反的事情,首先使用奇数索引: 例如:[a,b,c,d,e,f] => [b,d,f,a,c,e]. 我知道我可以创建单独的奇数/偶数数组然后重新合并它们,但性能是关键,我正在尝试找到一个单循环,就地解决方案,避免分配和使用临 我有一个排序数组,我想重新排序,以便先前甚至索引的项目在开头,然后是奇数索引项目.

例如:[a,b,c,d,e,f] => [a,f].

我也将(另外)想要做相反的事情,首先使用奇数索引:

例如:[a,f] => [b,f,a,e].

我知道我可以创建单独的奇数/偶数数组然后重新合并它们,但性能是关键,我正在尝试找到一个单循环,就地解决方案,避免分配和使用临时数组.

语境:

我递归搜索一个移动的游戏树(带有Alpha-beta的minimax)并且我正在尝试实现Lazy SMP,我在其他线程上搜索相同的位置,但尝试以略微不同的顺序移动,将结果保存到共享(换位) )表,以提高主搜索线程的效率.

澄清:

起始数组已经排序,我希望保持偶数/奇数索引内的顺序.也就是说,我不想只是将平均值和赔率分组在一起,最后说[f,a].

另外,我严格按索引值排序,而不是存储在那里的项目.因此,任何涉及项值的搜索谓词的方法都不起作用.

虽然我用C#编写,但我不想使用liNQ,因为我需要将代码移植到没有liNQ的系统.

我希望有一种方法可以循环一次数组并执行一系列项目交换,这样我最终会得到我所描述的排序.我一直在纸上尝试,但还没有任何工作.

澄清2:

我用字母而不是数字更新了示例,并在我向后调整奇数/偶数示例时进行了交换.我想要两个.

最终我试图模拟循环原始数组,但跳过所有其他项目仍然查看每个项目.有两个循环我会做以下事情:

// Case 1: Regular orderfor (int i = 0; i < items.Length; i ++){    // Process}// Case 2: Even indexes firstfor (int i = 0; i < items.Length; i += 2){    // Process}for (int i = 1; i < items.Length; i += 2){    // Process}// Case 3: Odd indexes firstfor (int i = 1; i < items.Length; i += 2){    // Process}for (int i = 0; i < items.Length; i += 2){    // Process}

循环中的处理足够复杂,因为它递归调用此函数,具有提前终止循环的单独条件等,因此我不想复制它和/或将其放在另一个函数中.

因此,我不是只有两个循环,或者是一个处理所有三种情况的复杂循环,而是选择预先分配项目.

澄清3:

我需要处理所有三种情况的东西,它支持任何大小的数组(不仅仅是#项目),并且没有使游戏搜索循环内容混乱.我认为在该循环之前进行就地预先排序是最好的选择.

最后,我决定放弃使用自定义迭代器跳过项目的就地预排序和扩展List.我在下面添加了我的代码,但我不会将其标记为答案,因为它在技术上并不是我要求的.

谢谢大家的帮助. (如果有人发布了一个循环,基于就地交换的解决方案适用于任意数量的项目,我将很乐意接受它作为答案.)

解决方法 这是一种在阵列上的单个路径中执行的算法.它假设数组具有偶数个项N,并且我们可以分配bool [N / 2]数组:
static voID OddEvenSwap(int[] data) {    int n = data.Length / 2;    int p = 0;    var seen = new bool[n];    while (true) {        int last = data[p];        do {            var tmp = data[p];            data[p] = last;            last = tmp;            if (p < n) {                seen[p] = true;            }            p = (p/2) + (p%2 == 0 ? n : 0);        } while (p >= n || !seen[p]);        data[p] = last;        while (p != n && seen[p]) {            p++;        }        if (p == n) {            break;        }    }}

以下是其工作原理的简要说明:

>给定项目的源索引p,我们总是可以直接计算其目标索引
>从索引零开始,计算其目标索引,在此处移动项目,并从目标索引继续到下一个目标
>标记我们访问过的下半部分中的所有索引
>最终我们将看到我们所见过的指数;将最后一项放在那里,因为我们已经完成了这个循环
>从我们尚未访问过的下半部分找到下一个索引
>一旦我们耗尽了所有索引,我们就完成了

Demo.

注意:如果重复运行此算法,您应该能够避免重新分配see []数组,方法是以最大大小分配一次,然后简单地用falses填充它.

总结

以上是内存溢出为你收集整理的c# – 如何在适当的位置重新排序数组以将偶数索引项放在奇数之前?全部内容,希望文章能够帮你解决c# – 如何在适当的位置重新排序数组以将偶数索引项放在奇数之前?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1249092.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存