好的我是一个非常初学的java编码器,我正在做一个我被卡住的任务。我需要创建一个通用方法(sort),根据频率对Type数组进行排序,基本上,我采用CountingSort算法并使其成为通用方法。这是我迷失的地方。我似乎无法弄清楚如何做到这一点。
以下是我的说明链接, https://classes.cs.siue.edu/pluginfile.php/7068/mod_assign/intro/150mp08.pdf
代码: 司机类
package mp08;
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Lists array = new Lists();
array.populateLists();
System.out.println("Original Int List: \n");
array.sort(Lists.intList);
System.out.println("Sorted Int List: \n");
}
}
列出类
package mp08;
import java.util.Arrays;
import java.util.Random;
public class Lists {
public static Integer[] intList;
public static Integer[] sortedintList;
public static Integer[] frequency;
public static Character[] charList;
public static Character[] sortedcharList;
public static int MAX_SIZE = 101;
public static int lengthInt;
public static int lengthChar;
public Lists(){
this.intList = new Integer[MAX_SIZE];
this.sortedintList = new Integer[MAX_SIZE];
this.charList = new Character[MAX_SIZE];
this.sortedcharList = new Character[MAX_SIZE];
this.frequency = new Integer[MAX_SIZE];
this.lengthInt = 0;
this.lengthChar = 0;
}
//Makes random integer for populated lists method.
public int randomInt(int min, int max){
Random rand = new Random();
int randomNum = rand.nextInt((max-min)+1)+min;
return randomNum;
}
//Makes random character for populated lists method.
public char randomChar(){
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int N = alphabet.length();
Random rand = new Random();
char randomLet = alphabet.charAt(rand.nextInt(N));
return randomLet;
}
//Populates intList and charList with random values.
public void populateLists(){
for (int i = 0; i < MAX_SIZE; i++) {
intList[i] = randomInt(1,100);
lengthInt++;
}
for (int i = 0; i < MAX_SIZE; i++) {
charList[i] = randomChar();
lengthChar++;
}
}
//Returns sorted array
public Integer[] sorted(){
return intList;
}
public static <T> void sort(T[] array) {
// array to be sorted in, this array is necessary
// when we sort object datatypes, if we don't,
// we can sort directly into the input array
Integer[] aux = new Integer[array.length];
// find the smallest and the largest value
int min = 1;
int max = 101;
// init array of frequencies
int[] counts = new int[max - min + 1];
// init the frequencies
for (int i = 0; i < array.length; i++) {
counts[array[i] - min]++;
}
// recalculate the array - create the array of occurence
counts[0]--;
for (int i = 1; i < counts.length; i++) {
counts[i] = counts[i] + counts[i-1];
}
/*
Sort the array right to the left
1) Look up in the array of occurences the last occurence of the given value
2) Place it into the sorted array
3) Decrement the index of the last occurence of the given value
4) Continue with the previous value of the input array (goto set1),
terminate if all values were already sorted
*/
for (int i = array.length - 1; i >= 0; i--) {
aux[counts[array[i] - min]--] = array[i];
}
}
public static void main(String[] args) {
Integer [] unsorted = {5,3,0,2,4,1,0,5,2,3,1,4};
System.out.println("Before: " + Arrays.toString(unsorted));
Integer [] sorted = sort(unsorted);
System.out.println("After: " + Arrays.toString(sorted));
}
}
我显然还没有完成我的驾驶课程,我很感激我能得到任何帮助!
答案 0 :(得分:1)
任何Comparable
类型都没有通用的方法来获取其序数。有时这些数字根本不存在(例如,String
为Comparable
,但您无法将任何String
映射到整数。我可以提出两个解决方案。
第一个是存储不在数组中的计数,而是存储在TreeMap
而是按需创建新条目(为简洁起见使用Java-8语法):
public static <T extends Comparable<T>> void sort(T[] array) {
Map<T, Integer> counts = new TreeMap<>();
for(T t : array) {
counts.merge(t, 1, Integer::sum);
}
int i=0;
for(Map.Entry<T, Integer> entry : counts.entrySet()) {
for(int j=0; j<entry.getValue(); j++)
array[i++] = entry.getKey();
}
}
public static void main(String[] args) {
Integer[] data = { 5, 3, 0, 2, 4, 1, 0, 5, 2, 3, 1, 4 };
System.out.println("Before: " + Arrays.toString(data));
sort(data);
System.out.println("After: " + Arrays.toString(data));
Character[] chars = { 'A', 'Z', 'B', 'D', 'F' };
System.out.println("Before: " + Arrays.toString(chars));
sort(chars);
System.out.println("After: " + Arrays.toString(chars));
}
这样的解决方案看起来很干净,但可能不是非常优化(尽管它的优点在于它并不关心所有数字是否都是1到100)。
另一种可能的解决方案是创建一些额外的接口,定义给定类型的排序:
public interface Ordering<T> {
int toOrdinal(T obj);
T toObject(int ordinal);
}
public class IntegerOrdering implements Ordering<Integer> {
@Override
public int toOrdinal(Integer obj) {
return obj;
}
@Override
public Integer toObject(int ordinal) {
return ordinal;
}
}
public class CharacterOrdering implements Ordering<Character> {
@Override
public int toOrdinal(Character obj) {
return obj;
}
@Override
public Character toObject(int ordinal) {
return (char)ordinal;
}
}
现在,您可以使排序方法接受排序参数:
public static <T> void sort(T[] array, Ordering<T> ordering) { ... }
每次需要按T
对象获取计数数组索引时,只需调用ordering.toOrdinal(object)
即可。每次需要通过数组索引获取对象时,只需使用ordering.toObject(index)
。所以,例如,而不是
counts[array[i] - min]++;
使用
counts[ordering.toOrdinal(array[i]) - min]++;
并按照以下方式调用排序方法:
sort(characterArray, new CharacterOrdering());
sort(integerArray, new IntegerOrdering());