找到运营商的最低价格表

时间:2013-01-23 22:57:19

标签: java binary-search comparator

Country Code List=   92,  445,  445,  966,   92,  445,  966,  966, 92
Price List =       0.99, 0.91, 0.92, 0.97, 0.93, 0.97, 0.92, 0.97, 1.0
Operator List=        A,    C,    A,    B,    C,    B,    A,    C,  A

当用户输入国家代码时,我应该找到最低价格表和相应的运营商。  国家/地区代码数据可以重复。它不是唯一的。例如因为我们不知道国家代码:92属于哪个运营商,国家代码列表中的运营商A,B或C可以存在92个。

我写了下面的代码。但它有一个问题,

问题:我能够对CountryCode进行排序,但是以下代码中的binarySearch无法相应地找出最小价格表。它总是给我随机值,这不是最低价格。将对以下代码的改进表示赞赏。

class Dog implements Comparator<Dog>, Comparable<Dog>{
   private int CountryCode; 
   private double Price;
   private String Operator;
   Dog(){
   }

   Dog( int c, double p, String o){
       CountryCode= c;
       Price= p;
       Operator=o;
   }

   public int getCountryCode(){
      return CountryCode;
   }

   public double getPrice(){
      return Price;
   }
   public String getOperator(){
          return Operator;
       }


   // Overriding the compareTo method
   public int compareTo(Dog d){

       return CountryCode- d.getCountryCode();
   }


   // Overriding the compare method to sort the age 
   public int compare(Dog d, Dog d1){
       return d.CountryCode - d1.CountryCode;     
   }




}


public class Ser {                          
/**                                     
 * @param args
 */
public static void main(String[] args) {
    // Takes a list o Dog objects
    ArrayList <Dog> list1 = new ArrayList<Dog>();

      list1.add(new Dog(92, 0.99 , "A"));
      list1.add(new Dog(445, 0.91 , "C"));
      list1.add(new Dog(445, 0.92 , "A"));
      list1.add(new Dog(966, 0.97 , "B"));
      list1.add(new Dog(92, 0.93 , "C"));
      list1.add(new Dog(445, 0.97 , "B"));
      list1.add(new Dog(966, 0.92, "A"));
      list1.add(new Dog(966,0.97, "C"));
      list1.add(new Dog(92,1.0, "A"));
      // Sorts the array list using comparator

      Collections.sort(list1, new Dog());

      for(Dog a: list1)//printing the sorted list of ages
          System.out.println(a.getCountryCode() +"  : "+
         a.getOperator()+"  : "+ a.getPrice());

     int index=  Collections.binarySearch(list1, new Dog ( 92,null,null));

      if (index>=0)
      System.out.println( list1.get(index).getOperator()+ " " + list1.get(index).getPrice());
      else
          System.out.println("No operator is availible");

}}

2 个答案:

答案 0 :(得分:3)

您从未按价格对列表进行排序,因此您不应期望获得最低价格。

首先,列表按国家/地区代码的顺序排序。

每个国家/地区代码中的价格顺序是随机的,具体取决于:

  • 原始列表已排序的未指定顺序...
  • 二元搜索使用正确的国家/地区代码找到的第一个值....

rolfl

编辑:

你问什么是正确的方法......有三种想法:

  • 使用Kent建议的预构建层次结构,对两个维度(国家/价格)的数据进行排序,然后您可以快速提取所需的数据。
  • 将比较器更改为按国家/地区和价格排序,然后扫描列表(而不是二进制搜索),并返回带有正确国家/地区的第一个项目。
  • 更改比较器以按国家/地区和价格排序,然后使用二进制搜索搜索国家/地区(二进制搜索将返回具有该国家/地区的任何位置),然后向后扫描以查找最低价格。

答案 1 :(得分:1)

如果您的要求是:if find multiple Dogs with same countryCode, return the Dog with lowest price.

我建议您更改列表设计。

您可以Map<Integer, List<Dog>>密钥为countryCode。当然,Map<Integer, TreeSet<Dog>>或番石榴MultiMap<Integer, Dog>也可以。

如果countryCodes确实是国家/地区,则您的地图不会超过300个条目。

然后您可以保存O(logn)二进制搜索。并使用O(1)获取同一countryCode的狗的列表/集合/ TreeSet。

然后,如果没有排序,你可以按价格排序(O(nlogn))Dog的集合。(你应该推出类似的界面并推测方法)并获得第一个/最后一个狗。取决于您的排序顺序。您还可以将收集分类以供以后使用。如果它只是一次性工作,你甚至可以通过狗收集并以最低的价格获得狗。 O(n)

如果您希望操作员也进行排序,请将该信息写入compareTo方法实现中。

如果它像你说的那样,只有数千种元素,你不必太在乎性能,除非最小/最大搜索次数要多少次。如果在这种情况下,当您填写地图时,或者即使使用您的方法,列表,也可以为countryCode的最小/最大价格构建另一个地图。这将节省大量时间。显然,如果你缓存最低/最高价格,你必须保持它,如果地图(或你的列表)被更改,或一些狗被修改。无论如何,你最了解你的要求,你可以选择正确的方式去。

最后,请阅读有关java命名约定的内容。 CountryCode,Price看起来像Class not fields。