【问题标题】:Radix sort with counting sort incorrectly sorts letters converted to binary带有计数排序的基数排序错误地对转换为二进制的字母进行排序
【发布时间】:2022-12-11 14:44:28
【问题描述】:

我无法理解为什么当我将输入转换为二进制时,我的带有计数排序的基数排序代码不能正确地对输入进行排序。我基本上对表示为十进制的字母使用相同的代码,它们工作得很好,但在这里它甚至还差得远。

下面是参与二进制基数排序的代码:

    static String[] countSort(String[] input, int position)
    {
        int[] count = new int[2];
        int n = input.length;

        char temp;
        for (String value : input) {
            temp = value.charAt(value.length()-1 - position);

            count[temp-'0']++;
        }

        for (int i = 1; i < 2; i++) {
            count[i] = count[i] + count[i - 1];
        }

        String[] output = new String[n];
        for (int i = n - 1; i >= 0; i--) {
            temp = input[i].charAt(input[i].length()-1 - position);

            output[count[temp-'0']-1] = input[i];
            count[temp-'0']--;
        }

        return output;
    }

    public static String[] radixSortBinary(String str, int stringLength) {

        //convert letters to binary
        char[] charArr = str.toCharArray();
        String[] array = new String[charArr.length];
        for (int i=0; i<charArr.length; i++)
            array[i] = Integer.toBinaryString(charArr[i]);

        System.out.println("Binary input:" + Arrays.toString(array));

        //iterate over each character position (starting from the least significant)
        for (int i = stringLength-1; i >= 0; --i) {
            array = countSort(array, i);
        }


        System.out.println("Binary output:" + Arrays.toString(array));

        //convert back to letters
        StringBuilder sb = new StringBuilder();
        for (int i=0; i<array.length; i++) {
            Arrays.stream(array[i].split("(?<=\\G.{7})")).forEach(s -> sb.append((char) Integer.parseInt(s, 2)));
            array[i] = sb.toString();
            sb.setLength(0);
        }

        return array;
    }

    public static void main(String[] args) {

    Scanner scan = new Scanner(System.in);
    String input2 = scan.next();

    String[] result = radixSortBinary(input2, 7);
    System.out.println("Output:" + Arrays.toString(result));
}

安慰:

input: 
ababababababa
Binary input:[1100001, 1100010, 1100001, 1100010, 1100001, 1100010, 1100001, 1100010, 1100001, 1100010, 1100001, 1100010, 1100001]
Binary output:[1100001, 1100010, 1100001, 1100010, 1100001, 1100010, 1100001, 1100010, 1100001, 1100010, 1100001, 1100010, 1100001]
Output:[a, b, a, b, a, b, a, b, a, b, a, b, a]

另一种情况:

input: 
abcdefgdftglkgfdj
Binary input:[1100001, 1100010, 1100011, 1100100, 1100101, 1100110, 1100111, 1100100, 1100110, 1110100, 1100111, 1101100, 1101011, 1100111, 1100110, 1100100, 1101010]
Binary output:[1100100, 1100100, 1100100, 1110100, 1101100, 1100010, 1101010, 1100110, 1100110, 1100110, 1100001, 1100101, 1100011, 1101011, 1100111, 1100111, 1100111]
Output:[d, d, d, t, l, b, j, f, f, f, a, e, c, k, g, g, g]

任何帮助将不胜感激!

【问题讨论】:

  • 我运行了你的代码,在第一种情况下得到了不同的结果(“ababababababa”),它也没有排序,但奇怪的是它是不同的
  • @harold 是的,我遇到过这样的情况,结果只有一个两个 a 彼此相邻。正如我所说,我使用相同的代码对字符串数组进行排序,除了我减去 temp-'a' 而不是 temp-'0',具有不同的计数数组大小,这里我不将字符串转换为小写。这就是全部的区别

标签: java sorting binary radix-sort counting-sort


【解决方案1】:

错误在这里:

//iterate over each character position (starting from the least significant)
for (int i = stringLength-1; i >= 0; --i) {
    array = countSort(array, i);
}

该代码没有按照评论所说的那样做。实际上,这会从最重要的字符开始遍历每个字符位置。有诸如 MSB-radix 之类的东西,但那是不同的。

反转那个循环使它对我来说正常工作。

顺便说一句,您应该确保所有二进制字符串的长度相同,必要时用前导零填充。直接处理字符整数表示的位不需要将其作为显式步骤。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-02
    • 2018-05-04
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 2014-04-13
    • 1970-01-01
    相关资源
    最近更新 更多