I am trying to loop through my array and find all the numbers that are repeating more than once:
E.G: if there is 1 1 2 3 4
It should print saying \
Just add the number you will find duplicated to some structure like HashSet
or HashMap
so you can find it later when you will detect another duplication.
Set<Integer> printed = new HashSet<Integer>();
for(int i=0; i<buffer.length; i++) {
for(int k=i+1; k<buffer.length; k++) {
if(buffer[k] == buffer[i]) {
Integer intObj = new Integer(buffer[k]);
if (!printed.contains(intObj)) {
System.out.println(buffer[k]);
printed.add(intObj);
}
break;
}
}
}
Better O(n) alghorithm:
Set<Integer> printed = new HashSet<Integer>();
for(int i=0; i<buffer.length; i++) {
if (!printed.add(new Integer(buffer[i])) {
System.out.println(buffer[i]);
}
}
Using the apache commons CollectionUtils.getCardinalityMap(collection):
final Integer[] buffer = {1, 2, 3, 4, 5, 6, 7, 2, 1, 7, 9, 1, 1, 3};
final List<Integer> list = Arrays.asList(buffer);
final Map<Integer, Integer> cardinalityMap = CollectionUtils.getCardinalityMap(list);
for (final Map.Entry<Integer, Integer> entry: cardinalityMap.entrySet()) {
if (entry.getValue() > 1) {
System.out.println(entry.getKey());
}
}
toString() of cardinalityMap looks like this after the init:
{1=4, 2=2, 3=2, 4=1, 5=1, 6=1, 7=2, 9=1}
Using standard java:
final Integer[] buffer = {1, 2, 3, 4, 5, 6, 7, 2, 1, 7, 9, 1, 1, 3};
final List<Integer> list = Arrays.asList(buffer);
final Set<Integer> set = new LinkedHashSet<Integer>(list);
for (final Integer element: set) {
if (Collections.frequency(list, element) > 1) {
System.out.println(element);
}
}
I would use a HashMap
to store the value I encounter in the array, with the count as a value. So if you encounter a 4, you would look it up in the HashMap
, if it doesn't exist, you would add it with a value of 1, otherwise increment the value returned.
You can the loop over the HashMap
and get all the values and print the number of duplicates encountered in the array.
Integer[] ints = {1, 1, 2, 3, 4};
System.out.println(new HashSet<Integer>(Arrays.asList(ints)));
Output: [1, 2, 3, 4]
This problem is much simpler and likely faster to solve using a collection. However, as requested here's an answer that uses "just simple array[s]" and no sorting. I've tried not to change your code too much but I refuse to leak resources in the case of an exception.
import java.io.*;
import java.util.Arrays;
import java.util.Scanner;
class Average {
public static void main(String[] args) throws IOException {
int numOfLines = 0;
int sum = 0, mean = 0, median = 0, lq = 0, uq = 0;
int[] buffer;
int flag = -1;
File myFile = new File("num.txt");
try (Scanner Scan = new Scanner(myFile)) {
while(Scan.hasNextLine()) {
Scan.nextLine();
numOfLines++;
}
}
try (Scanner Scan = new Scanner(myFile)) {
System.out.println("Number Of Lines: " + numOfLines);
buffer = new int[numOfLines];
for(int i=0; i<numOfLines; i++) {
buffer[i] = Scan.nextInt();
}
}
for(int i=0; i<buffer.length; i++) {
sum = sum+i;
mean = sum/numOfLines;
}
System.out.println("Sum: " + sum);
System.out.println("Mean: " + mean);
//copy every duplicate
int[] dupesOnly = new int[numOfLines];
int dupesOnlyIndex = 0;
for(int i=0; i<buffer.length; i++) {
for(int k=i+1; k<buffer.length; k++) {
if(buffer[k] == buffer[i]) {
dupesOnly[dupesOnlyIndex++] = buffer[i];
//System.out.println(buffer[k]);
}
}
}
//mark all but first occurrence of dupe
boolean[] skip = new boolean[dupesOnlyIndex]; //Inits to false
for (int i = 0; i < dupesOnlyIndex; i++) {
for(int k=i+1; k<buffer.length; k++) {
if(dupesOnly[k] == dupesOnly[i]) {
skip[k] = true;
}
}
}
//skip elements marked as extra dupes
int[] dupesUnique = new int[dupesOnlyIndex];
int dupesUniqueIndex = 0;
for (int i = 0; i < dupesOnlyIndex; i++) {
if (skip[i] == false) {
dupesUnique[dupesUniqueIndex++] = dupesOnly[i];
}
}
//trim to size
int[] dupesReport = new int[dupesUniqueIndex];
for (int i = 0; i < dupesReport.length; i++) {
dupesReport[i] = dupesUnique[i];
}
System.out.println("Dupes: " + Arrays.toString(dupesReport));
}
}
Input file "num.txt" (numbers separated by newlines not commas):
1, 2, 3, 4, 5, 6, 7, 2, 1, 7, 9, 1, 1, 3
Output:
Number Of Lines: 14
Sum: 91
Mean: 6
Dupes: [1, 2, 3, 7]
You perform the check for every single item of the array, including the first 4
, the second 4
and so on. That's why it just doesn't stop and it prints the message multiple times per duplicated element.
You're saying you cannot use a Set
and that you don't want to sort your data. My suggestion is that you loop over the array and add each duplicated item to a list. Make sure you check whether the item has already been added. (or use a Set
:) )
Then loop over the list and print those items.