Finding index of an item within a 2D Array - java

After some research, I found out how to find the index of an item within a 2D Array. However, I'm after just one value, the row number and also what if the item you are looking for appeared more than once?
How would you store the row number of all those times?
for(int j = 0; j < size; j++)
{
if (arr[i][j] == 88)
{
return i; // The value i wanna store
break;
}
}
If the number 88 appears more than once, how can I store all the different locations and later retrieve it?

You could store the values you want in a List.
List<Integer> rows = new ArrayList<>();
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (arr[i][j] == 88) {
rows.Add(i); // The value i wanna store
break; // exit inner loop and continue with next row
}
}
}

i'm after just one value, the row number
But if 88 appears more than once, how can I store all the different
locations and later retrieve it?
Considering you don't know how many duplicated copies of the value you're looking for there could be, I'd suggest using an ArrayList to store the indexes.
create this before the loops:
List<Integer> indexList = new ArrayList<>();
then within the if block simply add the index value for the value you've found to the ArrayList:
if (arr[i][j] == 88){
indexList.add(i);
break;
}
you can then return the ArrayList if your method requires returning the data:
return indexList; // after the loops have finished processing
However, if the method return type is void then you can simply ignore the return indexList;

Related

Nested loop only access X elements at once

I need to access all elements of a list, but only ever 10 elements at most in one go. For this I thought about a nested loop like this:
for (int i = 0; i < 50 / 10; i++) {
for (int k = 0; k < 10; k++) {
paramList.addParam(xyz)
}
sendRequest(paramList);
}
With this nested loop I can access all elements from 0-49 and only ever 10 elements in the inner loop. My problem occurs when the list only hast 49 elements instead of 50. Then I only get up to 39 elements with this logic. Also my best thought on only accessing e.g. 5 elements in the last iteration (list size = 45), is to break the loop, before it goes any further.
So my question is, how can I access all elements in a List with undefined size, but only a maximum of 10 elements in the inner loop (and less if list size doesn't allow 10)?
As an option you can just iterate in outer loop using step of 10 elements:
int step = 10;
for (int i = 0; i < list.size(); i+=step) {
for (int k = i; k < i + step && k < list.size()); k++) {
System.out.println(list.get(k));
}
}
I had to find a reason for your need, breaking the iteration with an inner loop like your snippet doesn't do anything useful, it's still iterate a list.
The only reason I see your logic needed is if you want to call a method after 10 element like :
for (int i = 0; i < 50 / 10; i++) {
for (int k = 0; k < 10; k++) {
System.out.println((i * 10) + k);
}
System.out.println("####");
}
That would make sense, but that second loop is not needed and also give a "complex" code to understand.
As an alternative, you can iterate normally a list and add a condition to execte that method. It gives a much more readable code
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
if( (i + 1)%10 == 0){ //add one to not trigger this on the first iteration
System.out.println("####");
}
}
From your comment:
I retrieve up to 50 records from my database. For each record I need to create a request which will be send in a POST request. Each POST request can contain 10 data requests and I can only send 5 of those request per minute (5*10=50). Since I always fetch TOP 50 data from my database, it can happen that I only get 35 entries instead of 50. To create my requests, I need that data from my database and therefore I have to iterate the whole list, but only ever 10 elements in 1 go to create 1 full POST request
I can see the need here, let's assume you have an instance post that have two method addParam and sendRequest. You need to iterate the list to send String parameters :
int i = 0;
for(String s : params){
post.addParam(s);
if( ++i % 10 == 0){
post.sendRequest();
}
}
//If the last `addParam` was not sended, we check again.
if( i % 10 != 0){
post.sendRequest();
}
Note the condition change outside the loop
as user7 say, you can add a condition to the nested loop
for (int i = 0; i < list.size(); i+=10) {
for (int k = i; k < list.size() && (k-i) < 10; k++) {
System.out.println(k);
}
}

Java - Multidimensional Arrays How to test an array for all unique values

I'm trying to test a multidimensional array to see if contains any duplicate values. If it does I would like the method to return false. Otherwise I would like it to return true.
Here is my current code. Where is my logic wrong?
public static boolean isUnique(int[][] array2, int num) {
for (int i = 0; i < array2.length - 1; i++) {
for (int j = i + 1; j < array2.length; j++) {
if (array2[i] == array2[j]) {
return false;
}
}
}
return true;
}
Your current implementation is checking whether two rows are the same (this is a reference based check, rather than a value.) This means that it asks 'Are array2[i] and array2[j] the same address in memory, rather than do they contain the same things.
If you want to see whether the rows are unique you'd use array2[i].equals(array2[j]) instead of array2[i] == array2[j].
If you wanted to check for unique elements (array[i][j] != array2[i+m][j+n] where !(m == n == 0)) you'd need to iterate through both levels in a
for (int i = 0; i < array2.length; i++) {
for (int j = 0; j < array2[i].length; j++) {
// compare array2[i][j] to all other array2[m][n] here.
}
}
Right now your code is checking whether any of the arrays inside array2 are the same. array2[i] and array2[j] are both referring to arrays, because array2 is an array of arrays.
Instead, you want to look at the values inside of each of those arrays. Since you want to fail on any repeated value anywhere in the grid, you're effectively trying to flatten the structure into one collection, and check for duplicates in that.
A HashSet is the best data structure to use in this case. Traverse the entire grid, row-by-row, adding values into your new struture. If you encounter a duplicate, return false:
public static boolean isUnique(int[][] array2) {
Set<Integer> values = new HashSet<>();
for (int i = 0; i < array2.length; i++) {
for (int j = 0; j < array2[i].length; j++) {
if (!values.add(array2[i][j])) {
return false;
}
}
}
return true;
}
Some things to note here:
The set's add method will return false if you attempt to add a duplicate to the collection, so that's wrapped in an if statement for a simple, fail-fast stopping condition.
The sizes of each of the inner arrays are completely independent from the size of the outer array, so you still want to loop from 0 to the length of the array (when you're using <, you don't need the length - 1).

The most common element in 2d array.How to optimize?

I have this task, find the most commonly seen element in int[][] array and print the number and times repeated.I solved the problem.
A friend of mine said that having 4 for()s is a bad idea.So I decided to try optimising it to remove one or two, but couldn't figure a way.
So here it is:
int cnt, element = arr[0][0], numberRepeats = 0;//cnt-counter,what's the element ,how many times it's repeated
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {//those two for's are for the current element
cnt = 0;//counter is nullified
for (int j2 = i; j2 < arr.length; j2++) {
for (int k = 0; k < arr[j2].length; k++) {//and those two are the compared element
if (arr[i][j] == arr[j2][k]) {//if the current element is the same as the compared element,increase counter
cnt++;
}
}
if (cnt > numberRepeats) {//after the compared element is done comparing and the number of repeats of the current element is more then the lastly checked element
element = arr[i][j];//we get the element ,and how many times it's repeated
numberRepeats = cnt;
}
}
}
}
The only optimisation that I could think of was starting the counting from the current element till the end.
Please give me some more ideas. All the answers I could find were for the 1D array, and they were all pretty much the same code.
You can just iterate your whole array and count the occurrences of every element in a map.
Map<Integer, Integer> elementsCounts = new HashMap<>();
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
Integer count = elementsCounts.get(arr[i][j]])
if(count == null){
count = 0
}
elementsCounts.put(arr[i][j]], count+1)
}
}
Now all it gets is to find the key with the maximum value in the map.
We need to use Map and as well as Set (Set to identify the duplicate elements in a row), only using Map will overlook an edge case scenario where duplicate value in a row may result in incrementing the counter. And finally will be considered as a common value.
Summarizing in below steps:
Populate map with key as a the value of array [i][j] and Map's value as a counter.
IF element is absent in the Map then add key-value pair, Mpa's value as counter initializing from 1.
ELSE, update the element in the Map incrementing the counter with 1
Before incrementing the counter check for duplicate value in the row using Set
Finally, iterate the Map using entrySet() and print only those element whose counter is equal to length of array.
input e.g.:
Integer [][] array = {{1,2,3},{1,4,5,5},{1,5,7}};
output result:
{1}

Gets the number of duplicates in the list - wrong output

How to count duplicates in ArrayList and count only once.
Here is what I have so far:
/**
* Gets the number of duplicates in the list.
* Get the next word. It is at index i. Does it match any of the words with index > i?)
* #return the number of duplicate words in the list
*/
public int countDuplicates() {
int duplicates = 0;
for (int i = 0; i < list.size(); i++) {
for (int j = i; j < list.size(); j++) {
if (list.get(i).equals(j)) duplicates++;
}
}
return duplicates;
}
Here is check output:
Actual: 0
Expected: 3
I am missing something very easy. However, couldn't find what exactly it is.
How to solve this trouble?
You don't get the jth element you just compare to j directly. And as a commenter points out, j should start at i+1 to avoid comparing an element to itself. Therefore, you need to write
public int countDuplicates()
{
int duplicates = 0;
for (int i = 0; i < list.size(); i++) {
for (int j = i+1; j < list.size(); j++) {
if (list.get(i).equals(list.get(j))) duplicates++;
}
}
return duplicates;
}
Should be:
public int countDuplicates()
{
int duplicates = 0;
// TODO: Write the code to get the number of duplicates in the list
for (int i = 0; i < list.size(); i++) {
for (int j = i + 1; j < list.size(); j++) {
if (list.get(i).equals(list.get(j))) duplicates++;
}
}
return duplicates;
}
Use two sets for this:
final Set<X> set = new HashSet<>();
final Set<X> dups = new HashSet<>();
int dupCount = 0;
for (final X x: list) {
if (set.add(x)) // first time the element is seen
continue;
// Dup; see whether it is the first time we see it
if (dups.add(x))
dupCount++;
}
return dupCount;
This relies on the fact that Set's .add() returns true if and only if the set has been modified as the result of the operation. And note that it traverses the list only once.
I can see three problems with your current code:
You are not comparing pairs of elements. You are actually comparing an element with an index.
Your inner loop is comparing element i and element i ... and that would result in a false "duplicate" count.
If you have more than 2 copies of any given element, then you will get too many duplicate counts. (To see why, try to "hand execute" with a list of (say) three identical elements.
In fact, you have to EITHER use an auxiliary data structure (e.g. 2 Sets or a Map) OR modify the input list to avoid counting duplicates more than once.
I would note that your statement of the problem is ambiguous. "... only count each duplicate once" could mean that '[1, 1, 1]' gives either 1 or 2. It depends whether you consider each individual 1 to be a duplicate to be counted once or that we have 1 as one of a set of duplicates ... that must only be counted once.
You are comparing index j value instead of value of list list.get(j).
Do
if (list.get(i).equals(list.get(j)))
instead of
if (list.get(i).equals(j))

Checking rows of 2d ArrayList for specific values

I am trying to scan every row of a 2d array (100x100 sizes) and make sure that every row (and later column) will have only 1 instance of every integer 1 through 100. In the following code I am trying to make sure every row only has one instance of every integer 1 through 100, but obviously the syntax does not work. Is there any method that could push this through or what am I missing?
Thanks for any assistance
for(int i = 0; i<100; i++) {
for (int j=0; j<100 ; j++) {
if(2dARR.get(i).get(j).contains(1) && 2dArr.get(i).get(j).contains(2)(.....)) {
System.out.println("FK");
}
}
}
Dump it into a Set, check that the size of the Array and Set are Equal. If they aren't, there are duplicates. If you get past that test, run a loop through the array and check that all values are greater than 0 and less than 101 (1-100).
for(int i = 0; i<100; i++) {
Set<Integer> numbersInRow = new HashSet<Integer>();
for (int j=0; j<100 ; j++) {
int num = 2dARR.get(i).get(j);
if (num < 1 || num > 100) {
// out of bounds, handle error
}
else {
numbersInRow.add(num);
}
}
// At this point we have the set of numbers found in the row, all guaranteed to be >=1 and <= 100
if (numbersInRow.size() != 100) {
// at least one number appeared more than once
}
}

Categories