2012-12-13 69 views
1
String input = "AAAB"; 

    String output = ""; 
    for (int index = 0; index < input.length(); index++) { 
     if (input.charAt(index % input.length()) != input 
       .charAt((index + 1) % input.length())) { 

      output += input.charAt(index); 

     } 
    } 
    System.out.println(output); 

但是,如果我的輸入是「ABABAB」或只是「AAAA」,則不起作用。有任何想法嗎?刪除字符串中的重複項而不使用數組

+2

我並不完全相信你的意圖是什麼,你可以添加輸入和匹配預期輸出的例子嗎? – bowmore

+1

您需要定義:*不使用數組*。 'input.charAt(..)'正在使用一個數組,例如... – assylias

回答

4

使用一個數據結構來知道,如果一個角色已經被發現,如Set。例如,您可以使用其add()方法並檢查其返回值。

此外,您可以考慮使用StringBuilder對於重複拼接,這是更有效的。

Set<Character> characters = new HashSet<Character>(); 
String input = "AAAB"; 
StringBuilder output = new StringBuilder(); 
for (int index = 0; index < input.length(); index++) { 
    char character = input.charAt(index); 
    if (characters.add(character)) { 
     output.append(character); 
    } 
} 
System.out.println(output.toString()); 
+1

具有諷刺意味的是使用數組會更困難。 – Esailija

+0

這是一個好主意,但我不允許使用任何類型的數組,我的意思是hashset也是如此。 – Mosaab

0

(我希望你的意思是重複的,不重複。)

public static String withoutDuplicates(String s) { 
    for (int i = 0; i < s.length();) { 
     boolean removedDuplicate = false; 
     for (int duplicateLength = (s.length() - i)/2; duplicateLength >= 1; 
       --duplicateLength) { 
      if (foundDuplicate(s, i, duplicateLength)) { 
       s = s.substring(0, i) + s.substring(i + duplicateLength); 
       removedDuplicate = true; 
       break; 
      } 
     } 
     if (!removedDuplicate) { 
      ++i; 
     } 
    } 
    return s; 
} 

private static boolean foundDuplicate(String s, int i, int duplicateLength) { 
    String sought = s.substring(i, i + duplicateLength); 
    return s.indexOf(sought, i + duplicateLength) != -1; 
} 

更正: duplicateLength初始化值超出範圍。

+0

非常感謝:) – Mosaab

+0

但是當我使用ABCCDA時出現錯誤。 – Mosaab

+0

這應該成爲BCDA(因爲總是刪除第一個副本)。 –

1

優化了極速版

public static void main(String[] args) { 
    String input = "AAAB"; 
    StringBuilder output = new StringBuilder(); 
    for (int i = 0; i < input.length(); i++) { 
     if (!contains(output, input.charAt(i))) { 
      output.append(input.charAt(i)); 
     } 
    } 
    System.out.println(output); 
} 

private static boolean contains(StringBuilder output, char c) { 
    for(int i = 0; i < output.length(); i++) { 
     if (output.charAt(i) == c) { 
      return true; 
     } 
    } 
    return false; 
} 
+0

考慮到「contains」方法,這不是O(n(log n))嗎?使用'HashSet的#加()'(O(1)),並通過串去(爲O(n))是O(n) –

+1

這個程序與原始字符纔有效。你能想象爲每個char創建一個Object的成本嗎?沒有測試,我可以說差異將是巨大的。 –

+0

實際上,從[5.1.7]開始裝箱時,似乎''u0000'-'\ u007f'範圍內的字符被緩存。拳擊轉換](http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7)。但絕對是一個好點。作爲一個方面說明,正如@assylias在他的評論中指出的那樣,使用StringBuilder來搜索字符可以被看作是使用數組。但是再次,幾乎所有流行的數據結構(如'HashSet' /'Map')最終都使用了數組:) –

0

讓我們來看看你的循環是這樣做的:

if (input.charAt(index % input.length()) != input 
    .charAt((index + 1) % input.length())) 

1)首先,你應該意識到,你就是在浪費時間和處理能力通過執行'%input.length()'操作,因爲索引總是小於input.length(),所以index%input.length()總是等於索引。

讓我們無視%input.length()前進。

2)當你比較input.charAt(index)來input.charAt(索引+ 1)你只是比較反對下一個當前字符。原來的問題,如果我理解正確的話,會要求你刪除所有重複的東西,而不僅僅是那些相鄰的東西。 3)你的算法很可能會拋出IndexOutOfBounds異常,因爲當你到達字符串的末尾時(當index == input.length() - 1)時,檢查input.charAt(index + 1)將看起來是一個字符在字符串中太遠了。

作爲第一個答案的建議,你會想使用某種形式的數據結構來存儲所有你遇到了性格迥異的。任何時候你點擊一個新角色,你都會想要a)將它添加到你的數據結構中,並且b)將它添加到你的輸出結尾。

+0

他使用模數只是爲了避免100B。在這種情況下,最好讓它發生,因爲他將最後一個字符與第一個字符進行比較。 –

+0

是的,我做到了,因爲我想看看最後一個元素==第一個元素。 – Mosaab

0
public static void print(String s) { 
    List<String> v = new ArrayList<String>(); 
    for(int j=0; j<s.length(); j++) { 
     if(!v.contains("" + s.charAt(j))) 
      v.add("" + s.charAt(j)); 
    } 


    for(String e : v) 
     System.out.print(e); 
} 
+0

對不起,我刪除了前一個,是的,前面的代碼是因爲TreeSet而打印的,這個保留了原始的順序。 – pgardunoc