'How do I take the repeated values in an array and print out the number of duplicates using a for loop ?(Java)

I have written the following program which takes the duplicates in the doubleArray and adds them to a counter.

Then I wrote a for loop to print out the values in the array going from the smallest value, up by 0.1, to the highest value. Then the program is supposed to put a dollar sign after each number that is represented in the array.

double[] doubleArray = {1.7,1.7,2.0,1.3,1.0};
int count = 0;          
Arrays.sort(doubleArray);  
for(int i = 0;i<doubleArray.length-1;i++){
    for(int j =i+1;j<doubleArray.length;j++){
        if (doubleArray[i] == doubleArray[j]) {
            count++;
        } else {
            break;
        }
    }
}

int finalDub = doubleArray.length;
double min = doubleArray[0];
double max = doubleArray[finalDub - 1];

for (double i = min; i < max+0.1; i += 0.1) {
    System.out.printf("%.1f ", i);  
    System.out.print("$".repeat(count));
    System.out.print("\n");
}

But when I run the code, the following gets outputted

1.0 $
1.1 $
1.2 $
1.3 $
1.4 $
1.5 $
1.6 $
1.7 $
1.8 $
1.9 $
2.0 $

When it should be the following because I want it to add the $ only after a double represented in the array, and multiple '$''s for duplicate values.

1.0 $
1.1 
1.2 
1.3 $
1.4 
1.5 
1.6 
1.7 $$
1.8 
1.9 
2.0 $

I believe what is happening is the count integer is being set once and never updating. Either way, how can I update my counter logic to represent what I want to be outputted?



Solution 1:[1]

I made a custom Counter class to keep track of each Double and the counts of the Double. You can iterate through all your doubles, add the non-duplicates, and if duplicate, increment count.

import java.util.ArrayList;
import java.util.Arrays;

public class test {

    static class Counter{
        Double value;
        int count;

        Counter(Double d, int c){
            this.value = d;
            this.count = c;
        }

        public String toString() { return value+":"+count; }
    }

    public static void main(String[] args){
        double[] doubleArray = {1.7,1.7,2.0,1.3,1.0};
        ArrayList<Counter> list = new ArrayList<>();

        Arrays.sort(doubleArray);
        for(int i = 0;i<doubleArray.length;i++){
            int size = list.size();
            if (size == 0){
                list.add(new Counter(doubleArray[0], 1));
            }else{
                Counter current = list.get(size-1);
                if (doubleArray[i] != current.value){
                    list.add(new Counter(doubleArray[i], 1));
                }else{
                    current.count = current.count +1;
                }
            }
        }

//        for (int i=0; i< list.size(); i++){
//            System.out.println(list.get(i).toString());
//        }

        int finalDub = doubleArray.length;
        double min = doubleArray[0];
        double max = doubleArray[finalDub - 1];

        for (double i = min; i < max+0.1; i += 0.1) {
            int count = 0;
            System.out.printf("%.1f ", i);
            for (int j=0; j< list.size(); j++){
                Counter obj = list.get(j);
                double val = Double.parseDouble(String.format("%.1f", i));  
//this is necessary to format the floating point number to the exact accuracy stored in your array
                if (obj.value == val){
                    count = obj.count;
                    break;
                }else{
                    continue;
                }
            }
            System.out.print("$".repeat(count));
            System.out.print("\n");
        }
    }
}

I also found that for some reason, your loop to iterate through values from min to max have some floating point issues that cause it to not have the same value as the double stored in the array. floating point error looks fine now

Solution 2:[2]

BUG FOUND o_o (REFERENCE ONLY)

NOTE THIS IS NOT A FULL SOLUTION ONLY A RECOMMENDATION

Instead of creating a nested loop with a break statement, I would 1000% recommend an approach closer to this.

    int size = doubleArray.length - 1, count = 0;
    double number = doubleArray[0];

    for(int index = 1; index < size; index++)
    {
        if(number == doubleArray[index])
        {
            count++;
        }
        number = doubleArray[index + 1];
    }

Though I do not know exactly where the issue is with your code, the easier it is to read the easier the bug will be to find!

EDIT after MY found bug ha

This part works great and is what you want

if(number == doubleArray[index])
{            
    count++;
}

But if this is in the for-loop,

number = doubleArray[index + 1];

Each number after that will be considered a match.

Solution 3:[3]

How could I change it so it is updated for each value

If you create a second array to track each digit you could do so pretty reliably, though I am sure there are more efficient ways out there.

int[] digitCount = new int[11]; // 1.0 - 2.0
...
if(number == doubleArray[index])
{
    digitCount[number]++;
}
...

And then down in your print

...
System.out.print("$".repeat(digitCount[i]));
...

Make sure that the i (or whatever you call it) is a WHOLE number because you cannot have decimal indecies.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3