#java #arrays #sorting #big-o #radix-sort
#java #массивы #сортировка #big-o #сортировка по основанию
Вопрос:
Привет! Я застрял в этой проблеме, когда я должен сортировать многозначные целые числа (с n всего цифр) за O (n) время. Я считаю, что сортировка по основанию — это, скорее всего, правильный путь, но я не уверен, как правильно это сделать. Сначала я попытался выполнить сортировку по выбору, но она не прошла ни один из тестов из тестового кода.
Вот код со всеми тестовыми примерами:
import java.io.*;
import java.util.*;
public class Lab4
{
/**
* Problem: Sort multi-digit integers (with n total digits) in O(n) time.
* (Technically, it is O(n * b) time. However, since our base b = 128 is constant, it is O(n).)
*/
private static void problem(byte[][] arr)
{
// Implement me!
for (int i=0; i<arr.length; i ){ //loop rows?
for(int j = 0; j < arr[i].length; j ){ //loop columns?
}
}
}
// ---------------------------------------------------------------------
// Do not change any of the code below!
private static final int LabNo = 4;
private static final String quarter = "Fall 2020";
private static final Random rng = new Random(654321);
private static boolean testProblem(byte[][] testCase)
{
byte[][] numbersCopy = new byte[testCase.length][];
// Create copy.
for (int i = 0; i < testCase.length; i )
{
numbersCopy[i] = testCase[i].clone();
}
// Sort
problem(testCase);
Arrays.sort(numbersCopy, new numberComparator());
// Compare if both equal
if (testCase.length != numbersCopy.length)
{
return false;
}
for (int i = 0; i < testCase.length; i )
{
if (testCase[i].length != numbersCopy[i].length)
{
return false;
}
for (int j = 0; j < testCase[i].length; j )
{
if (testCase[i][j] != numbersCopy[i][j])
{
return false;
}
}
}
return true;
}
// Very bad way of sorting.
private static class numberComparator implements Comparator<byte[]>
{
@Override
public int compare(byte[] n1, byte[] n2)
{
// Ensure equal length
if (n1.length < n2.length)
{
byte[] tmp = new byte[n2.length];
for (int i = 0; i < n1.length; i )
{
tmp[i] = n1[i];
}
n1 = tmp;
}
if (n1.length > n2.length)
{
byte[] tmp = new byte[n1.length];
for (int i = 0; i < n2.length; i )
{
tmp[i] = n2[i];
}
n2 = tmp;
}
// Compare digit by digit.
for (int i = n1.length - 1; i >=0; i--)
{
if (n1[i] < n2[i]) return -1;
if (n1[i] > n2[i]) return 1;
}
return 0;
}
}
public static void main(String args[])
{
System.out.println("CS 302 -- " quarter " -- Lab " LabNo);
testProblems();
}
private static void testProblems()
{
int noOfLines = 10000;
System.out.println("-- -- -- -- --");
System.out.println(noOfLines " test cases.");
boolean passedAll = true;
for (int i = 1; i <= noOfLines; i )
{
byte[][] testCase = createTestCase(i);
boolean passed = false;
boolean exce = false;
try
{
passed = testProblem(testCase);
}
catch (Exception ex)
{
passed = false;
exce = true;
}
if (!passed)
{
System.out.println("Test " i " failed!" (exce ? " (Exception)" : ""));
passedAll = false;
break;
}
}
if (passedAll)
{
System.out.println("All test passed.");
}
}
private static byte[][] createTestCase(int testNo)
{
int maxSize = Math.min(100, testNo) 5;
int size = rng.nextInt(maxSize) 5;
byte[][] numbers = new byte[size][];
for (int i = 0; i < size; i )
{
int digits = rng.nextInt(maxSize) 1;
numbers[i] = new byte[digits];
for (int j = 0; j < digits - 1; j )
{
numbers[i][j] = (byte)rng.nextInt(128);
}
// Ensures that the most significant digit is not 0.
numbers[i][digits - 1] = (byte)(rng.nextInt(127) 1);
}
return numbers;
}
}
Комментарии:
1. Я не вижу никакого кода для сортировки по
problem()
основанию. Числа сначала сохраняются с наименьшей значащей цифрой, причем первая значащая цифра гарантированно не равна нулю, что может быть причиной сбоя сортировки вашего выбора. Это также поможет с сортировкой по основанию.2. Далее, поскольку числа сначала хранятся с наименьшей значащей «цифрой», тогда обычная сортировка по основанию с наименьшей значащей цифрой будет начинаться с arr[][0], следующий проход по arr[] [1], … . Все, что находится за пределами конца подмассива, будет рассматриваться какцифра == 0.