【问题标题】:Sorting even and odd numbers inside an array对数组中的偶数和奇数进行排序
【发布时间】:2015-10-24 12:03:00
【问题描述】:

我正在尝试将数组拆分为 oddeven 数字。请注意,最终结果中的数字排序无关紧要。我正在编译代码,输出包含一些错误。我的代码正确排列了 odd 数字,而 even 数字给我带来了一些麻烦。有人可以帮我安排even 号码吗?

基本上,我将odd数字排列在数组的左侧,并在开头有oddPos = 0even 数字在右侧,定位从数组的最末端开始evenPos = myArray.length - 1

public class EvenOddArray {

    public static void main(String[] args){

        int[] myArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};


        int oddPos = 0;
        int evenPos = myArray.length - 1;

        for(int i = 0; i < myArray.length; i++){
            if(myArray[i] % 2 == 0){
                myArray[evenPos] = myArray[i];
                evenPos--;
            }
            else{
                myArray[oddPos] = myArray[i];
                oddPos++;
            }
        }

        for(int i = 0; i < myArray.length; i++){
            System.out.print(myArray[i] + " ");
        }
    }
}

输出:

1 3 5 7 2 4 6 6 4 2 

【问题讨论】:

  • 您正在覆盖尚未处理的输入。要么使用一个新的数组作为输出,要么用一个未处理的位置交换目标位置。
  • @CodesInChaos,您能否解释一下覆盖尚未处理的输入?我不明白那部分
  • 除非您真的需要避免额外分配数组的开销,否则我建议使用单独的数组进行输入和输出。它更易于实现且更易于使用。

标签: java arrays


【解决方案1】:
int current = 0;
int evenPos = myArray.Length - 1;
while (current < evenPos) {
    if (myArray[current] % 2 == 0) {
        swap(myArray, evenPos, current);
        evenPos--;
    } else {
        current++;
    }
}

一个压缩有趣的版本:

for (int curPos=0, evenPos=myArray.length-1; curPos < evenPos;)
    if (myArray[curPos] % 2 == 0)
        swap(myArray, evenPos--, curPos);
    else
        curPos++;

更有趣的版本:

for (int curPos=0, evenPos=myArray.length-1; curPos < evenPos;)
    swap(myArray, curPos, myArray[curPos]%2==0 ? evenPos-- : curPos++);

解释:

当数字是奇数时,您不必交换值。只有你 增加当前计数器。

您也不能将 for 循环计数器用作数组的索引。到 不要错过交换到计数器索引的数字 处理。这是其他答案没有涵盖的错误。

【讨论】:

  • 我会更改结束条件以比较 currentevenPos。一旦超出evenPos,您所做的就是将元素与自身交换。 i 也相当没有意义,所以我会用 while 循环替换 for 循环。类似while(current &lt; evenPos)
  • 我喜欢。更快,更少的代码。编辑它以获得认可:)
  • 不错的解决方案!尽管我制作了您的解决方案的优化版本,但避免交换已经在数组右侧的偶数。 :)
  • 如果是偶数则与自己互换
【解决方案2】:

实际上,您在读取时正在编辑相同的 myArray 数组。那么会发生什么,

在循环的第 6 次迭代中,您将 6 插入到 myArray[7] th 位置。因此,在第 7 次迭代中,当您阅读 myArray[7] 时,它是 6。不是 8。因为,您在上一次迭代中用 6 覆盖了 8。

因此,使用单独的数组来保存结果。希望你明白这一点。

你可以这样做,

    int[] myArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int[] resultArray = new int[myArray.length];
    int oddPos = 0;
    int evenPos = myArray.length - 1;

    for(int i = 0; i < myArray.length; i++){
        if(myArray[i] % 2 == 0){
            resultArray[evenPos] = myArray[i];
            evenPos--;
        }
        else{
            resultArray[oddPos] = myArray[i];
            oddPos++;
        }
    }

【讨论】:

  • 这是一个正确的答案。它是如此清晰。但它不是最快的,它使用更多的内存。比我建议和更新的@CodesInChaos
  • @hasan83 是的,你是对的。但我的意图是通过进行最少的更改而不添加更多逻辑来交换元素来解决这个问题。但我认为在速度方面,这种方法没有什么大问题。
  • 非常感谢..!回报了人情! ;)
【解决方案3】:

让我们看看你的 for 循环的每次迭代会发生什么。

  • 原文:1 2 3 4 5 6 7 8 9 10
  • 第一次迭代:1 2 3 4 5 6 7 8 9 10
  • 第二次迭代:1 2 3 4 5 6 7 8 9 2
  • 第三次迭代:1 3 3 4 5 6 7 8 9 2
  • 第四次迭代:1 3 3 4 5 6 7 8 4 2
  • 第 5 次迭代:1 3 5 4 5 6 7 8 4 2
  • 第 6 次迭代:1 3 5 4 5 6 7 6 4 2
  • 第 7 次迭代:1 3 5 7 5 6 7 6 4 2
  • 第 8 次迭代:1 3 5 7 5 6 6 6 4 2
  • 第 9 次迭代:1 3 5 7 5 4 6 6 4 2
  • 第 10 次迭代:1 3 5 7 2 4 6 6 4 2

如您所见,您正在“就地”修改数组。您正在修改数组而不使用所有值。例如,看 9,它在被访问之前就被覆盖了。所以,你的算法是错误的。

建议:

  • 使用新数组来保存 tibzon 答案中的结果
  • 使用交换而不是覆盖。您必须相应地更新您的算法。我打算提供一个。但 Murenik 已经提供了一个。

【讨论】:

    【解决方案4】:

    这是我的优化版本,与@hasan83 版本相比,它使用了大约一半的交换。

        int n = myArray.length;
        int oddPos = 0;
        int evenPos = n - 1;
        while (true) {
            while (oddPos < n && myArray[oddPos] % 2 == 1) {
                oddPos++;
            }
            while (evenPos >= 0 && myArray[evenPos] % 2 == 0) {
                evenPos--;
            }
            if (oddPos >= evenPos) break;
            swap(myArray, oddPos, evenPos);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-13
      • 2017-07-07
      相关资源
      最近更新 更多