I am writing a program to find an array of doubles, let's say it found:
double[] dubArray = {3.5,3.5,3.7,4.3,4.5,4.5,4.5,4.7,5.0,5.5,5.5};
Then create a counter that will print all the values from lowest to highest
Array.sort(dubArray); //considering the array is out of order
int finalDub = dubArray.length;
double min = dubArray[0];
double max = dubArray[finalDub - 1];
for (double i = min; i < max; i = 0.1) {
System.out.printf("%.1f %n", i );
}
I need to have this code not only print through the values but also count the number of doubles and put a '$' in front of it to show the amount that double is in the array.
For example, my above code would output:
3.5
3.6
3.7
.
.
.
5.3
5.4
5.5
But I need it to output:
3.5 $$
3.6
3.7 $
.
.
.
5.3
5.4
5.5 $$
How could I make the counter then be able to iterate it into the 'System.out.printf("%.1f %n", i );' line?
I'd prefer to incorporate the $ counter into the System.out.printf line rather than using a string builder or something but if it cant be done then it cant be done.
CodePudding user response:
double[] dubArray = {3.5, 3.5, 3.7, 4.3, 4.5, 4.5, 4.5, 4.7, 5.0, 5.5, 5.5};
// O(nlogn)
Map<Double, Integer> treeMap = new TreeMap<>();
Arrays.stream(dubArray).forEach(d -> treeMap.put(d, treeMap.getOrDefault(d, 0) 1));
// O(n)
StringBuilder sb = new StringBuilder();
treeMap.forEach((d, f) -> {
sb.setLength(0);
while (f-- > 0) {
sb.append("$");
}
System.out.println(d " " sb);
});
Add the elements to a TreeMap
(my approach instead of sorting) with key as the element and the value as the frequency.
Iterate on the TreeMap
again and generate the $
string based on the value of the frequency and print out the result.
// Output
3.5 $$
3.7 $
4.3 $
4.5 $$$
4.7 $
5.0 $
5.5 $$
You don't always need to build the $
string. You can also store that into a HashMap
.
Map<Integer, String> dollarSignMap = new HashMap<>();
StringBuilder sb = new StringBuilder();
treeMap.forEach((d, f) -> {
if (dollarSignMap.containsKey(f)) {
System.out.println(d " " dollarSignMap.get(f));
} else {
sb.setLength(0);
while (f-- > 0) {
sb.append("$");
}
dollarSignMap.put(f, sb.toString());
System.out.println(d " " sb);
}
});
CodePudding user response:
Addition to Harshal Parekh's answer: if you want to use System.out.printf
, you can use String.repeat
instead of a while loop and a StringBuilder
:
System.out.printf("%.1f %s%n", i, "$".repeat(count));
To compute the count value, you can use a simple for loop:
int count = 0;
for (double v : dubArray) {
if (Math.abs(i - v) < 1e-5) {
count ;
}
}
Using Math.abs(i - v) < 1e-5
introduces a bit of numerical tolerance which is always a good idea with doubles. Note that using a for loop is inefficient and there are much faster approaches, for example using hash map like in Harshal Parekh's answer.