2016-12-17 96 views
1

下面的代碼應該按照正確的順序對版本號進行排序。它的大部分工作原理,但它沒有一個我無法訪問的隱藏的測試用例。鑑於有任何邊緣情況,你可以看到我可能會失蹤。排序版本號

import java.util.*; 

public class Answer { 
public static void main(String[] args) 
{ 
    //Testing 
    String[] versions = {"0.0.0","0","0.0","1.113","0.0.0.1","2.0.0","1.2","2","0.1","1.2.1","1.1.1","2.0"}; 
    String[] results = answer(versions); 
    for(int i =0; i<results.length;i++) 
    { 
     System.out.println(results[i]); 
    } 
} 
public static String[] answer(String[] l) { 

    String temp = new String(); 
    //Insertion sort on the given array to assign correct version numbers 
    for (int i = 1; i < l.length; i++) { 
     for(int j = i ; j > 0 ; j--){ 
      if(compareVersion(l[j],l[j-1])<0){ 
       temp = l[j]; 
       l[j] = l[j-1]; 
       l[j-1] = temp; 
      } 
     } 
    } 
    return l; 
} 
//Will compare version numbers breaking it apart into a String array 
public static int compareVersion(String version1, String version2) { 
String[] arr1 = version1.split("\\."); 
String[] arr2 = version2.split("\\."); 

int i=0; 
while(i<arr1.length || i<arr2.length){ 
    if(i<arr1.length && i<arr2.length){ 
     if(Integer.parseInt(arr1[i]) < Integer.parseInt(arr2[i])){ 
      return -1; 
     }else if(Integer.parseInt(arr1[i]) > Integer.parseInt(arr2[i])){ 
      return 1; 
     } 
     else if(Integer.parseInt(arr1[i]) == Integer.parseInt(arr2[i])) 
     { 
      int result = specialCompare(version1,version2); 
      if(result != 0) 
      { 
       return result; 
      } 
     } 
    } else if(i<arr1.length){ 
     if(Integer.parseInt(arr1[i]) != 0){ 
      return 1; 
     } 
    } else if(i<arr2.length){ 
     if(Integer.parseInt(arr2[i]) != 0){ 
      return -1; 
     } 
    } 

    i++; 
} 

return 0; 
} 
    // Meant for when version numbers such as 2 and 2.0 arise. This method will make sure to 
    // put the smaller version number (in length) first 
    public static int specialCompare(String str1, String str2) 
{ 
     String[] arr1 = str1.split("\\."); 
    String[] arr2 = str2.split("\\."); 
    for(int i =1; i<arr1.length;i++) 
    { 
     if(Integer.parseInt(arr1[i]) != 0) 
     { 
      return 0; 
     } 
    } 
    for(int j =1; j<arr2.length;j++) 
    { 
     if(Integer.parseInt(arr2[j]) != 0) 
     { 
      return 0; 
     } 
    } 
    if(arr1.length < arr2.length) 
    { 
     return -1; 
    } 
    else 
    { 
     return 1; 
    } 

} 
} 
+0

您希望有人在您的代碼中修復某些內容,但您甚至不知道失敗是什麼?你認爲任何人都可以完成這個任務?看看http://stackoverflow.com/help/how-to-ask並試圖澄清你的問題 – pvg

回答

0

在你的代碼上述specialCompare方法您的意見...

意味着當版本號,如2和2.0出現。這種方法 將確保把較小的版本號(長)第一

所以我從這個您想要的版本通過版本號的長度進行排序猜測。例如:從您提供的版本字符串數組要如下排序​​...

0 
2 
0.0 
0.1 
1.2 
1.113 
2.0 
0.0.0 
1.1.1 
1.2.1 
2.0.0 
0.0.0.1 

如果是這樣的話,那麼你似乎使這個複雜得多,它必須是。當你得到版本長度不同的兩個版本時,應該先選擇版本長度較短的版本。因此,簡單檢查版本拆分數組的長度應該解決這個問題。如果它們長度相同,則需要檢查每個版本。當版本長度相同時,不需要使用specialCompare方法。只需檢查每個版本以及它們是否相同,然後轉到下一個版本號等等。只要一個版本不同,你就會知道要返回什麼。如果你經歷了整個陣列,那麼你知道所有的版本號都是一樣的。

下面是使用上述邏輯對compareVersion方法的更改。沒有必要使用specialCompare方法。我猜這是你正在尋找的。

public static int compareVersion(String version1, String version2) 
{ 
    String[] arr1 = version1.split("\\."); 
    String[] arr2 = version2.split("\\."); 

    if (arr1.length < arr2.length) 
    return -1; 
    if (arr1.length > arr2.length) 
    return 1; 

    // same number of version "." dots 
    for (int i = 0; i < arr1.length; i++) 
    { 
    if(Integer.parseInt(arr1[i]) < Integer.parseInt(arr2[i])) 
     return -1; 
    if(Integer.parseInt(arr1[i]) > Integer.parseInt(arr2[i])) 
     return 1; 
    } 
    // went through all version numbers and they are all the same 
    return 0; 
} 
+0

是的,事實證明,我在今天早上就明白了這一點,並且讓自己變得更加困難。但我很感謝你回答我的問題。 –

0

package com.e;

import java.util。*;

/** *由dpc在17-2-27創建。 * */ 公共類VersionComparator實現比較{

@Override 
public int compare(String o1, String o2) { 

    if (o1 == null && o2 == null) { 
     return 0; 
    } else if (o1 == null && o2 != null) { 
     return -1; 
    } else if (o1 != null && o2 == null) { 
     return 1; 
    } else { 
     if (o1.length() == 0 && o2.length() == 0) { 
      return 0; 
     } else if (o1.length() == 0 && o2.length() > 0) { 
      return -1; 
     } else if (o1.length() > 0 && o2.length() == 0) { 
      return 1; 
     } else { 
      return compareVersion(o1, o2); 
     } 
    } 


} 


public static int compareVersion(String version1, String version2) { 
    String[] arr1 = version1.split("\\."); 
    String[] arr2 = version2.split("\\."); 

    try { 

     int i = 0; 
     while (i < arr1.length || i < arr2.length) { 
      if (i < arr1.length && i < arr2.length) { 
       if (Integer.parseInt(arr1[i]) < Integer.parseInt(arr2[i])) { 
        return -1; 
       } else if (Integer.parseInt(arr1[i]) > Integer.parseInt(arr2[i])) { 
        return 1; 
       } else if (Integer.parseInt(arr1[i]) == Integer.parseInt(arr2[i])) { 
        int result = specialCompare(version1, version2); 
        if (result != 0) { 
         return result; 
        } 
       } 
      } else if (i < arr1.length) { 
       if (Integer.parseInt(arr1[i]) != 0) { 
        return 1; 
       } 
      } else if (i < arr2.length) { 
       if (Integer.parseInt(arr2[i]) != 0) { 
        return -1; 
       } 
      } 

      i++; 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return 0; 
} 

public static int specialCompare(String str1, String str2) { 
    String[] arr1 = str1.split("\\."); 
    String[] arr2 = str2.split("\\."); 
    for (int i = 1; i < arr1.length; i++) { 
     if (Integer.parseInt(arr1[i]) != 0) { 
      return 0; 
     } 
    } 
    for (int j = 1; j < arr2.length; j++) { 
     if (Integer.parseInt(arr2[j]) != 0) { 
      return 0; 
     } 
    } 
    if (arr1.length < arr2.length) { 
     return -1; 
    } else { 
     return 1; 
    } 
} 


// test 
public static List<String> getLowerList(String str, Comparator<String> comparator, List<String> list) { 
    if (str == null) { 
     return list; 
    } 
    List<String> newlist = new ArrayList<String>(); 
    newlist.add(str); 
    newlist.addAll(list); 
    // sort 
    Collections.sort(newlist, comparator); 
    // search 
    int endIndex = Collections.binarySearch(newlist, str); 
    if (endIndex >= 0) { 
     // sublist 0 1 
     return newlist.subList(0, endIndex + 1); 
    } else { 
     return new ArrayList<String>(); 
    } 
} 

public static void main(String[] args) { 
    List<String> test1 = Arrays.asList(new String[]{ 
      "2.1.1", "1.21.22", "1.21.25", "1.113", "0.0.0.1", 
      "2.0.0", "1.2", "2.0", "0.1", "1.2.1", "1.1.1", 
      "11", "100", "" + Integer.MAX_VALUE + ".1", "", 
      "2.0", "10.1"}); 

    List<String> test2 = Arrays.asList(new String[]{"", null, "0", "10.20.100", "3.1.1", "9.8", "10.3.92"}); 

    List<String> newlist = new ArrayList<String>(); 
    newlist.addAll(test1); 
    newlist.addAll(test2); 

    Collections.sort(newlist, new VersionComparator()); 

    VersionComparator compareVersion = new VersionComparator(); 
    System.out.println(newlist); 

    System.out.println(getLowerList("2", compareVersion, newlist)); 
    System.out.println(getLowerList("3", compareVersion, newlist)); 
    System.out.println(getLowerList("4", compareVersion, newlist)); 
    System.out.println(getLowerList("5", compareVersion, newlist)); 

} 

}

0

我最近有需要的任意文件名這樣做是一個更通用的方法,類似於Windows資源管理器如何排序文件:

enter image description here

I wrote a blog post about thisThe idea was inspired by this answer here。以這種方式訂購文件的比較器如下所示:

public final class FilenameComparator implements Comparator<String> { 
    private static final Pattern NUMBERS = 
     Pattern.compile("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)"); 
    @Override public final int compare(String o1, String o2) { 
     // Optional "NULLS LAST" semantics: 
     if (o1 == null || o2 == null) 
      return o1 == null ? o2 == null ? 0 : -1 : 1; 

     // Splitting both input strings by the above patterns 
     String[] split1 = NUMBERS.split(o1); 
     String[] split2 = NUMBERS.split(o2); 
     for (int i = 0; i < Math.min(split1.length, split2.length); i++) { 
      char c1 = split1[i].charAt(0); 
      char c2 = split2[i].charAt(0); 
      int cmp = 0; 

      // If both segments start with a digit, sort them numerically using 
      // BigInteger to stay safe 
      if (c1 >= '0' && c1 <= '9' && c2 >= 0 && c2 <= '9') 
       cmp = new BigInteger(split1[i]).compareTo(new BigInteger(split2[i])); 

      // If we haven't sorted numerically before, or if numeric sorting yielded 
      // equality (e.g 007 and 7) then sort lexicographically 
      if (cmp == 0) 
       cmp = split1[i].compareTo(split2[i]); 

      // Abort once some prefix has unequal ordering 
      if (cmp != 0) 
       return cmp; 
     } 

     // If we reach this, then both strings have equally ordered prefixes, but 
     // maybe one string is longer than the other (i.e. has more segments) 
     return split1.length - split2.length; 
    } 
}