Reputation: 25
it keeps repeating regardless of whether it's been already calculated or not. You can see the example output. it already calculated the occurrence of 1, but when it sees 1 again, it will calculate it again!
public class SortingInLinearTime {
public static int[][] howMany(int[] n){
// Makes a double array list where the second value is occurrence of the first value.
int[][] a = new int[n.length][2];
int counter = 0;
for(int i = 0; i != n.length; i++){
for(int j = 0; j != n.length; j++) {
if(n[i] == n[j]){
counter++;
}
}
a[i][0] = n[i];
a[i][1] = counter;
counter = 0;
}
// printer helper function
for(int i = 0; i != n.length; i++){
System.out.print(a[i][0] + " occurs ");
System.out.println(a[i][1] + " times");
}
return a;
}
public static void main(String[] args) {
int[] testArray = {1, 2, 3, 1, 2, 3, 4};
System.out.print(howMany(testArray));
}
}
output: 1 occurs 2 times 2 occurs 2 times 3 occurs 2 times 1 occurs 2 times 2 occurs 2 times 3 occurs 2 times 4 occurs 1 times [[I@15db9742
Upvotes: 1
Views: 702
Reputation: 3709
Convert your array to list using Arrays.asList() and then use the collections api to get the count.
Collections.frequency(Collection c, Object o)
Updated with the implementation
import java.util.AbstractList;
import java.util.Collections;
import java.util.List;
public class SortingInLinearTime {
public static int[][] howMany( int[] n){
// Makes a double array list where the second value is occurrence of the first value.
int[][] a = new int[n.length][2];
for(int i = 0; i < n.length; i++){
int count = Collections.frequency(asList(n), n[i]);
a[i][0] = n[i];
a[i][1] = count;
}
// printer helper function
for(int i = 0; i < n.length; i++){
System.out.print(a[i][0] + " occurs ");
System.out.println(a[i][1] + " times");
}
return a;
}
public static List<Integer> asList(final int[] is)
{
return new AbstractList<Integer>() {
public Integer get(int i) { return is[i]; }
public int size() { return is.length; }
};
}
public static void main(String[] args) {
int[] testArray = {1, 2, 3, 1, 2, 3, 4};
System.out.print(howMany(testArray));
}
}
Upvotes: 0
Reputation: 6780
You're making this way harder than it needs to be both by looping over the array twice and by using an array to store your result. Try this:
public class SortingInLinearTime {
public static Hashtable<Integer, Integer> howMany(int[] n){
Hashtable<Integer, Integer> toRet = new Hashtable<Integer, Integer>();
for (int i = 0; i < n.length; i++) {
if (!toRet .containsKey(n[i])) {
toRet.put(n[i], 1);
} else {
toRet.put(n[i], toRet.get(n[i]) + 1);
}
}
return toRet;
}
public static void main(String[] args) {
int[] testArray = {1, 2, 3, 1, 2, 3, 4};
Hashtable<Integer, Integer> counts = howMany(testArray);
Set<Integer> keys = counts.keySet();
for(Integer key : keys){
System.out.println(key + " occurs " + counts.get(key) + " times.");
}
}
}
This has several advantages. It will not break if you pass an array with large numbers, like {1, 11, 203, 203}
, which your current implementation cannot handle. It does not use extra space by declaring an array with many elements that you do not need. Most important, it works.
Upvotes: 0
Reputation: 81
In the first loop with i, you are recounting the same values again and again. 1 appears when i = 0 and when i = 3 as well. you once counted for 1 when i == 0 and recounted again at i == 3 in array n. However, I believe the best solution for your problem could be achieved by changing your data structure from int[][] to an hashmap.
Upvotes: 2