2017-11-11 136 views
2

我正在嘗試編寫一個代碼,用於查找方法中輸入的字符串中的字符的頻率(phraseList()是一種已在使用的方法,它將每個字符放入arrayList) 和返回一個新的List,其中包含字母及其頻率,下面是我的代碼;ArrayList中元素的頻率

public List <String> ltrfrq(String phrase){ 
List <String> list0 = new ArrayList<String>(); 
int count = 1; 
List <String> list = phraseList(phrase.toUpperCase()); 
for(int i = 0; i < list.size(); i++){ 
    for(int j = i + 1; j < list.size(); j++){ 
    if(list.get(i).equals(list.get(j))){ 
     count++; 
    } 
    } 
    if(list.get(i).equals(" ")){ 
    list0.add("Space" + "-" + count); 
    } 
    else{ 
    list0.add(list.get(i) + "-" + count); 
    } 
    count = 1; 
} 
return list0; 
    } 
} 

但是我的問題是,它返回所有的字母,雖然我已經嘗試了許多方法來消除他們喜歡用remove()方法,它仍然無法正常工作,我有這樣的事情

list.remove(list.get(i)); 
i--; 

誰能幫我?謝謝。

+0

你試過一個HashMap <字符,整數>? –

+0

@JabariDash我不是那個。 – toBiloBa

回答

3

HashMaps是鍵值對。但鑰匙是獨一無二的。所以你不能有重複的密鑰。有點像字典,你可以更新一個單詞的值(定義),但是你不會有那個單詞被列出兩次。

關注:https://www.youtube.com/watch?v=j442WG8YzM4

閱讀:https://beginnersbook.com/2013/12/hashmap-in-java-with-example/

輸出:

{a=4, b=3, c=2, d=1} 

我會離開它作爲一個練習,讓你穿越地圖。

import java.util.HashMap; 

public class F { 

    public static void main(String[] args) { 

    String string = "aaaabbbccd"; 

    HashMap<Character, Integer> map = frequency(string); 

    System.out.println(map); 
    } 

    public static HashMap<Character, Integer> frequency(String string) { 
    int length = string.length(); 
    char c; 

    HashMap<Character, Integer> map = new HashMap<Character, Integer>(); 

    for (int i = 0; i < length; i++) { 
     c = string.charAt(i); 

     if (map.containsKey(c)) { 
     map.put(c, map.get(c) + 1); 

     } else { 

     map.put(c, 1); 
     } 
    } 

    return map; 
    } 
} 
+0

謝謝,這很好,但是沒有其他方法可以做到這一點,比使用HashMaps ?,我說這是因爲我還沒有熟悉它,儘管我知道我必須反正學習它。 – toBiloBa

+0

你可以...我認爲算法會更復雜...可能比僅僅學習hashmap如何工作更復雜,但看不到。 –

+0

好的,謝謝.... – toBiloBa

2

如果我只能使用List數據結構(和我自己定製的數據結構),這是我該怎麼做。我會重新定義所有的添加,刪除功能來補償重複的條目。

輸出:

[{a=4}, {b=3}, {c=2}, {d=1}] 

代碼:

import java.util.List; 
import java.util.ArrayList; 

public class F { 

    static class Entry { 
    char character; 
    int count; 

    public Entry(char c, int i) { 
     character = c; 
     count = i; 
    } 

    public String toString() { 
     return "{" + character + "=" + count + "}"; 
    } 
    } 

    public static void main(String[] args) { 

    String string = "aaaabbbccd"; 

    List<Entry> list = frequency(string); 

    System.out.println(list); 
    } 


    public static List<Entry> frequency(String string) { 
    int length = string.length(); 
    char c; 
    Entry entry; 

    List<Entry> list = new ArrayList<Entry>(); 

    for (int i = 0; i < length; i++) { 
     c = string.charAt(i); 

     // add to list 
     add(c, list); 
    } 

    return list; 
    } 

    public static void add(char c, List<Entry> list) { 

    // If the list does not contain the character 
    if (!contains(c, list)) { 
     list.add(new Entry(c, 1)); 

    } else { 

     // Find the entry 
     int index = find(c, list); 

     // If we found the entry's indes 
     if (index >= 0) { 

     // Get the entry 
     Entry temp = list.get(index); 

     temp.count++;   // Increment its count 
     list.remove(index);  // Delete old 1 
     list.add(index, temp); // Insert new 1 
     } 
    } 
    } 

    // Finds the index of an entry thats associated with a character 
    public static int find(char c, List<Entry> list) { 
    int index = -1; 
    int length = list.size(); 


    Entry temp; 


    for (int i = 0; i < length; i++) { 
     temp = list.get(i); 

     if (temp.character == c) { 
     index = i; 
     break; 
     } 
    } 


    return index; 
    } 

    // Remove an Entry from list that is associate with a given character 
    public static List<Entry> remove(char c, List<Entry> list) { 

    for (Entry entry : list) { 
     if (entry.character == c) { 
     list.remove(entry); 
     } 
    } 

    return list; 
    } 

    // Get the entry that correlates to a give character in the list 
    public static Entry get(char c, List<Entry> list) { 
    Entry entryToReturn = null; 

    for (Entry entry : list) { 
     if (entry.character == c) { 
     entryToReturn = entry; 
     break; 
     } 
    } 

    return entryToReturn; 
    } 


    // Checks if the list contains the character 
    public static boolean contains(char c, List<Entry> list) { 
    boolean contains = false; 

    for (Entry entry : list) { 
     if (entry.character == c) { 
     contains = true; 
     break; 
     } 
    } 

    return contains; 
    } 
} 
+0

它的作品謝謝,我知道有另一種方式的線索,謝謝 – toBiloBa

+0

沒問題。但真的考慮這些HashMaps! –

1

的HashMap是解決這個問題的簡單的方法。如果你不得不使用列表,你可以先檢查這個字符是否存在於list0中。如果該字符在list0中不存在,則計數其頻率。

更新的代碼:

public static void main(String args[]){ 
    ArrayList <String> list0 = new ArrayList<String>(); 
     int count = 1; 
     //List <String> list = phraseList(phrase.toUpperCase());\ 
     ArrayList<String> list = new ArrayList<String>(); 
     list.add("a"); 
     list.add("b"); 
     list.add("a"); 
     list.add("c"); 
     list.add("b"); 
     list.add("a"); 

     for(int i = 0; i < list.size(); i++){ 
      boolean isDuplicate = false; 
      for (String s: list0){ 
       if (s.contains(list.get(i).trim())) 
        isDuplicate =true; 
      } 

      if (!isDuplicate){ 

        for(int j = i + 1; j < list.size(); j++){ 
        if(list.get(i).equals(list.get(j))){ 
         count++; 
        } 
        } 
        if(list.get(i).equals("/s")){ 
        list0.add("Space" + "-" + count); 
        } 
        else{ 
        list0.add(list.get(i) + "-" + count); 
        } 
        count = 1;  
      } 
     } 
     for (String a: list0) 
      System.out.println(a);   
} 
+0

我不知道這是否完整,但我已經檢查過它並沒有工作 – toBiloBa

+0

你會得到什麼輸出? – Maggie

+0

與我沒有if語句相同 – toBiloBa

1

這裏是一個辦法做到這一點使用上Java8 Map提供的新方法merge()

import java.util.HashMap; 
import java.util.Map; 

public class CountLetterFrequency { 

    public static void main(String[] args) { 
     System.out.println(ltrfrq("abacacdea")); 
    } 

    public static Map<Character, Integer> ltrfrq(String phrase){ 
     Map<Character, Integer> frqMap = new HashMap<>(); 
     for(int i=0; i<phrase.length(); i++){ 
      frqMap.merge(phrase.charAt(i), 1, Integer::sum); 
     } 
     return frqMap; 
    } 
} 

輸出:

{a=4, b=1, c=2, d=1, e=1} 

利用該方法merge(),當產品沒有在地圖上,它只是增加了它,在這種情況下會增加key=charAt(i),value=1。另一方面,如果鍵已經在地圖上,則合併調用傳遞當前值和新值的函數,並使用此函數的結果更新地圖。

Integer::sum是方法參考,因爲merge方法需要一個帶有兩個參數的函數,所以我們可以將它重寫爲(currV,newV) -> currV+newV

現在,如果您願意,您可以改用新的Stream API。首先,將String轉換爲IntStream,然後將每個int映射到Character,然後在HashMap上收集結果並將其返回。方法ltrfrq將如下:

public static Map<Character, Integer> ltrfrq(String phrase){ 
    return phrase.chars() 
     .mapToObj(i->(char)i) 
     .collect(HashMap::new, 
      (m,k) -> m.merge(k, 1, Integer::sum), 
      Map::putAll); 
}