I have a text file as input and I am trying to find the number of times every word of the file appears as well as how many times it appears on each line. So for the word "banana" I would like an output like: {banana: 5,0,0,1,1,1} meaning that "banana" appears 5 times in the text, 2 times in the first line (0) and 3 times in the second line.
I am thinking of using a 2D HashMap for that so that:
Map<String, Map<Integer, Integer>>
where String is the word, the first Integer is the line the word appears at, and the second Integer the number of occurrences in the line. The problem is that I cannot implement my idea in code as I get many errors:
Map<Map<Integer,Integer>, String > hashOfHash = new HashMap<Map<Integer, Integer>, String>();
while (line!=null){
Map<Integer, Integer> hash = new HashMap<Integer, Integer>();
String[] words = line.split(" ");
for (String z:words){
if (hashOfHash.containsKey(z)) {
Integer r = hashOfHash.get(z);
r = r + 1;
} else {
hash.put(z, new Integer(1));
}
}
}
Could anyone please assist me with the problem?
I would make a class that wraps your functionality for you:
public class WordInfo {
private int occurrences = 0; //Store total occurances
private final Map<Integer, Integer> lines = new TreeMap<>(); //Map line numbers to occurance counts
public void markLine(int line) {
Integer curr = this.lines.get(line);
if (curr == null) {
curr = 0;
}
this.lines.put(line, ++curr);
}
public int getOccurrences() {
return this.occurrences;
}
public int getOccurrencesAtLine(int line) {
return this.lines.containsKey(line) ? this.lines.get(line) : 0;
}
public Map<Integer, Integer> getOccurrenceLocations() {
return Collections.unmodifiableMap(this.lines);
}
}
Then it simply becomes a matter of managing your own mapping to this class appropriately (some example methods):
private final Map<String, WordInfo> wordInfo = new HashMap<>(); //Use to retrieve info about words
private WordInfo getInfo(String word) {
WordInfo back = this.wordInfo.get(word);
if (back == null) {
back = new WordInfo();
this.wordInfo.put(word, back);
}
return back;
}
public void markWord(String word, int line) { //Call upon occurance of a word
this.getInfo(word).markLine(line);
}
You're working in a language which is essentially all object-orientated, it helps to make objects which represent your information rather than combining confusing amounts of Collections and Maps.
As for your specific example, you could easily convert to a string like so:
public String wordInfo(String word) {
StringBuilder sb = new StringBuilder("{");
WordInfo info = this.getInfo(word);
sb.append(word).append(": ").append(info.getOccurrences());
info.getOccurrenceLocations().entrySet().forEach(ent -> {
for (int i = 0; i < ent.getValue(); i++) { //#getValue() -> occcurences at a line
sb.append(",").append(ent.getKey()); //#getKey() -> line number
}
});
return sb.append("}").toString();
}
Would output like
{banana: 0} //no occurrences
{banana: 1,1} //one occurrence on line 1
{banana: 5,0,0,1,1,1} //5 occurrences, 2 on line "0", 3 on line "1"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.