Java 中的数组排序

发布于 2024-09-05 08:47:34 字数 1039 浏览 4 评论 0原文

用 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++;
    }
}

我如何修复或重写我的代码以便它能正常工作?

Write a static method in Java:

public static void sortByFour (int[] arr)

That receives as a parameter an array full of non-negative numbers (zero or positive) and sorts the array in the following way:

  • In the beginning of the array all the numbers that are divisible by four will appear.

  • After them all the numbers in the array that divide by 4 with a remainder of 1 will appear.

  • After them all the numbers in the array that divide by 4 with a remainder of 2 will appear.

  • In the end of the array all the rest numbers (those which divide by 4 with the remainder 3) will appear.

(The order of the numbers in each group doesn't matter.)

The method must be as efficient as possible.

The following is what I wrote, but unfortunately it doesn't work well... :(

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++;
    }
}

How do I fix or rewrite my code so that it will work well?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

月光色 2024-09-12 08:47:34

我将在伪代码中为您执行此操作,但在代码中执行此操作将为您提供答案,这是家庭作业,因此您可以完成自己的工作。 =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)
    }
}

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

I will do this in psuedocode for you but doing it in code would be giving you the answer and this is homework so you can do your own work. =P

Here is how to do it without lists. This example is restricted based on the requirements but will work once you code it.

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)
    }
}

then concatenate the four buckets in their respective order to get your end result

够钟 2024-09-12 08:47:34

您可以这样解决这个问题:

  1. 选择您想要使用的排序算法。看起来您正在尝试编程 Quicksort,但您也可以使用 冒泡排序
  2. 识别算法中比较输入数组中的两个值的点。例如,在维基百科文章中的冒泡排序伪代码中,唯一的比较是行 if A[i] > A[i+1] 然后...
  3. 找出一种比较两个数字的方法,以便除以 4 时余数为 0 的数字 s 被认为小于除以 4 时余数为 1 的数字 t。替换算法与比较器 计算(例如 if myIsGreater(A[i], A[i+1]) then...)。

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

You can attack the problem like this:

  1. Select a sorting algorithm that you wish to use. It looks like you are trying to program Quicksort, but you could also use Bubble Sort.
  2. Identify the point(s) of the algorithm where two values from the input array are being compared. For example, in the pseudocode for Bubble Sort on the Wikipedia article, the only comparison is the line if A[i] > A[i+1] then....
  3. Figure out a way to compare two numbers so that a number s having remainder 0 when divided by 4 is considered less than a number t having remainder 1 when divided by 4. Replace the comparison operations of the algorithm with your comparator calculation (e.g. if myIsGreater(A[i], A[i+1]) then...).

For step 3, you are definitely on the right track by considering the modulus operator.

画中仙 2024-09-12 08:47:34

我会重申丹尼尔所说的话:你可以选择排序算法。如果需要的话,请使用迄今为止在课程中介绍过的最有效的方法。但是,当您在算法中比较两个项目时,请比较它们的值 mod 4。所以类似于 if A[i] >如果 A[i] % 4 > 则 A[j] 变为 如果 A[j] % 4 。然后,您继续执行算法指定的对该数组元素执行的操作。交换、冒泡、退货,无论需要什么。

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

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

I will reiterate what Daniel said: you have your choice of sorting algorithm. Use the most efficient one that you've covered in the class so far, if that is the requirement. But when you get to the point in your algorithm where two items are being compared, compare their value mod 4 instead. So something like if A[i] > A[j] becomes if A[i] % 4 > if A[j] % 4. Then you continue doing whatever the algorithm specifies that you do with that array element. Swap it, bubble it up, return it, whatever is called for.

Regarding the code that you posted, I don't think that it lends itself to a quick fix. Which algorithm is it supposed to be using? What is mid there for? I think that once you know which algorithm you intend to use, and figure out which line of code contains the comparison, you will be able to quickly see and code a solution.

In general, with these sorts of things, it can help if you focus on getting a working solution before you worry about efficiency. I used selection sort the first time I had to do a problem like this. I would recommend trying that first, and then using the experience gained to do one with merge sort, which is O(n log n).

会傲 2024-09-12 08:47:34

线性时间解决方案

最渐进有效的方法是使用桶排序

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

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


List 的说明性解决方案

下面是上述算法的实现(对于一般模 M) 使用 为了清楚起见,List 和 for-each 。忽略未经检查的强制转换警告,只专注于理解算法。

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]"
    }
}

一旦您完全理解了该算法,将其转换为使用数组(如果必须的话)就很简单了。

另请参见


关于%的特别说明

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

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

参考文献

A linear-time solution

The most asymptotically efficient way to do this would be to use bucket sort.

  • You have 4 buckets, one for each of the congruency class of numbers modulo 4.
  • Scan the numbers in the array once
    • Put each number in the right bucket
  • Then construct the output array
    • Put all numbers from bucket 0 first, then all from bucket 1, then bucket 2, then bucket 3

Thus, this sorts the numbers in O(N), which is optimal. The key here is that by sorting on numbers modulo 4, there are essentially only 4 numbers to sort: 0, 1, 2, 3.


An illustrative solution with List

Here's an implementation of the above algorithm (for general modulo M) using List and for-each for clarity. Ignore the unchecked cast warning, just concentrate on understanding the algorithm.

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]"
    }
}

Once you fully understand the algorithm, translating this to use arrays (if you must) is trivial.

See also


A special note on %

The stipulation that numbers are non-negative is significant, because % is NOT the modulo operator as it's mathematically defined; it's the remainder operator.

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

References

伤痕我心 2024-09-12 08:47:34

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

这应该有帮助从长远来看你是最好的。也挺好玩的!

Read this page. http://en.wikipedia.org/wiki/Sorting_algorithm#Summaries_of_popular_sorting_algorithms

That should help you best in the long run. It's also pretty fun!

总以为 2024-09-12 08:47:34

这是一种 Java 式的方式......

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

Here's a Java-ish way...

    Arrays.sort(arr,new Comparator<Integer>(){
      public int compare(Integer a,Integer b)
      {
        return (a % 4) - (b % 4);
      }
    });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文