我有一个包含双值的二维ArrayList:
ArrayList<ArrayList<Double>> data = new ArrayList<ArrayList<Double>>();
与经典数组类似,我想对此矩阵的“cols”进行排序:我想在子ArrayLists中获取具有相同索引的项目,然后对它们进行排序。就像为每列调用Collections.sort()一样...... 按行我的意思是外层和内层是列。
这样做的正确方法是什么? 我想迭代矩阵来反转它然后用Collections.sort()排序每一行?但也许它不是最好的解决方案,因为矩阵大约是400 * 7000。
我不能使用经典数组,因为矩阵的大小是未知的。
感谢您的帮助。
答案 0 :(得分:3)
做这样的事情:
final int COLUMN = 5;
Comparator<ArrayList<Double>> myComparator = new Comparator<ArrayList<Double>>() {
@Override
public int compare(ArrayList<Double> o1, ArrayList<Double> o2) {
return o1.get(COLUMN).compareTo(o2.get(COLUMN));
}
};
Collections.sort(list, myComparator);
将COLUMN设置为您要排序的任何列。
更新
是的,这根本不起作用。
我喜欢ahanin的第二个建议,即制作你自己的List,它包装你原来的List。您还必须包装get()返回的对象,以便变量wrappedList包含列值,wrappedList.get(0)也返回一列值。然后排序可以工作。我想知道你必须实现Collections.sort()在List上工作的最小方法。
最简单的方法就是拿别人的快速排序,让它与你的名单一起使用。
以下是一项实施:http://www.vogella.de/articles/JavaAlgorithmsQuicksort/article.html
答案 1 :(得分:3)
所以这里有一个类似于反转想法的选项,但不是反转整个事情,而是一次构建一个列,对其进行排序,然后丢弃它。
ArrayList<ArrayList<Double>> data = new ArrayList<ArrayList<Double>>();
for(int c=0; c<data.get(0).size(); c++) {
List<Double> col = new ArrayList<Double>();
for( int r=0; r<data.size(); r++ )
col.add( data.get(r).get(c) );
Collections.sort(col);
for( int r=0; r<col.size(); r++ )
data.get(r).set( c, col.get(r) );
}
我怀疑你能否获得更高效的东西,除了可能选择创建你自己的类,它提供表格列的视图作为列表。
答案 2 :(得分:2)
我有两个疯狂的想法:要么实现自己的排序算法,要知道你的倒置矩阵结构,要么写一个Collection的实现,它将包装你的结构并表示列,以后可以用作参数到Collections.sort()。使用ArrayList,这应该相当快。
答案 3 :(得分:2)
这是将数据转换为对象数组的这种情况的方法。将列更改为您喜欢的任何内容。
final int column = 3;
ArrayList<ArrayList<Double>> data = new ArrayList<ArrayList<Double>>();
// Convert data into an object array
Object [] temp = data.toArray();
Arrays.sort(temp, new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
// Get inner arrays to be compared by type-casting
ArrayList<Double> temp1 = (ArrayList<Double>) o1;
ArrayList<Double> temp2 = (ArrayList<Double>) o2;
// Then compare those inner arrays' indexes
return temp1.get(column).compareTo(temp2.get(column));
}
});
// Clear the old one and add the ordered list into
data.clear();
for(Object o: temp)
{
data.add((ArrayList<Double>) o);
}
答案 4 :(得分:0)
我想如果存储不是问题,你可以在ArrayList中使用SortedMap。这样您就不必担心对元素进行排序。
ArrayList<SortedMap<Double,byte>> data;
答案 5 :(得分:0)
不确定我是否正确理解了您的Q,但这会对所有“列”进行排序(假设外层是行,内层是列):
final ArrayList<ArrayList<Double>> data = new ArrayList<ArrayList<Double>>();
//...
final Integer[] rows = new Integer[data.size()];
for(int i=0;i<rows.length;i++)
rows[i]=i;
int cols = data.get(0).size();
for(int c=0;c<cols;c++)
{
final int colidx = c;
Arrays.sort(rows,new Comparator<Integer>(){
@Override
public int compare(Integer arg0,
Integer arg1) {
return data.get(arg0).get(colidx).compareTo(data.get(arg1).get(colidx));
}});
for(int i=0;i<rows.length;i++)
data.get(i).add(colidx+1,data.get(rows[i]).get(colidx));
for(int i=0;i<rows.length;i++)
data.get(i).remove(colidx);
}
答案 6 :(得分:0)
您必须访问所有元素才能在任何情况下对它们进行排序。所以你能做的就是这个。
int temp[] = new temp[col.length];
int x = 0;
while(x < row.length)
{
for(int i = 0; i<col.length; i++)
{
temp[i] = mat[x][i];
}
sort(temp);
for(int i = 0; i<col.length; i++)
{
mat[x][i] = temp[i];
}
x++;
}
此处的运行时间为O(n^2logn)
,但由于您只需要400次双打,不会花费太多时间。因为您必须至少访问矩阵中的每个元素一次,所以不能低于O(n^2)