【问题标题】:Sorting arrays in JavaJava中的数组排序
【发布时间】:2011-02-28 20:11:59
【问题描述】:

用Java写一个静态方法:

public static void sortByFour (int[] arr)

接收一个包含非负数(零或正数)的数组作为参数,并按以下方式对数组进行排序:

  • 所有能被四整除的数字都会出现在数组的开头。

  • 数组中除以 4 余数为 1 的所有数字都将出现在它们之后。

  • 数组中除以 4 余数为 2 的所有数字都将出现在它们之后。

  • 将出现在数组末尾的所有余数(除以 4 余数为 3 的数)。

(每组数字的顺序无关紧要。)

方法必须尽可能高效。

以下是我写的,可惜效果不好……:(

public static void swap( int[] arr, int left, int right )
{
    int temp = arr[left];
    arr[left] = arr[right];
    arr[right] = temp;
}

public static void sortByFour( int[] arr )
{
    int left = 0;
    int right = ( arr.length - 1 );
    int mid = ( arr.length / 2 );
    while ( left < right )
    {
        if ( ( arr[left] % 4 ) > ( arr[right] % 4 ) )
        {
            swap( arr, left, right );
            right--;
        }
        if ( ( arr[left] % 4 ) == ( arr[right] % 4 ) )
            left++;
        else
            left++;
    }
}

如何修复或重写我的代码以使其正常运行?

【问题讨论】:

  • @VeeArr 好吧,很明显。但这是个好问题。
  • 正确,但我试图解决它但它不起作用,这就是我寻求帮助的原因。
  • 你为什么使用那个代码?我的意思是,你试图在那里实现的逻辑是什么?
  • -1 要求让其他人做你的作业。 Polygenlubricants 和 GEShafer 已经为您提供了很好的推动力。
  • -1 “帮我找出问题所在”和“帮我解决”(即使是“请”)是完全不同的东西。

标签: java arrays sorting modulo


【解决方案1】:

我将在伪代码中为您执行此操作,但在代码中执行此操作将为您提供答案,这是家庭作业,因此您可以自己完成工作。 =P

以下是不使用列表的方法。此示例受要求限制,但在您编写代码后即可使用。

int bucketSize = (arr.length() / 4) + 1;

int bucket1[bucketSize];
int bucket2[bucketSize];
int bucket3[bucketSize];
int bucket4[bucketSize];

for (int i=0; i<arr.length; i++) {
    if ((arr[i] % 4) == 0)
        put arr[i] in bucket 1
    else if ((arr[i] % 4) == 1)
        put arr[i] in bucket 2
    else if ((arr[i] % 4) == 2)
        put arr[i] in bucket 3
    else
        put arr[i] in bucket 4
}

for (int i=0; i<4; i++) {
    this will go for each bucket
    for (int j=0; j<bucketSize; j++) {
        do sort of your choice here to sort the given bucket
        the sort you used in your code will do fine (the swapping)
    }
}

然后按照各自的顺序连接四个存储桶以获得最终结果

【讨论】:

  • 我还问过我的老师我是否可以使用辅助数组,她说这不是想法......必须有比这更简单和高效的东西。
  • 首先效率取决于你如何编码,这只是伪代码。其次,真正获得比这更有效的唯一方法是使用真正的桶排序作为上面发布的多基因润滑剂,但不允许使用列表。所以我的建议是,如果你可以编写自己的列表类(相当简单)但那仍然使用列表类,或者用数组替换列表(正如我向你展示的那样)
  • 不使用数组,而是使用整数系统来索引您在数组中的位置并执行相同的操作...
  • 你能写出来让我明白吗?
【解决方案2】:

你可以这样解决问题:

  1. 选择您希望使用的排序算法。看起来您正在尝试编程Quicksort,但您也可以使用Bubble Sort
  2. 确定算法中输入数组中两个值进行比较的点。例如,在维基百科文章中冒泡排序的伪代码中,唯一的比较是 if A[i] &gt; A[i+1] then... 这一行。
  3. 找出一种比较两个数字的方法,使得除以 4 时余数为 0 的数字 s 被认为小于除以时余数为 1 的数字 t 4.用你的comparator计算替换算法的比较操作(例如if myIsGreater(A[i], A[i+1]) then...)。

对于第 3 步,通过考虑模运算符,您肯定走在正确的轨道上。

【讨论】:

  • +1 余数排序的要求绝对不是这个问题的重点,比较器会很好地为你处理。
【解决方案3】:

我将重申丹尼尔所说的:您可以选择排序算法。如果需要,请使用迄今为止您在课堂上学习过的最有效的一种。但是,当您在算法中比较两个项目时,请改为比较它们的值 mod 4。所以像if A[i] &gt; A[j] 这样的东西变成了if A[i] % 4 &gt; if A[j] % 4。然后,您继续执行算法指定您对该数组元素执行的任何操作。交换它,冒泡它,退回它,无论需要什么。

关于您发布的代码,我认为它不适合快速修复。它应该使用哪种算法? mid 是干什么用的?我认为一旦你知道你打算使用哪种算法,并弄清楚哪一行代码包含比较,你将能够快速查看并编写解决方案。

一般来说,对于这类事情,如果您在担心效率之前专注于获得可行的解决方案会有所帮助。我第一次不得不做这样的问题时使用了选择排序。我建议先尝试一下,然后使用获得的经验进行合并排序,即 O(n log n)。

【讨论】:

    【解决方案4】:

    线性时间解

    最渐近有效的方法是使用bucket sort

    • 您有 4 个存储桶,每个存储桶用于模 4 的同余类数字。
    • 扫描数组中的数字一次
      • 将每个数字放入正确的桶中
    • 然后构造输出数组
      • 首先放入桶 0 中的所有数字,然后放入桶 1 中的所有数字,然后是桶 2,然后是桶 3

    因此,这会对O(N) 中的数字进行排序,这是最优的。这里的关键是,通过对数字模 4 进行排序,基本上只有 4 个数字需要排序:0、1、2、3。


    List 的说明性解决方案

    为了清楚起见,这里使用List 和for-each 实现了上述算法(用于一般模M)。忽略 unchecked cast 警告,只专注于理解算法。

    import java.util.*;
    
    public class BucketModulo {
        public static void main(String[] args) {
            final int M = 4;
            List<Integer> nums = Arrays.asList(13,7,42,1,6,8,1,4,9,12,11,5);
            List<Integer>[] buckets = (List<Integer>[]) new List[M];
            for (int i = 0; i < M; i++) {
                buckets[i] = new ArrayList<Integer>();
            }
            for (int num : nums) {
                buckets[num % M].add(num);
            }
            nums = new ArrayList<Integer>();
            for (List<Integer> bucket : buckets) {
                nums.addAll(bucket);
            }
            System.out.println(nums);
            // prints "[8, 4, 12, 13, 1, 1, 9, 5, 42, 6, 7, 11]"
        }
    }
    

    一旦你完全理解了算法,把它翻译成使用数组(如果你必须的话)就很简单了。

    另见


    关于%的特别说明

    数字非负的规定很重要,因为% 不是数学定义的 运算符;它是 remainder 运算符。

    System.out.println(-1 % 2); // prints "-1"
    

    参考文献

    【讨论】:

      【解决方案5】:

      阅读本页。 http://en.wikipedia.org/wiki/Sorting_algorithm#Summaries_of_popular_sorting_algorithms

      从长远来看,这应该对您有最大的帮助。也挺好玩的!

      【讨论】:

      • 我读过它...实际上对我没有帮助。如果有人可以通过修复我的代码来帮助我,我将不胜感激。我已经被这个问题困了好几个小时了。
      • 如果我们只是在您不了解为什么它不起作用的情况下修复您的代码,它对您没有帮助。
      • 我知道,但是当我有固定的代码时,我会检查它并检查它为什么以前不起作用。向我解释为什么它不能正常工作会对我有更大的帮助。
      • @user:您的代码不起作用,因为它是错误的。就这么简单。没有简单的解决办法。
      • 就像:嘿,我有这个打印报告系统,这是我目前拥有的 System.out.println("Hell world") 请修复它,让我完成剩下的工作。
      【解决方案6】:

      这是一种类似于 Java 的方式...

          Arrays.sort(arr,new Comparator<Integer>(){
            public int compare(Integer a,Integer b)
            {
              return (a % 4) - (b % 4);
            }
          });
      

      【讨论】:

      猜你喜欢
      • 2011-06-09
      • 1970-01-01
      • 2023-04-02
      • 2011-05-01
      • 2021-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多