2017-09-04 105 views
2

我有兩個字符串看起來像這樣的:的Java:關鍵字比較字符串以不同的順序

String str1 = "[0.7419,0.7710,0.2487]"; 
String str2 = "[\"0.7710\",\"0.7419\",\"0.2487\"]"; 

,我想對它們進行比較,並不顧階差分等於...

哪個最快和最簡單的方法來做到這一點?

我應該將每一個分成數組並比較兩個數組嗎?或不? 我想我必須刪除「[」,「]」,「」「字符才能使它更清晰,所以我也這樣做了,而且我也用」「替換了」,「但我不知道這是否有幫助。 。提前:)

感謝

編輯:。我的琴絃不會永遠是一組雙打或漂浮它們也可以是實際的單詞或一組字符

+3

你的字符串是的'設置'陳述(至少你這麼說)。因此解析它們,然後比較。 –

+0

你的字符串裏只有數字嗎?或者它可以是任何字符? –

+0

我會將這些數字解析爲Double並將它們放入List中。然後一個接一個地排序和比較。 – MTCZiomal

回答

1

這可以通過下面的方法來完成,這是通過使用TreeSet來實現的一組字符串的一種方法來實現的,因此排序可以是內置的句柄。它只是一個簡單的轉換集合的字符串和使用equals方法進行比較。 試試下面的代碼:

String str1 = "[0.7419,0.7710,0.2487]"; 
     String str2 = "[\"0.7710\",\"0.7419\",\"0.2487\"]"; 
     String jsonArray = new JSONArray(str2).toString(); 
     Set<String> set1 = new TreeSet<String>(Arrays.asList(str1.replace("[", "").replace("]", "").split(","))); 
     Set<String> set2 = new TreeSet<String>(Arrays.asList(jsonArray.replace("[", "").replace("]", "").replace("\"", "").split(","))); 
     if(set1.equals(set2)){ 
      System.out.println(" str1 and str2 are equal"); 
     } 

在這裏,在上面的代碼中,我注意到幫助jsonArray,除去「\」字符。

注:

但這不會在一個字符串和其他 字符串,如果重複的元素工作在數量上有所不同,因爲一套不留副本。

嘗試使用列表保持重複的元素,並解決您的問題。

String str1 = "[0.7419,0.7710,0.2487]"; 
      String str2 = "[\"0.7710\",\"0.7419\",\"0.2487\"]"; 
      String jsonArray = new JSONArray(str2).toString(); 
      List<String> list1=new ArrayList<String>(Arrays.asList(str1.replace("[", "").replace("]", "").split(","))); 
      List<String> list2=new ArrayList<String>(Arrays.asList(jsonArray.replace("[", "").replace("]", "").replace("\"", "").split(","))); 
      Collections.sort(list1); 
      Collections.sort(list2); 
      if(list1.equals(list2)){ 
        System.out.println("str1 and str2 are equal"); 
      } 
+0

如果'set2'在刪除'set1'後是空的,這並不意味着它們是相等的。這可能意味着'set2'是'set1'的一個子集。改用'set1.equals(set2)'。 – DodgyCodeException

+1

怎麼可能? ,如果set1的所有元素都從set2中刪除,那麼,如果它變爲空,那麼它們相等,否則不相等。 –

+1

如果'set2'爲'{1,2,3}'且'set1'爲'{1,2,3,4}',那麼從'set2'中移除'set1'會給你一個空集。但他們仍然不平等 – Rogue

0

這是非常簡單的解決方案對你使用HashSet。

設置好處: -

  • 它不能包含重複。
  • 元素的插入/刪除是O(1)。
  • 比Array快得多。這裏保留元素Order也是 不重要,所以沒關係。

    String str1 = "[0.7419,0.7710,0.2487]"; 
    String str2 = "[\"0.7710\",\"0.7419\",\"0.2487\"]"; 
    
    Set<String> set1 = new HashSet<>(); 
    Set<String> set2 = new HashSet<>(); 
    
    String[] split1 = str1.replace("[", "").replace("]", "").split(","); 
    String[] split2 = str2.replace("[", "").replace("]", "").replace("\"", "").split(","); 
    set1.addAll(Arrays.asList(split1)); 
    set2.addAll(Arrays.asList(split2)); 
    
    System.out.println("set1: "+set1); 
    System.out.println("set2: "+set2); 
    
    boolean isEqual = false; 
    if(set1.size() == set2.size()){ 
        set1.removeAll(set2); 
        if(set1.size() ==0){ 
         isEqual = true; 
        } 
    } 
    
    System.out.println("str1 and str2 "+(isEqual ? "Equal" : "Not Equal")); 
    

輸出:

set1: [0.7710, 0.2487, 0.7419] 
set2: [0.7710, 0.2487, 0.7419] 
str1 and str2 Equal 
+0

如果'set2'包含'set1'的所有元素加上幾個元素,那麼您將無法區分兩個集合的區別是相同的。 – DodgyCodeException

+0

或者只是子串,然後分割一次。對於更長的字符串沒有迭代。 – Rogue

+0

@DodgyCodeException我沒有看到有關保持重複的問題。 – nagendra547

0

像這樣:

String[] a1 = str1.replaceAll("^\\[|\\]$", "").split(",", -1); 
    String[] a2 = str2.replaceAll("^\\[|\\]$", "").split(",", -1); 
    for (int i = 0; i < a2.length; i++) 
     a2[i] = a2[i].replaceAll("^\\\"|\\\"$", ""); 
    Arrays.sort(a1); 
    Arrays.sort(a2); 
    boolean stringsAreEqual = Arrays.equals(a1, a2); 

或者你可以使用一個全功能的方法(這可以稍微低效率):

boolean stringsAreEqual = Arrays.equals(
      Arrays.stream(str1.replaceAll("^\\[|\\]$", "").split(",", -1)) 
        .sorted() 
        .toArray(), 
      Arrays.stream(str2.replaceAll("^\\[|\\]$", "").split(",", -1)) 
        .map(s -> s.replaceAll("^\\\"|\\\"$", "")) 
        .sorted() 
        .toArray() 
    ); 

使用數組而不是使用數組(其他人提議)的優點是數組通常使用較少的內存,並且可以保存重複數據。如果您的問題域可以在每個字符串中包含重複元素,則無法使用集合。

+0

對於大量元素,這是效率低下的解決方案。當你正在對這兩個數組進行排序時,只需要檢查兩個數組的相等性。 – nagendra547

+1

順便說一句,如果使用'java.util.HashSet'是一個問題,由於無法處理重複,它可以被谷歌Guava HashMultiset取代:http://google.github.io/guava/releases/22.0/api /docs/com/google/common/collect/HashMultiset.html。 – yegodm

1

因爲你有混合的結果類型,需要先處理它作爲一個混合輸入

這是我怎麼會取代它,特別是對於更長的字符串。

private Stream<String> parseStream(String in) { 
    //we'll skip regex for now and can simply hard-fail bad input later 
    //you can also do some sanity checks outside this method 
    return Arrays.stream(in.substring(1, in.length() - 1).split(",")) //remove braces 
     .map(s -> !s.startsWith("\"") ? s : s.substring(1, s.length() - 1)); //remove quotes 
} 

跟進,現在我們有一個字符串,它需要被解析成無論是原始或字符串流(因爲我假設我們沒有對象序列化的一些怪異的形式):

private Object parse(String in) { 
    //attempt to parse as number first. Any number can be parsed as a double/long 
    try { 
     return in.contains(".") ? Double.parseDouble(in) : Long.parseLong(in); 
    } catch (NumberFormatException ex) { 
     //it's not a number, so it's either a boolean or unparseable 
     Boolean b = Boolean.parseBoolean(in); //if not a boolean, #parseBoolean is false 
     b = in.toLowerCase().equals("false") && !b ? b : null; //so we map non-false to null 
     return b != null ? b : in; //return either the non-null boolean or the string 
    } 
} 

利用這一點,我們可以在我們的混合流,然後轉換爲混合收集:

Set<Object> objs = this.parseStream(str1).map(this::parse).collect(Collectors.toSet()); 
Set<Object> comp = this.parseStream(str2).map(this::parse).collect(Collectors.toSet()); 
//we're using sets, keep in mind the nature of different collections and how they compare their elements here 
if (objs.equals(comp)) { 
    //we have a matching set 
} 

最後,一些理智的檢查將確保東西,如適當的括號是在我的例子輸入字符串等。儘管其他人說我學習了設置語法{a, b, ...c},並且系列/列表語法爲[a, b, ...c],這兩者在這裏有不同的比較。

+0

解析爲Long,Double或Boolean而不是簡單地將所有內容保存爲字符串的優點是什麼? – DodgyCodeException

+1

解析時不同數量的相同值不會與字符串匹配,例如'1237.0'和'1237.00'。 – Rogue

+0

公平點。下一個問題:你的意思是'substring(1)'而不是'substring(0)'? (後者簡單地返回'this'。) – DodgyCodeException

0

Google GSON可以通過讀取值作爲Set<String>相當整齊地完成這一任務:

final String str1 = "[0.7419,0.7710,0.2487]"; 
    final String str2 = "[\"0.7710\",\"0.7419\",\"0.2487\"]"; 
    final String str3 = "[\"0.3310\",\"0.7419\",\"0.2487\"]"; 
    final Gson gson = new Gson(); 
    final Type setOfStrings = new TypeToken<Set<String>>() {}.getType(); 
    final Set<String> set1 = gson.fromJson(str1, setOfStrings); 
    final Set<String> set2 = gson.fromJson(str2, setOfStrings); 
    final Set<String> set3 = gson.fromJson(str3, setOfStrings); 

    System.out.println("Set #1:" + set1); 
    System.out.println("Set #2:" + set2); 
    System.out.println("Set #3:" + set3); 
    System.out.println("Set #1 is equivalent to Set #2: " + set1.equals(set2)); 
    System.out.println("Set #1 is equivalent to Set #3: " + set1.equals(set3)); 

輸出是:

Set #1:[0.7419, 0.7710, 0.2487] 
Set #2:[0.7710, 0.7419, 0.2487] 
Set #3:[0.3310, 0.7419, 0.2487] 
Set #1 is equivalent to Set #2: true 
Set #1 is equivalent to Set #3: false