Reputation: 31
Hi I am trying to go through a two-dimensional array (specifically a 4x4 array) and both find any numbers that repeat, then count the number of times that the number repeats. So far I have 4 for loops that work however do more than what i really want.
int counter1 =1;
String huh="";
for (int x = 0; x< dataTable.length; x++)
{
for (int y=0; y< dataTable.length; y++)
{
for (int z = 0; z< dataTable.length; z++)
{
for (int a=0; a< dataTable.length; a++)
{
if ( x != z && x !=a && y != z && y !=a)
{
if (dataTable[x][y] == dataTable[z][a])
{
counter1++;
}
}
}
}
if (counter1 > 1)
{
huh += ("\n " + dataTable[x][y] + " repeats " + counter1 + " times!");
}
counter1=1;
}
}
Basically this works in the sense that it compares every number in my array with every other number including itself (but the if statement keeps it from counting itself). Basically i need the output to state something simple like
The number 3 repeats 3 times
However with the way that my setup works it would add to the string that same statement each time it compared the number 3 in each of its places in my array. So is my method correct at all and only needs some tweaking? or is it wrong altogether and i need something totally different? I am only in a beginner programming class at my college so we only know the basics of java so far like arrays, loops, and a few other things.
Upvotes: 3
Views: 5353
Reputation: 2918
You could have an array of n*n rows and 2 columns:
/*being n the number of rows/columns*/
int count[]][] = new int[n*n][2];
for (int i = 0; i < dataTable.length; i++) {
for (int k = 0; k < dataTable.length; k++) {
/*this loop finds the position in which it should go*/
for (int h = 0; h < n*n; h++) {
if (count[h][0] == dataTable[i][k]) {
break;
}
/*Assuming that '0' is not a possible number in dataTable, use '-1' or a number that */
if (count[h][0] == 0) {
break;
}
}
count[h][0] = dataTable[i][k];
count[h][1]++;
}
}
Upvotes: 0
Reputation: 129517
I think the best approach would be to maintain a Map<Integer, Integer>
that keeps track of the number frequencies (i.e. it maps each number in the array to the number of times it appears). It would not be hard to loop through the entire array and update this map accordingly. What you're doing now seems way more complicated than it really needs to be (in my opinion).
And why are you using 4 for-loops? Perhaps I'm misunderstanding the purpose of your specific code, but you should only need two to loop over a 2D-array (and to ultimately count the number-frequencies):
for (int[] a : array)
for (int i : a)
// do something
Relevant documentation:
Upvotes: 2
Reputation: 234807
The most general solution is to use a map, as others have suggested. However if the array values are within a relatively small range, you can use an array instead of a map. If min
is (at most) the smallest value in the array and max
is (at least) the largest value:
public int[] getFrequencyMap(int[][] array, int min, int max) {
int[] map = new int[max - min + 1];
for (int[] row : array) {
for (int val : row) {
map[val - min]++;
}
}
return map;
}
In the returned array, the value at index val - min
will be the number of times that the value val
occurs in the array.
Upvotes: 0
Reputation: 4640
Just convert this array into a Map<Integer, Integer>
and then print it out, like this:
public static void main(String[] args) throws Exception {
final int[][] dataTable = new int[][] {
new int[] {0, 1, 2, 1},
new int[] {0, 1, 3, 1},
new int[] {0, 1, 2, 2},
new int[] {0, 1, 2, 0}
};
final Map<Integer, Integer> map = new HashMap<Integer, Integer> ();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
final int value = dataTable[i][j];
final Integer currentCount = map.get(value);
final Integer newCount;
if (currentCount == null) {
newCount = 1;
}
else {
newCount = currentCount + 1;
}
map.put (value, newCount);
}
}
for (final Map.Entry<Integer, Integer> entry : map.entrySet()) {
System.out.println(String.format ("The number %d repeats %d times", entry.getKey(), entry.getValue()));
}
}
Here you can find the results.
Upvotes: 2