How Can I have index of a sorted array in Java?
For instance:
int[] myIntArray = new int[]{20,100,69,4};
and Arrays.sort(myIntArray) result is:
{4,20,69,100}
What if , index of original array is desired?
which means :
{3,0,2,1}
If I understood your problem correctly.
Considering there is no duplicates in you array. After you sort the array.
OPTION 1:
Writing a small helper method.
Passing each value to the below method and getting it's index.
public int findIndex(int[] iarray, int value) {
for(int i=0; i<iarray.length; i++)
if(iarray[i] == value)
return i;
}
OPTION 2:
Use org.apache.commons.lang Class ArrayUtils
public static int indexOf(int[] array,
int valueToFind)
Then,
If you are wanting to store these index in an array, take an array with initial array length and fill that array with returned index.
Declare a class that contains the index and the value, and sets up a comparator that compares just the values.
class IndexAndValue implements Comparable<IndexAndValue> {
public int index;
public int value;
public IndexAndValue(int index, int value) {
this.index = index;
this.value = value;
}
#Override
public int compareTo(IndexAndValue other) {
return Integer.compareTo(value, other.value);
}
}
Build an array of IndexAndValue of objects that contain the index and value.
IndexAndValue[] myIVArray = new IndexAndValue[myIntArray.length];
for (int i = 0; i < myIntArray.length, i++)
myIVArray[i] = new IndexAndValue(i, myIntArray[i]);
Now when you call sort on myIVArray, it will use the comparator to sort, which means it will compare the values. But the resulting array contains the IndexAndValue objects, which will keep the indexes together with the values.
(P.S. not tested, so it's possible I botched some syntax...)
(PPS. Public data members are usually evil, but I think it's OK for a small class like this whose purpose is just to hold a few values together. But if you don't like it, make them private and use accessor methods.)
I think a way to do this would be to create a class "intWithIndex" implementing Comparable. In that ways you could jeep track of the index.
public class IntWithIndex implements Comparable<IntWithIndex>{
public int value;
public int index;
#Override
Public int compareTo(intWithIndex x) {
return value - x.value;
}
}
public Test {
IntWithIndex[] myArray = ...
myArray[].sort;
}
IntWithIndex[].sort should then work, and you can check the initial indices with the index field.
Do you see what I mean ?
Additional to #SURESH ATTA, you can use Map to define your data structure, the key would be save as index and value would be your integers.
To get indexArray of sorted value without using any lib. Also take care of duplicate/multiple array element.
import java.util.Arrays;
public class IndexCal {
public static void main(String args[]) {
int[] myIntArray = new int[] { 20, 100, 69, 4, 20, 4, 100 };
int[] copyArray = new int[myIntArray.length];
System.arraycopy(myIntArray, 0, copyArray, 0, myIntArray.length);
Arrays.sort(myIntArray);
int[] indexArray = new int[myIntArray.length];
Arrays.fill(indexArray, -1);
for (int i = 0; i < copyArray.length; i++) {
int skiplength = 0;
int index = find(copyArray, myIntArray[i], 0);
while(find(indexArray, index, 0) != -1){
index = find(copyArray, myIntArray[i], skiplength++);
}
indexArray[i] = index;
}
for (int i = 0; i < copyArray.length; i++) {
System.out.println(indexArray[i]);
}
}
public static int find(int[] array, int value, int skiplength) {
for (int i = 0; i < array.length; i++)
if (array[i] == value)
if(skiplength == 0)
return i;
else
skiplength--;
return -1;
}
}
Related
help here will be greatly appreciated. I'm pretty stuck. What I have to do is I have to use the selection sort algorithm to sort an arraylist, but there are multiple indexes in each object in the arraylist. This has to be done in java.
For example:
public class a {
private int number;
private String letter;
public a(int n, String l)
{
number = n;
letter = l;
}
}
public class SortingArrays {
private ArrayList<a> myarray;
private Comparator<a> sortByNumber;
private Comparator<a> sortByLetter;
public FootballPlayerData() {
myarray = new ArrayList<a>();
getmyarray().add(new a(2, "A"));
getmyarray().add(new a(7, "J"));
//COMPARATORs//
sortByNumber = new Comparator<a>() {
#Override
public int compare(a o1, a o2)
{
if (o1.number < (o2.number)) {
return -1;
}
if (o1.number == (o2.number)) {
return 0;
}
return 1;
}
};
sortByLetter = new Comparator<a>() {
#Override
public int compare(a o1, a o2)
{
return o1.letter.compareTo(o2.letter);
}
};
public void selectionSortbyNumber
{
???
}
public void selectionSortbyLetter
{
???
}
}
So how do I create a selection sort in java (has to be selection sort) that sorts the arraylist by different elements within the objects? I already have the comparator part down, but I don't know how to incorporate that with selection sort.
A Comparator implementation is usually used to compare two elements with one another, returning -1 (or any negative number) if the first element is less than the second, 0 if they are equal, and 1 (or any positive number) if the first element is greater than the second. This can be used to compare two elements to see if one is greater, less than, or equal to the other.
In the context of selection sort, you can use a supplied comparator to determine which value in the unsorted portion of the list is the minimum. The general algorithm for selection sort is as follows:
for i from 0 to array.length:
current_minimum_index = i
for j from i + 1 to array.length:
if array at j is less than array at current_minimum_index:
current_minimum_index = j
swap array at current_minimum_index with array at i
The if array at j is less than array at current_minimum_index can be implemented using Comparator. For example, given a supplied ArrayList called array, the call to the Comparator object named comparator would be:
if (comparator.compare(array.get(j), array.get(current_minimum_index))) < 0)
I do not want to provide you with the complete answer, as that would not help you learn selection sorting, but the method signature for your sorting would resemble the following:
public <T> void selectionSort(ArrayList<T> array, Comparator<T> comparator) {
// for i from 0 to array.size():
// currentMinIndex = i
// for j from i + 1 to array.size():
if (comparator.compare(array.get(j), array.get(currentMinIndex))) < 0) {
// currentMinIndex = j
}
// swap array at currentMinIndex with array at i
}
Your call to this method would then look like one of the following:
selectionSort(myarray, sortByNumber);
selectionSort(myarray, sortByLetter);
Source from https://en.wikipedia.org/wiki/Selection_sort:
/* a[0] to a[n-1] is the array to sort */
int i,j;
int n;
/* advance the position through the entire array */
/* (could do j < n-1 because single element is also min element) */
int iMin;
for (j = 0; j < n-1; j++) {
/* find the min element in the unsorted a[j .. n-1] */
/* assume the min is the first element */
iMin = j;
/* test against elements after j to find the smallest */
for (i = j+1; i < n; i++) {
/* if this element is less, then it is the new minimum */
if (a[i] < a[iMin]) {
/* found new minimum; remember its index */
iMin = i;
}
}
}
if (iMin != j) {
swap(a[j], a[iMin]);
}
The method swap() just switch the values in the array.
Your job will be to swap the array with list. :P But that's not so hard because you can access the list value by index get(int index) method.
My question is how do I find the frequency of the numbers "8" and "88" in this array, using a method. It seems as what I put in the assessor method does not appear to work. For example, if "8" occurs three times in the array the output would be "3" and the same for "88".
If I am wrong please point me to the right direction. Any help with my question is greatly appreciate.
import java.util.Random;
public class ArrayPractice {
private int[] arr;
private final int MAX_ARRAY_SIZE = 300;
private final int MAX_VALUE = 100;
public ArrayPractice() {
// initialize array
arr = new int[MAX_ARRAY_SIZE];
// randomly fill array with numbers
Random rand = new Random(1234567890);
for (int i = 0; i < MAX_ARRAY_SIZE; ++i) {
arr[i] = rand.nextInt(MAX_VALUE) + 1;
}
}
public void printArray() {
for (int i = 0; i < MAX_ARRAY_SIZE; ++i)
System.out.println(arr[i]);
}
public int countFrequency(int value) {
for (int i: MAX_VALUE) {
if (i == 8)
i++;
}
public static void main(String[] args) {
ArrayPractice ap = new ArrayPractice();
System.out.println("The contents of my array are: ");
ap.printArray();
System.out.println("");
System.out.println("The frequency of 8 is: " + ap.countFrequency(8));
System.out.println("The frequency of 88 is: " + ap.countFrequency(88));
}
}
}
You need to iterate over arr and increment a variable when an element matches value.
public int countFrequency(int value) {
int count = 0;
for (int num : arr) {
if (num == value) {
count++;
}
}
return count;
}
You have a hard-coded seed, so your random values won't be random on different runs. You are also hard-coding your frequency count against 8 (instead of value). But honestly, I suggest you revisit this code with lambdas (as of Java 8), they make it possible to write the array generation, the print and the count routines in much less code. Like,
public class ArrayPractice {
private int[] arr;
private final int MAX_ARRAY_SIZE = 300;
private final int MAX_VALUE = 100;
public ArrayPractice() {
// randomly fill array with numbers
Random rand = new Random();
arr = IntStream.generate(() -> rand.nextInt(MAX_VALUE) + 1)
.limit(MAX_ARRAY_SIZE).toArray();
}
public void printArray() {
IntStream.of(arr).forEachOrdered(System.out::println);
}
public int countFrequency(int value) {
return (int) IntStream.of(arr).filter(i -> i == value).count();
}
}
You need to iterate over the array and increment a counter variable when an element matches i
what you are doing is increment i instead of a counter:
if (i == 8)
i++;
} // if i is 8 then i becomes 9
A working example:
public int countFrequency(int i) {
int count = 0;
for (int num : arr) {
if (num == i) {
count++;
}
}
return count;
}
Solution:
public int countFrequency(int value) {
int counter = 0; // here you will store counter of occurences of value passed as argument
for (int i : arr) { // for each int from arr (here was one of your errors)
if (i == value) // check if currently iterated int is equal to value passed as argument
counter++; // if it is equal, increment the counter value
}
return counter; // return the result value stored in counter
}
Explanation:
Main problem in your code was countFrequency() method, there are few bugs that you need to change if you want to make it work correctly:
You passed value as argument and you didn't even use it in the body of method.
for (int i : MAX_VALUE ) - you meant to iterate over elements of arr array, (You can read it then as: For each int from arr array do the following: {...}.
if (i == 8) i++ - here you said something like this: Check if the current element from array (assuming that you meant MAX_VALUE is an array) is equal to 8, and if it is - increment this value by 1 (so if it were 8, now it's 9). Your intention here was to increment counter that counts occurences of 8.
You might want to consider making these improvements to countFrequency() method, to make it work properly.
I have the task of determining whether each value from 1, 2, 3... n is in an unordered int array. I'm not sure if this is the most efficient way to go about this, but I created an int[] called range that just has all the numbers from 1-n in order at range[i] (range[0]=1, range[1]=2, ect). Then I tried to use the containsAll method to check if my array of given numbers contains all of the numbers in the range array. However, when I test this it returns false. What's wrong with my code, and what would be a more efficient way to solve this problem?
public static boolean hasRange(int [] givenNums, int[] range) {
boolean result = true;
int n = range.length;
for (int i = 1; i <= n; i++) {
if (Arrays.asList(givenNums).containsAll(Arrays.asList(range)) == false) {
result = false;
}
}
return result;
}
(I'm pretty sure I'm supposed to do this manually rather than using the containsAll method, so if anyone knows how to solve it that way it would be especially helpful!)
Here's where this method is implicated for anyone who is curious:
public static void checkMatrix(int[][] intMatrix) {
File numberFile = new File("valid3x3") ;
intMatrix= readMatrix(numberFile);
int nSquared = sideLength * sideLength;
int[] values = new int[nSquared];
int[] range = new int[nSquared];
int valCount = 0;
for (int i = 0; i<sideLength; i++) {
for (int j=0; j<sideLength; j++) {
values[valCount] = intMatrix[i][j];
valCount++;
}
}
for (int i=0; i<range.length; i++) {
range[i] = i+1;
}
Boolean valuesThere = hasRange(values, range);
valuesThere is false when printed.
First style:
if (condition == false) // Works, but at the end you have if (true == false) or such
if (!condition) // Better: not condition
// Do proper usage, if you have a parameter, do not read it in the method.
File numberFile = new File("valid3x3") ;
intMatrix = readMatrix(numberFile);
checkMatrix(intMatrix);
public static void checkMatrix(int[][] intMatrix) {
int nSquared = sideLength * sideLength;
int[] values = new int[nSquared];
Then the problem. It is laudable to see that a List or even better a Set approach is the exact abstraction level: going into detail not sensible. Here however just that is wanted.
To know whether every element in a range [1, ..., n] is present.
You could walk through the given numbers,
and for every number look whether it new in the range, mark it as no longer new,
and if n new numbers are reached: return true.
int newRangeNumbers = 0;
boolean[] foundRangeNumbers = new boolean[n]; // Automatically false
Think of better names.
You say you have a one dimensional array right?
Good. Then I think you are thinking to complicated.
I try to explain you another way to check if all numbers in an array are in number order.
For instance you have the array with following values:
int[] array = {9,4,6,7,8,1,2,3,5,8};
First of all you can order the Array simpel with
Arrays.sort(array);
After you've done this you can loop through the array and compare with the index like (in a method):
for(int i = array[0];i < array.length; i++){
if(array[i] != i) return false;
One way to solve this is to first sort the unsorted int array like you said then run a binary search to look for all values from 1...n. Sorry I'm not familiar with Java so I wrote in pseudocode. Instead of a linear search which takes O(N), binary search runs in O(logN) so is much quicker. But precondition is the array you are searching through must be sorted.
//pseudocode
int range[N] = {1...n};
cnt = 0;
while(i<-inputStream)
int unsortedArray[cnt]=i
cnt++;
sort(unsortedArray);
for(i from 0 to N-1)
{
bool res = binarySearch(unsortedArray, range[i]);
if(!res)
return false;
}
return true;
What I comprehended from your description is that the array is not necessarily sorted (in order). So, we can try using linear search method.
public static void main(String[] args){
boolean result = true;
int[] range <- Contains all the numbers
int[] givenNums <- Contains the numbers to check
for(int i=0; i<givenNums.length; i++){
if(!has(range, givenNums[i])){
result = false;
break;
}
}
System.out.println(result==false?"All elements do not exist":"All elements exist");
}
private static boolean has(int[] range, int n){
//we do linear search here
for(int i:range){
if(i == n)
return true;
}
return false;
}
This code displays whether all the elements in array givenNums exist in the array range.
Arrays.asList(givenNums).
This does not do what you think. It returns a List<int[]> with a single element, it does not box the values in givenNums to Integer and return a List<Integer>. This explains why your approach does not work.
Using Java 8 streams, assuming you don't want to permanently sort givens. Eliminate the copyOf() if you don't care:
int[] sorted = Arrays.copyOf(givens,givens.length);
Arrays.sort(sorted);
boolean result = Arrays.stream(range).allMatch(t -> Arrays.binarySearch(sorted, t) >= 0);
public static boolean hasRange(int [] givenNums, int[] range) {
Set result = new HashSet();
for (int givenNum : givenNums) {
result.add(givenNum);
}
for (int num : range) {
result.add(num);
}
return result.size() == givenNums.length;
}
The problem with your code is that the function hasRange takes two primitive int array and when you pass primitive int array to Arrays.asList it will return a List containing a single element of type int[]. In this containsAll will not check actual elements rather it will compare primitive array object references.
Solution is either you create an Integer[] and then use Arrays.asList or if that's not possible then convert the int[] to Integer[].
public static boolean hasRange(Integer[] givenNums, Integer[] range) {
return Arrays.asList(givenNums).containsAll(Arrays.asList(range));
}
Check here for sample code and output.
If you are using ApacheCommonsLang library you can directly convert int[] to Integer[].
Integer[] newRangeArray = ArrayUtils.toObject(range);
A mathematical approach: if you know the max value (or search the max value) check the sum. Because the sum for the numbers 1,2,3,...,n is always equal to n*(n+1)/2. So if the sum is equal to that expression all values are in your array and if not some values are missing. Example
public class NewClass12 {
static int [] arr = {1,5,2,3,4,7,9,8};
public static void main(String [] args){
System.out.println(containsAllValues(arr, highestValue(arr)));
}
public static boolean containsAllValues(int[] arr, int n){
int sum = 0;
for(int k = 0; k<arr.length;k++){
sum +=arr[k];
}
return (sum == n*(n+1)/2);
}
public static int highestValue(int[]arr){
int highest = arr[0];
for(int i = 0; i < arr.length; i++) {
if(highest<arr[i]) highest = arr[i];
}
return highest;
}
}
according to this your method could look like this
public static boolen hasRange (int [] arr){
int highest = arr[0];
int sum = 0;
for(int i = 0; i < arr.length; i++) {
if(highest<arr[i]) highest = arr[i];
}
for(int k = 0; k<arr.length;k++){
sum +=arr[k];
}
return (sum == highest *(highest +1)/2);
}
This is a homework assignment that I have not been able to complete. I am close, but I am having trouble understanding how to finish. Any help is greatly appreciated.
Implement a class Arrayplus1() that takes an integer array data and an int x as its size. Create a method inside the class Arrayplus1()
that creates a new array whose length is one greater than data’s length.
Then create a method to copy all data’s elements into the new array and add the value of x into the last element of the array.
Create a printall() method to return all the integers in the new array.
I am not sure what to do with the size = i part.
Code:
package addarray19;
class Arrayplus1{
int[]array ={1,2,3,4,5};
int[]newarray = array;
int size;
int data;
public Arrayplus1(int i){
size = i;
}
class Arrayadd{
int[]newarray = new int[array.length +1 ];
}
void printall(){
for(int i = 0; i < array.length; i++){
newarray[i] = array[i];
}
array = newarray;
}
void copy(){
System.arraycopy(array, 0, newarray, 0, array.length);
newarray[5] = 5;
}
}
public class Addarray19{
public static void main(String[] args) {
Addarray19 array = new Addarray19();
array.printall();
}
}
If I'm reading your requirements correctly, you're supposed to append the int x to your data array. Based on that assumption, the instruction to write a routine to first "grow" the data array might be implemented readily enough. First, set a default to 1 (because adding anything to an empty array should be a one element array). Next, check that the data isn't null. If it isn't take its' length and add one as the size. Then return a new int[] of length size like
static int[] growArray(int[] data) {
int size = 1;
if (data != null) {
size = 1 + data.length;
}
return new int[size];
}
Next, your method to add to the array is to first grow it then copy the values and finally append the new element at the end. Like,
private static int[] addToArray(int[] data, int x) {
int[] array2 = growArray(data);
if (data != null) {
System.arraycopy(data, 0, array2, 0, data.length);
}
array2[array2.length - 1] = x;
return array2;
}
Then, you can implement your required Arrayplus1 constructor like
private int[] data;
public Arrayplus1(int[] data, int x) {
this.data = addToArray(data, x);
}
Next, printall should do something like
public void printall() {
System.out.print(data[0]);
for (int i = 1; i < data.length; i++) {
System.out.printf(", %d", data[i]);
}
System.out.println();
}
Finally, your main() method should be instantiating Arrayplus1 instances... For example,
public static void main(String[] args) {
int[] in = { 1, 2, 3 };
int x = 4;
Arrayplus1 a = new Arrayplus1(null, 1);
a.printall();
Arrayplus1 b = new Arrayplus1(in, x);
b.printall();
}
and the output is
1
1, 2, 3, 4
I think you are overlooking the first requirement. The constructor should take BOTH an integer array AND an int for size. The int for size in the class should represent and remember the length of data stored in int[] array
class Arrayplus1{
int[] array;
int size;
public Arrayplus1(int[] a, int i){
array = a;
size = i;
}
}
I would like to find the index/indices that hold the maximum value in an ArrayList. I want to preserve the order that the numbers are in (in other words no sorting) because I want to keep track of what index had what value. The values are from a random number generator and there is the possibility of having two (or more) indices sharing the same maximum value.
An example ArrayList:
12, 78, 45, 78
0,1,2,3 <- indices
(So indices, 1 and 3 contain the values that have the max values. I want to maintain the fact that indices 1 and 3 have the value 78. I do not want to just create a new ArrayList and have indices 0 and 1 of the new ArrayList have the values 78)
Therefore, I want to find all of the indices that have the maximum values because I will be doing something with them to "break" the tie if there is more than one index. So how can I find the indices that contain the maximum value and maintain the index-to-value relationship?
I have written the following methods:
public static ArrayList<Integer> maxIndices(ArrayList<Integer> numArrayList) {
// ???
return numArrayList;
}
public static void removeElement(ArrayList<Integer> numArrayList, int index) {
numArrayList.remove(index);
}
public static int getMaxValue(ArrayList<Integer> numArrayList) {
int maxValue = Collections.max(numArrayList);
return maxValue;
}
public static int getIndexOfMaxValue(ArrayList<Integer> numArrayList, int maxVal) {
int index = numArrayList.indexOf(maxVal);
return index;
}
public static ArrayList<Integer> maxIndices(ArrayList<Integer> list) {
List<Integer> indices = new ArrayList<Integer>();
int max = getMaxValue(list);
for (int i = 0; i < list.size(); i++) {
if(list.get(i) == max) {
indices.add(list.get(i));
}
}
return indices;
}
O(n) solution:
public static List<Integer> maxIndices(List<Integer> l) {
List<Integer> result = new ArrayList<Integer>();
Integer candidate = l.get(0);
result.add(0);
for (int i = 1; i < l.size(); i++) {
if (l.get(i).compareTo(candidate) > 0) {
candidate = l.get(i);
result.clear();
result.add(i);
} else if (l.get(i).compareTo(candidate) == 0) {
result.add(i);
}
}
return result;
}