Reputation: 35
I am trying to write a code that finds the frequency of characters in a String entered in the method (phraseList()
is an already working method that takes a word and puts each character in an arrayList
)
and returns in a new List
that has the letters and their frequency, my code below;
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;
}
}
My problem however is that it returns all the letters and although I have tried many methods to remove them like using the remove()
method, it still does not work, I had something like
list.remove(list.get(i));
i--;
Can anyone help me?
Upvotes: 3
Views: 5000
Reputation: 121
HashMap is the easier way to solving this problem. If you have to use List, you can check if the character exist in list0 first. If the character is not exist in list0 then count for its frequency.
Updated Code :
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);
}
Upvotes: 1
Reputation: 81
Here is a way to do it using the new method merge()
available on Java8 Map
.
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;
}
}
Output:
{a=4, b=1, c=2, d=1, e=1}
With the method merge()
, when the item is not in the map, it just adds it, which in this case will add key=charAt(i),value=1
. On the other hand, if the key is already on the map, merge calls a function passing both current and new values, and updates the map with the result of this function.
Integer::sum
is a method reference, since the merge
method expects a function with two parameters, we could rewrite it as (currV,newV) -> currV+newV
.
Now, if you wish, you can use the new Stream
API instead. First, convert the String
to an IntStream
, then map each int
to a Character
, then collect the result on a HashMap
and return it. The method ltrfrq
would be as follows:
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);
}
Upvotes: 1
Reputation:
If I could only use List data structures (and my own custom one), this is how I would do it. I would redefine all of the add, remove functions to compensate for duplicate entries.
Output:
[{a=4}, {b=3}, {c=2}, {d=1}]
Code:
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;
}
}
Upvotes: 2
Reputation:
HashMaps are key-value pairs. But the keys are unique. So you cannot have duplicate keys. Kind of like a dictionary, you can update the value (definition) of a word, but you won't have that word listed twice.
Watch: https://www.youtube.com/watch?v=j442WG8YzM4
Read: https://beginnersbook.com/2013/12/hashmap-in-java-with-example/
Output:
{a=4, b=3, c=2, d=1}
I'll leave it as an exercise for you to traverse the map.
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;
}
}
Upvotes: 3