2017-11-11 139 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); 
}