patternjavaMinor
Print total occurrences of a char in a string
Viewed 0 times
totaloccurrencescharprintstring
Problem
Scenario: Count the total number of times a char occurs in a word.
For instance, "aaabbcccdddaaaa" should print out "a7b2c3d3".
Can you please critique my code?
For instance, "aaabbcccdddaaaa" should print out "a7b2c3d3".
Can you please critique my code?
import java.util.HashMap;
import java.util.Map;
public class Demo {
public static void main(final String[] args) {
final Demo d = new Demo();
final String name = "aaabbcccdddaaaa";
System.out.println(d.countNoOfInteger(name));
}
public String countNoOfInteger(final String str) {
if (str.equals(null)) {
throw new IllegalArgumentException();
}
if (str.isEmpty()) {
return "";
}
final Map map = new HashMap<>();
int count = 0;
final char[] charArray = str.trim().toCharArray();
for (final char element : charArray) {
if (map.get(element) != null) {
count = map.get(element);
map.put(element, ++count);
} else {
count = 0;
map.put(element, ++count);
}
}
int total;
char ch;
final Map visited = new HashMap<>();
final StringBuilder sb = new StringBuilder();
for (final char element : charArray) {
if ((visited.get(element) == null)) {
ch = element;
sb.append(ch);
total = map.get(element);
sb.append(total);
visited.put(element, true);
}
}
return sb.toString();
}
}Solution
The use of
Some notes:
Map is unnecessary overhead. You can leverage the fact that chars can be mapped as ints along with a simple array to solve this problem.private static final int OFFSET = 'a';
public String countNoOfInteger(final String str) {
final int[] counts = new int[26]; // or 'z' - 'a' + 1, if you prefer
for (final char character : str.toCharArray()) {
counts[character - OFFSET]++;
}
final StringBuilder output = new StringBuilder();
for (int i = 0; i < counts.length; i++) {
if (counts[i] == 0) {
continue;
}
output.append((char) (i + OFFSET));
output.append(counts[i]);
}
return output.toString();
}Some notes:
OFFSETcould probably have a better name. I'll leave that as an exercise for the reader.
- Contrary to other respondents, I heartily encourage the use of
finalas a statement of intent.
- In a "real" system, it would be preferable to separate the business logic (find the letter counts) from the display logic (print them to the screen). In such a system, your method would return the
counts int[](orMap) and the caller (main(), in this case) would be responsible for displaying it (everything after the firstforloop).
- Note that this solution will fail spectacularly for invalid input. If that's something you need to handle, add a check to the first loop to ensure that
characteris betweenoffsetandoffset + counts.length.
Code Snippets
private static final int OFFSET = 'a';
public String countNoOfInteger(final String str) {
final int[] counts = new int[26]; // or 'z' - 'a' + 1, if you prefer
for (final char character : str.toCharArray()) {
counts[character - OFFSET]++;
}
final StringBuilder output = new StringBuilder();
for (int i = 0; i < counts.length; i++) {
if (counts[i] == 0) {
continue;
}
output.append((char) (i + OFFSET));
output.append(counts[i]);
}
return output.toString();
}Context
StackExchange Code Review Q#116436, answer score: 3
Revisions (0)
No revisions yet.