0

我有一个车辆清单。我想根据品牌对这些车辆进行分类。顺序在另一个数组中定义。

此代码与两个品牌“Honda”和“Kia”的数组很好地分类。这与本田在起亚之上的排序在其他之上。是否有可能使其对大小会发生变化的数组通用。如果阵列是“雪佛兰”、“道奇”、“福特”怎么办?

谢谢

//This sorts Honda first, Kia second, and others after.
final String[] makes = new String[]{"Honda","Kia"};
Collections.sort(vehicles, new Comparator<Vehicle>() {
    @Override
    public int compare(Vehicle o1, Vehicle o2) {
        String makeObj1 = o1.getModel().getMakeName().toLowerCase();
        String makeObj2 = o2.getModel().getMakeName().toLowerCase();
        //honda first
        if (makeObj1.equals(makes[0].toLowerCase())) {
            if (makeObj2.equals(makes[0].toLowerCase())) {
                return 0;//honda = honda
            }
            if (makeObj2.equals(makes[1].toLowerCase())) {
                return -1;//honda > kia
            } else {
                return -1;//honda > others
            }
        }
        //kia first
        if (makeObj1.equals(makes[1].toLowerCase())) {
            if (makeObj2.equals(makes[0].toLowerCase())) {
                return 1;//kia < honda
            }
            if (makeObj2.equals(makes[1].toLowerCase())) {
                return 0;//kia = kia
            } else {
                return -1;//kia > others
            }
        }
        //honda second
        if (makeObj2.equals(makes[0].toLowerCase())) {
            if (makeObj1.equals(makes[1].toLowerCase())) {
                return 1;//kia < honda
            } else {
                return 1;//other < honda
            }
        }
        //kia second
        if (makeObj2.equals(makes[1].toLowerCase())) {
            return 1;//others < kia
        }
        return 0;//all cases should been covered
    }
});
4

3 回答 3

4

没有测试它,但你可以尝试:

public int compare(Vehicle o1, Vehicle o2) {

    String makeObj1 = o1.getModel().getMakeName().toLowerCase();
    String makeObj2 = o2.getModel().getMakeName().toLowerCase();

    int indexMake1 = Arrays.asList(makes).indexOf(makeObj1);
    int indexMake2 = Arrays.asList(makes).indexOf(makeObj2);

    if (indexMake1 == -1) indexMake1 = makes.length;
    if (indexMake2 == -1) indexMake2 = makes.length;

    return indexMake1 - indexMake2;
}
于 2013-05-31T13:38:40.927 回答
1

一个可能的解决方案(如果您不想使用 Collections.sort)可以使用关键索引计数,其中汽车的品牌是关键(存储桶)。

参考:http ://www.cs.princeton.edu/courses/archive/spr13/cos226/demo/51DemoKeyIndexedCounting.pdf

快速实现示例:

public class Vehicle {
    private String m_name;
    private String m_brand;

    public Vehicle(String name, String brand)  {
        m_name = name;
        m_brand = brand;
    }

    public String getBrand() {
        return m_brand;
    }

    @Override
    public String toString()  {
        return "Vehicle: " + m_name + " - " + m_brand;
    }
}


public class KeyIndexCounting 
{
    public void sort(ArrayList<Vehicle> input, ArrayList<String> rules)
    {
        int N = input.size();
        int R = rules.size();
        int[] count = new int[R + 1];
        Vehicle[] aux = new Vehicle[N];

        for(int i = 0; i < N; ++i)
        {
            String brand = input.get(i).getBrand();
            ++count[rules.indexOf(brand) + 1];
        }

        for(int r = 0; r < R; ++r)
            count[r + 1] += count[r];

        for(int i = 0; i < N; ++i)
        {
            String brand = input.get(i).getBrand();
            aux[count[rules.indexOf(brand)]++] = input.get(i);
        }

        for(int i = 0; i < N; ++i)
            System.out.println(aux[i]); // Print sorted output array
    }
}

用法:

    KeyIndexCounting key = new KeyIndexCounting();

    ArrayList<Vehicle> v = new ArrayList<>();
    v.add(new Vehicle("A", "Kia"));
    v.add(new Vehicle("B", "Honda"));
    v.add(new Vehicle("C", "Mazda"));
    v.add(new Vehicle("D", "Kia"));
    v.add(new Vehicle("E", "Honda"));
    v.add(new Vehicle("F", "Mercedes"));
    v.add(new Vehicle("G", "Porsche"));
    v.add(new Vehicle("H", "Honda"));
    v.add(new Vehicle("I", "Kia"));

    ArrayList<String> b = new ArrayList<>();
    b.add("Kia");
    b.add("Mercedes");
    b.add("Honda");
    b.add("Porsche");
    b.add("Mazda");

    key.sort(v, b);

输出:

车辆:A - 起亚
车辆:D - 起亚
车辆:I - 起亚
车辆:F - 梅赛德斯
车辆:B - 本田
车辆:E - 本田
车辆:H - 本田
车辆:G - 保时捷
车辆:C - 马自达

编辑:一个版本只需要将所有未出现在“规则”数组列表中的品牌车辆放在最后:

    int N = input.size();
    int R = rules.size();
    int[] count = new int[R + 1];
    Vehicle[] aux = new Vehicle[N];

    int others = aux.length - 1;

    for(int i = 0; i < N; ++i)
    {
        String brand = input.get(i).getBrand();
        int index = rules.indexOf(brand);
        if(index != -1)
            ++count[index + 1];
        else
            aux[others--] = input.get(i);
    }

    for(int r = 0; r < R; ++r)
        count[r + 1] += count[r];

    for(int i = 0; i < N; ++i)
    {
        String brand = input.get(i).getBrand();
        int index = rules.indexOf(brand);
        if(index != -1)
            aux[count[index]++] = input.get(i);
    }

    for(int i =0; i < N; ++i)
        System.out.println(aux[i]);

    System.out.println("Unsorted vehicles: " + others);

用法:

    KeyIndexCounting sort = new KeyIndexCounting();

    ArrayList<Vehicle> v = new ArrayList<>();
    v.add(new Vehicle("A", "Kia"));
    v.add(new Vehicle("B", "Honda"));
    v.add(new Vehicle("C", "Mazda"));
    v.add(new Vehicle("D", "Kia"));
    v.add(new Vehicle("E", "Honda"));
    v.add(new Vehicle("F", "Mercedes"));
    v.add(new Vehicle("G", "Porsche"));
    v.add(new Vehicle("H", "Honda"));
    v.add(new Vehicle("I", "Kia"));

    ArrayList<String> b = new ArrayList<>();
    b.add("Mazda");
    b.add("Kia");
    b.add("Mercedes");

输出:

车辆:C - Mazda
车辆:A - Kia
车辆:D - Kia
车辆:I - Kia
车辆:F - Mercedes
车辆:H - Honda
车辆:G - Porsche
车辆:E - Honda
车辆:B - Honda
未分类车辆:4

如您所见,最后 4 辆车未排序,因为本田和保时捷均未出现在列表中。

于 2013-05-31T14:00:55.037 回答
0

我做了这项工作,它很简单,但我先看看@ultddave。

这是我的代码:

Collections.sort(vehicles, new Comparator<Vehicle>() {
    @Override
    public int compare(Vehicle o1, Vehicle o2) {
        if (o1 == null && o2 == null) {
            return 0;
        }
        if (o1 == null) {
            return -1;
        }
        if (o2 == null) {
            return 1;
        }
        //honda first

        for (int i = 0; i < makes.length; i++) {
            for (int j = 0; j < makes.length; j++) {
                String str1 = o1.getModel().getMakeName().toLowerCase();
                String str2 = o2.getModel().getMakeName().toLowerCase();
                if (i < j) {
                    if (str1.equals(makes[i].toLowerCase())) {
                        return -1;
                    }
                    if (str2.equals(makes[i].toLowerCase())) {
                        return 1;
                    }
                } else if (i == j) {
                    if (str1.equals(makes[i].toLowerCase()) && str2.equals(makes[j].toLowerCase())) {
                        return 0;
                    }
                } else {
                    if (str1.equals(makes[i].toLowerCase())) {
                        return 1;
                    }
                    if (str2.equals(makes[i].toLowerCase())) {
                        return -1;
                    }
                }
            }
        }
        return 0;
    }
});
于 2013-05-31T14:23:32.010 回答