Finding all Indices of a number from an Array (Java) - java

Say I have an array of:
int [] I = { 1, 3, 6, 3, 7,3, 9, 3};
int value = 3;
I have a for loop that tracks the amount of occurences of the value:
int counter = 0;
for(int x = 0; x < I.length; x++)
{
if(I[x] == value)
{
counter++;
}
}
I make a new array with length equal to the number of occurrences, that can store all the indices of the occurences from the original array:
int [] index = new int [counter];
for(int x = 0; x < index.length; x++)
{
for(int i = 0; i<I.length; i++)
{
if(I[i] == value){
index[x] = i;
}
}
}
However, when I print my array of indices, i just get the last index printed the amount of times counter is equal to, when I want all the indices.
for(int i = 0; i<index.length; i++)
{
System.out.println(index[i]);
}
It just prints "7" (the last index) 3 times. How do I go about fixing this so I have an array of all indices?
Thank you.

Your second for loop should not be nested; you should only increment x when you find a match. Something like,
for (int i = 0, x = 0; i < I.length; i++) {
if (I[i] == value) {
index[x] = i;
x++;
}
}
Assuming you're using Java 8+, you could have written a filter() on the range of indices in the array. Like,
int[] index = IntStream.range(0, I.length).filter(i -> I[i] == value).toArray();
System.out.println(Arrays.toString(index));

Just remove the outer for loop and store into the index array as you iterate through the original array I. The problem with your code is that, since you repeat the iterations once for each index in the index array, you end up with the last found index (7 in your case).
for(int i = 0, x = 0; i < I.length; i++) {
if(I[i] == value) {
index[x++] = i;
}
}

Related

Can't understand why loop is not updating variable value

When I create this method to find the index of the smallest number in an array starting from a specific index, it keeps returning 0 no matter which numbers are in the array. It seems that index = i in the for loop is not updating the value of the index variable, even if the array contains other numbers lower than the 0 spot. Why?
public static int indexOfSmallestFrom(int[] array, int startIndex) {
int smallest = array[startIndex];
int index = 0;
for (int i = startIndex; i < array.length; i++) {
int each = array[i];
if (each < smallest) {
smallest = each;
index = i;
}
}
return index;
}
edit: Here's the main method:
public static void main(String[] args) {
// write your test code here
int[] array = {99, 3, 1, 7, 4, 5, 2, 4};
System.out.println("Smallest: " + indexOfSmallestFrom(array, 1));
}
It works correctly every time EXCEPT when the startIndex variable passed to the method call is 2! When a 1 is passed as above, it correctly returns 2, when 3 is passed, it correctly returns 6, etc. ???
Because when you pass startIndex = 2 into the function, we have smallest = array[startIndex] = 1 in this case, and your code initializes int index = 0;. However, in your for loop, you have:
for (int i = startIndex; i < array.length; i++) {
int each = array[i];
if (each < smallest) {
smallest = each;
index = i;
}
}
Since your smallest was initialized to the number at position startIndex but not your index, and the fact that startIndex happened to be the index of the smallest number, your if (each < smallest) will never be entered, meaning that index will stay at 0.
To fix this, either change int index = 0; to int index = startIndex; OR you can change the condition in the if statement to if (each <= smallest) and your code should work fine (note that if you do this, it will return the last index if multiple minimums are present in the array).
Your code works for me, may be the smallest value is in 0 place in your case. But you should change index = startingIndex. Because that is where you are comparing items from.
public static int indexOfSmallestFrom(int[] array, int startIndex) {
int smallest = array[startIndex];
int index = startIndex;
for (int i = startIndex; i < array.length; i++) {
int each = array[i];
if (each < smallest) {
smallest = each;
index = i;
}
}
return index;
}
Or change < to <=
public static int indexOfSmallestFrom(int[] array, int startIndex) {
int smallest = array[startIndex];
int index = 0;
for (int i = startIndex; i < array.length; i++) {
int each = array[i];
if (each <= smallest) {
smallest = each;
index = i;
}
}
return index;
}
Because the value in position 2 is the SMALLEST value (it's 1), hence the if condition is never entered :).

(Java) Search indexes of values of an array in another array

I have written the following code that takes two arrays and searches the index of the first occurrence of each value from the first array in the second one. For example if first = {15, 10, 18, 17, 15} and second = {10, 15, 10, 17} then the output would be an array with an equal length to first which contains the indices output = {1, 0, -1, 3, 1}, as e.g. 15 occurs in index 1 of the second array, 10 occurs at the 0th index, etc. The index will be -1 if the value in first doesn't occur in second. The code I've written to loop through the arrays is as follows:
public static int[] searchIndexes(int[] first, int[] second) {
int[] indices = new int[first.length];
int index = -1;
for (int i = 0; i < first.length; i ++) {
for (int j = 0; j < second.length; j ++) {
if (first[i] == second[j])
index = j;
}
indices[i] = index;
}
return indices;
}
However, for the given example the output is instead {1, 2, 2, 3, 1}. I think I do understand the issue; since 10 occurs twice in second then the index of the second occurrence is recorded, but I don't know how to get around this. Putting a break; statement after the if clause doesn't seem to fix it.
This would be straightforward by using the ArrayUtils.indexOf() utility method. Moving through the second array, call ArrayUtils.indexOf() for each of its elements in reference to the first array, storing the results in the indices array. This will also mean that there would be a single loop, not a nested loop.
The ArrayUtils class is a part of the org.apache.commons.lang3 library.
A different option, not requiring an external library, would be to convert your arrays to Lists and then take advantage of the List.indexOf() method.
I hope that helps!
Two issues in your code:
Once index is set to any value at all, it can never again become -1
Once you find the first occurrence in the second array, you keep going - need a break.
Updated code:
public static int[] searchIndexes(int[] first, int[] second) {
int[] indices = new int[first.length];
int index;
for (int i = 0; i < first.length; i ++) {
// reset index on each iteration
index = -1;
for (int j = 0; j < second.length; j ++) {
if (first[i] == second[j]) {
// once the first match is found, break out of the inner loop
index = j;
break;
}
}
indices[i] = index;
}
return indices;
}
try this
public static int[] searchIndexes(int[] first, int[] second) {
int[] indices = new int[first.length];
//fill all values with -1
Arrays.fill(indices,0,first.length - 1, -1);
for (int i = 0; i < first.length; i++) {
for (int j = 0; j < second.length; j++) {
// when you met with same value fill your indices array with second array's value's index and break the loop
if (first[i] == second[j]) {
indices[i] = j;
break;
}
}
}
return indices;
}
Just add break after found the element and reset the index
public static int[] searchIndexes(int[] first, int[] second) {
int[] indices = new int[first.length];
int index = -1;
for (int i = 0; i < first.length; i++) {
index = -1;
for (int j = 0; j < second.length; j++) {
if (first[i] == second[j]) {
index = j;
break;
}
}
indices[i] = index;
}
return indices;
}
, main
public static void main(String args[]) {
int[] indices = searchIndexes(new int[] { 15, 10, 18, 17, 15 }, new int[] { 10, 15, 10, 17 });
for (int i = 0; i < indices.length; i++)
System.out.print(indices[i] + " ");
System.out.println();
}
, output
1 0 -1 3 1

Insert value to 2d array

I have a loop to loop through 0-200 and if the number matches the number in the list. I will put it inside the freq[][]. However, I'm having problem into putting the numbers I found into the freq[][] considering that it needs to be in the size of [10][20].
public static void example(List<Integer> numbers, List<Integer> elements, int[][] list){
int index = 0;
int[][] freq = new int[10][20];
for (int i = 0; i < 200; i++){
for (int x = 0; x < list.length; x++){
for (int y = 0; y < list[x].length; y++){
if (list[x][y] == i){
freq[][index] = i;
}
}
}
}
}
Keep it as
if (list[x][y]== i){
freq[x][y] = i;
}
else {
freq[x][y] = 0; // if not matched
}
So that freq will be a two dimensional array with 10rows and 20 columns .
-Element at 5th index position in the list will be in 0*5th position in the 10*20 array.
-Element at 199 th index position in the list will be in 9*19th position in the 10*20 array.
first, you make a loop to read 200 numbers inside this loop you want to loop 2d array to compare its elements by every number and make condition if a number exist in list but it in freq[][] this code put every number Achieves the condition in freq array and otherwise but 0
for (int i = 0; i <= 200; i++) {
for (int j = 0; j < list.length; j++) {
for (int k = 0; k < list[j].length; k++) {
if(list[j][k]==i)
freq[j][k]=i;
}
}
}
if you use `
else
freq[j][k]=0;
`
that mean it start putting in array the number or 0, and finally, you get an array don't match you want, so let if condition only without else I test it and it work for me

Given two sorted lists (or arrays) and a number k, create an algorithm to fetch the least k numbers of the two lists

Need to find the first 3 smallest number in given two sorted array. I supposed that two array should merge into one first and sort it in order to fetch the first 3 smallest number. Can anyone help me with the merge and sort part or provide some advice, any help will appreciate.
This is where i reached now, I only can get the smallest number ( not first 3, just one).
public class MergeandSort {
public static void main(String[] args) {
int[] set1 = {1,2,6,9,18};
int[] set2 = {2,3,7,10,21,30};
int smallest = set1[0];
int smallests = set2[0];
for(int i=0; i < set1.length; i++){
if(set1[i] < smallest)
smallest = set1[i];
}
for(int k=0; k < set2.length; k++){
if(set2[k] < smallests)
smallests = set2[k];
}
System.out.println("Smallest Number in Set 1 is : " + smallest);
System.out.println("Smallest Number in Set 2 is : " + smallests);
}
}
The arrays are already sorted, so you don't have to iterate over the entire arrays to find the 3 smallest numbers.
You just have to start iterating over both arrays at the same time (i.e. in the same loop).
In each iteration you compare the current two elements of the two arrays (starting at the 2 elements at the 0 index) and take the smaller of them
Then you advance the index of the array from which you took the smallest number.
Once you reach 3 elements (after 3 iterations), you break out of the loop.
Here's some pseudo code to get you started:
int i = 0;
int j = 0;
int c = 0;
int[] lowest3 = new int[3];
while (true) {
find the smaller of set1[i] and set2[j] and put it in lowest3[c]
if set1[i] is smaller, increment i
otherwise increment j
increment c
if (c==3) // you are done
break;
}
the lowest3 array now contains the 3 lowest numbers of both arrays
Of course you can swap 3 with any k. You just have to make sure that i is always smaller than set1.length and j is always smaller than set2.length.
If the arrays are already sorted, just implement the merging technique of merge sort with the limitation in while condition that it should run only k times (in this case 3), but dont forget to check that size of sets are less than k or not!
int k = 0,i = 0,j = 0;
while (k<3 && k<set1.length && k<set2.length )
{
if (set1[i] <= set2[j])
{
final_set[k] = set1[i];
i++;
}
else
{
final_set[k] = set2[j];
j++;
}
k++;
}
while (k<3 && k<set1.length) {
final_set[k]=set1[i];
k++;
i++;
}
while (k<3 && k<set2.length) {
final_set[k]=set1[j];
k++;
j++;
}
public class MergeandSort {
public static void main(String[] args) {
int[] set1 = {1,2,6,9,18};
int[] set2 = {2,3,7,10,21,30};
int[] sorted = new int[k];
int smallest = set1[0];
int smallests = set2[0];
int i = 0, j = 0, c = 0;
while(i < set1.length && j < set2.length && c < k){
if (set1[i] < set2[j])
sorted[c++] = arr1[i++];
else
sorted[c++] = arr2[j++];
while (i < set1.length && c < k)
sorted[c++] = arr1[i++];
while (j < set2.length && c < k)
sorted[c++] = arr2[j++];
System.out.println(sorted);
}
}
where k is the count of sorted numbers you want
That would not work as:
Array1 = {1,3,5}
Array2 = {2,3,4}
Correct solution: {1,2,3}
Output of your solution: {1,3,4}

Getting the most "popular" number from array

I need for homework to get the most "popular" number in an array (the number in the highest frequency), and if there are several numbers with the same number of shows, get some number randomly.
After more then three hours of trying, and either searching the web, this is what I got:
public int getPopularNumber(){
int count = 1, tempCount;
int popular = array[0];
int temp = 0;
for ( int i = 0; i < (array.length - 1); i++ ){
if ( _buses[i] != null )
temp = array[i];
tempCount = 0;
for ( int j = 1; j < _buses.length; j++ ){
if ( array[j] != null && temp == array[j] )
tempCount++;
}
if ( tempCount > count ){
popular = temp;
count = tempCount;
}
}
return popular;
}
This code work, but don't take into account an important case- if there is more than one number with the same count of shows. Then it just get the first one.
for example: int[]a = {1, 2, 3, 4, 4, ,5 ,4 ,5 ,5}; The code will grab 4 since it shown first, and it's not random as it should be.
Another thing- since it's homework I can't use ArrayList/maps and stuff that we still didn't learn.
Any help would be appreciated.
Since they didn't give you any time complexity boundary, you can "brute force" the problem by scanning the the array N^2 times. (disclaimer, this is the most intuitive way of doing it, not the fastest or the most efficient in terms of memory and cpu).
Here is some psuedo-code:
Create another array with the same size as the original array, this will be the "occurrence array"
Zero its elements
For each index i in the original array, iterate the original array, and increment the element in the occurrence array at i each time the scan finds duplicates of the value stored in i in the original array.
Find the maximum in the occurrence array
Return the value stored in that index in the original array
This way you mimic the use of maps with just another array.
If you are not allowed to use collection then you can try below code :
public int getPopularNumber(){
int inputArr[] = {1, 2, 3, 4, 4, 5 ,4 ,5 ,5}; // given input array
int[] tempArr = new int[inputArr.length];
int[] maxValArr = new int[inputArr.length];
// tempArr will have number as index and count as no of occurrence
for( int i = 0 ; i < inputArr.length ; i++){
tempArr[inputArr[i]]++;
}
int maValue = 0;
// find out max count of occurrence (in this case 3 for value 4 and 5)
for( int j = 0 ; j < tempArr.length ; j++){
maValue = Math.max(maValue, tempArr[j]);
}
int l =0;
// maxValArr contains all value having maximum occurrence (in this case 4 and 5)
for( int k = 0 ; k < tempArr.length ; k++){
if(tempArr[k] == maValue){
maxValArr[l] = k;
l++;
}
}
return maxValArr[(int)(Math.random() * getArraySize(maxValArr))];
}
private int getArraySize(int[] arr) {
int size = 0;
for( int i =0; i < arr.length ; i++){
if(arr[i] == 0){
break;
}
size++;
}
return size;
}
that's hard as hell :D
After some trying, I guess I have it (If there will be 2 numbers with same frequency, it will return first found):
int mostPopNumber =0;
int tmpLastCount =0;
for (int i = 0; i < array.length-1; i++) {
int tmpActual = array[i];
int tmpCount=0;
for (int j = 0; j < array.length; j++) {
if(tmpActual == array[j]){
tmpCount++;
}
}
// >= for the last one
if(tmpCount > tmpLastCount){
tmpLastCount = tmpCount;
mostPopNumber = tmpActual;
}
}
return mostPopNumber;
--
Hah your code give me idea- you cant just remember last most popular number, btw I've found it solved there Find the most popular element in int[] array
:)
EDIT- after many, and many years :D, that works well :)
I've used 2D int and Integer array - you can also use just int array, but you will have to make more length array and copy actual values, Integer has default value null, so that's faster
Enjoy
public static void main(String[] args) {
//income array
int[] array= {1,1,1,1,50,10,20,20,2,2,2,2,20,20};
//associated unique numbers with frequency
int[][] uniQFreqArr = getUniqValues(array);
//print uniq numbers with it's frequency
for (int i = 0; i < uniQFreqArr.length; i++) {
System.out.println("Number: " + uniQFreqArr[i][0] + " found : " + uniQFreqArr[i][1]);
}
//get just most frequency founded numbers
int[][] maxFreqArray = getMaxFreqArray(uniQFreqArr);
//print just most frequency founded numbers
System.out.println("Most freq. values");
for (int i = 0; i < maxFreqArray.length; i++) {
System.out.println("Number: " + maxFreqArray[i][0] + " found : " + maxFreqArray[i][1]);
}
//get some of found values and print
int[] result = getRandomResult(maxFreqArray);
System.out.println("Found most frequency number: " + result[0] + " with count: " + result[1]);
}
//get associated array with unique numbers and it's frequency
static int[][] getUniqValues(int[] inArray){
//first time sort array
Arrays.sort(inArray);
//default value is null, not zero as in int (used bellow)
Integer[][] uniqArr = new Integer[inArray.length][2];
//counter and temp variable
int currUniqNumbers=1;
int actualNum = inArray[currUniqNumbers-1];
uniqArr[currUniqNumbers-1][0]=currUniqNumbers;
uniqArr[currUniqNumbers-1][1]=1;
for (int i = 1; i < inArray.length; i++) {
if(actualNum != inArray[i]){
uniqArr[currUniqNumbers][0]=inArray[i];
uniqArr[currUniqNumbers][1]=1;
actualNum = inArray[i];
currUniqNumbers++;
}else{
uniqArr[currUniqNumbers-1][1]++;
}
}
//get correctly lengthed array
int[][] ret = new int[currUniqNumbers][2];
for (int i = 0; i < uniqArr.length; i++) {
if(uniqArr[i][0] != null){
ret[i][0] = uniqArr[i][0];
ret[i][1] = uniqArr[i][1];
}else{
break;
}
}
return ret;
}
//found and return most frequency numbers
static int[][] getMaxFreqArray(int[][] inArray){
int maxFreq =0;
int foundedMaxValues = 0;
//filter- used sorted array, so you can decision about actual and next value from array
for (int i = 0; i < inArray.length; i++) {
if(inArray[i][1] > maxFreq){
maxFreq = inArray[i][1];
foundedMaxValues=1;
}else if(inArray[i][1] == maxFreq){
foundedMaxValues++;
}
}
//and again copy to correctly lengthed array
int[][] mostFreqArr = new int[foundedMaxValues][2];
int inArr= 0;
for (int i = 0; i < inArray.length; i++) {
if(inArray[i][1] == maxFreq){
mostFreqArr[inArr][0] = inArray[i][0];
mostFreqArr[inArr][1] = inArray[i][1];
inArr++;
}
}
return mostFreqArr;
}
//generate number from interval and get result value and it's frequency
static int[] getRandomResult(int[][] inArray){
int[]ret=new int[2];
int random = new Random().nextInt(inArray.length);
ret[0] = inArray[random][0];
ret[1] = inArray[random][1];
return ret;
}

Categories