2013-05-31 106 views
0

我有車輛列表。我想根據製造商對這些車輛進行分類。訂單被定義在另一個數組中。根據關鍵字進行Java排序

此代碼與兩個品牌「本田」和「起亞」的排列很好。在起亞之上,本田和本田之上的其他車型排在前列。是否有可能使它的大小變化的數組通用。如果陣列是「雪佛蘭」,「道奇」,「福特」呢?

感謝

//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

沒有測試它,但你可以嘗試:

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; 
} 
+0

它沒有爲第一個使用陣列工作。兩輛本田之間發現閃避:P 無論如何,我會繼續努力吧! – David

+2

是否需要「toLowerCase」調用?由於調用'indexOf('honda')'會產生'-1',這些調用正在破壞算法,因此我的解決方案不起作用。無論如何,我希望你得到了我想要做的事情(使用'makes'數組的索引來排序'Vehicle')。順便說一句,作爲起亞的擁有者,我認爲你應該把他們放在第一位! :P – orique

+1

+1,確實,「toLowerCase」是這裏的問題。如果區分大小寫不重要,那麼只需手動循環「生成」-array並使用String-class的「equalsIgnoreCase」函數即可。 – ultddave

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 - 奔馳
車輛:乙 - 本田
車輛:電子 - 本田
車輛:H - 本田
車輛:g - 將保時捷
車輛:C - 馬自達

編輯:這需要一個版本只是把所有的車輛從沒有出現在「規則」的ArrayList品牌,在最後:

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 - 馬自達
車輛:A - 起亞
車輛:d - 起亞
車輛:I - 起亞
車輛:F - 奔馳
Vehicle:H - 本田
Vehicle:G - 保時捷
Vehicle:E - 本田
車輛:乙 - 本田
未分類的車輛:4

正如你所看到的,最後4輛車是無序因爲本田和保時捷都沒有出現在列表中。

+0

是我還是我得到一個java.lang.ArrayIndexOutOfBoundsException:-1當我嘗試這種技術? – David

+1

啊,我知道了,你的規則數組必須包含所有可能的結果,否則indexOf將返回-1,從而將計數放在第一個位置。 – David

+0

Exacly,我編輯我的帖子與第二個版本,其中考慮到名單不一定包含所有制造商。對於有類似問題的其他人可能會派上用場。 – ultddave

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; 
    } 
}); 
相關問題