Home > Enterprise >  How do I iterate through a System.out.format line in java?
How do I iterate through a System.out.format line in java?

Time:05-03

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.

  • Related