Arraylist basics - java

Write a method that recieves an ArrayList of integers as a parameter and returns the index of the largest integer in the collection.
So far I only have the code needed to receive an ArrayList of integers, search for a specific integer and return true.
Can anyone tell me what the int key is needed for? Wouldn't the code work without it?
public static boolean search (ArrayList<Integer>list, int key) {
for (int=0 ; i< listsize(); i++)
if (list.get(i) == key) {
return true;
} return false;
}

This should do the trick:
public int getIndexOfMaxValue(final List<Integer> list)
{
int maxFound = Integer.MIN_VALUE, value;
int ret = 0;
for (int index = 0; index < list.size(); index++) {
value = list.get(index);
if (value > maxFound) {
maxFound = value;
ret = index;
}
}
return ret;
}
Note that lists can have duplicate elements and that this code will return the index of the first maximum found. If you want the last index, just replace > with >= in the code above.

First you want to loop the ArrayList starting with i = 2 or 2nd element(assuming you have more than 1 element in the list),
if you have 1 or less than 1 element in then it simply skips the loop and returns 0 index(frst element). If the element of
if you have more than 1 element in the list, then it compares the value in the 2nd element to the value element before it, if it is higher or the same,then it sets it as the highestIntIdx.
public static int search(List list) {
int highestIntIdx= 0;
for (int i = 1;i<list.size();i++){
if(list.isEmpty())
break;
if (list.get(i) >= list.get(i-1)){
highestIntIdx = i;
}
}
return highestIntIdx;
}
}

The variable key is necessary because the method pictured appears to not be a method to find the max but rather a method to return whether the list contains a certain number.
The pictured method does have a logical error because the body of the loop returns immediately if the 0th index is not key:
if (list.get(i) == key) {
return true;
}
return false; // <- this should be after the loop
Regarding the method that's assigned (I assume it's an assignment):
Write a method that recieves an ArrayList of integers as a parameter and returns the index of the largest integer in the collection.
No, this method does not need a key variable.
To write a method such as this, the first thing you should do is make sure the list is not empty. An empty list cannot have a max index.
if(list.isEmpty()) {
return -1; // return a special value indicating the list is empty
}
That check will also throw a NullPointerException if the list is null. We could check if the list is null and return something else but this is a case where it's probably more informative to throw an exception.
Then you need to keep a variable that is the "current" highest index. We can initialize this to 0 because we already know the list is at least size of 1.
int indexOfMax = 0;
Then we'll have a loop that compares each index in the list to the current highest index and reassigns it if the number at that index is higher. We can start this loop at 1 because, again, we already know the list's size must at least be 1. The loop will simply break immediately if there are no other indexes. If a list only has one number, then that number is the largest one.
for(int i = 1; i < list.size(); i++) {
Then do the comparison and assignment:
if(list.get(i) > list.get(indexOfMax)) {
indexOfMax = i;
}
}
Finally return our index.
return indexOfMax;

You appear to have been asked to return the index of the largest integer in the ArrayList.
So you will want to implement a method liek
package com.snippet;
import java.util.ArrayList;
public class Largest {
public Largest() {
}
public int getIndexOfLargest(ArrayList<Integer> list) {
int index;
if (list == null) {
index = -1;
} else {
index = 0;
for (int i = 1; i < list.size(); i++) {
if (list.get(i) > list.get(index)) {
index = i;
}
}
}
return index;
}
}

Related

How to check whether list is present inside list in the java

A TreeSet containing a list and containing custom comparator. I want to check whether the list is present inside the list but this code is giving me the wrong answer. Can anybody resolve this issue with a proper explanation or how to make modify the treeset for getting the correct answer,
public static void main(String[] args) {
//Creating TreeSet
TreeSet<ArrayList<Integer>> H = new TreeSet<ArrayList<Integer>>(new Comparator<ArrayList<Integer>>() {
//Implementing the comparotor
#Override
public int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) {
for (int i = 0; i < Math.min(o1.size(), o2.size()); ++i) {
//Checking the order of the number
if (o1.get(i) < o2.get(i)) {
return -1;
} else if (o1.get(i) > o2.get(i)) {
return 1;
} else {
return 0;
}
}
if (o1.size() == o2.size()) {
return 0;
}
if (o1.size() < o2.size()) {
return -1;
}
return 1;
}
});
ArrayList<Integer>A=new ArrayList<>();
A.add(1);
A.add(2);
A.add(3);
//Inserting the list in the treeset
H.add(A);
ArrayList<Integer>B=new ArrayList<>();
B.add(1);
B.add(2);
B.add(3);
B.add(4);
System.out.println(H.contains(B)); //This line is giving true
}
Your for loop never executes for more than one iteration: all three branches of the conditional contain a return statement.
for (int i = 0; i < Math.min(o1.size(), o2.size()); ++i) {
//Checking the order of the number
if (o1.get(i) < o2.get(i)) {
return -1;
} else if (o1.get(i) > o2.get(i)) {
return 1;
} else {
return 0;
}
}
So, all you are doing is comparing the first elements of the two lists.
Remove the return 0; in the final case.
You may instead find it neater to write the comparator body as:
for (int i = 0; i < Math.min(o1.size(), o2.size()); ++i) {
int cmp = Integer.compare(o1.get(i), o2.get(i));
if (cmp != 0) {
return cmp;
}
}
return Integer.compare(o1.size(), o2.size());
In terms of writing your existing code as suggested ("you may find it neater"), the original code is equivalent to:
if (!o1.isEmpty() && !o2.isEmpty()) {
return Integer.compare(o1.get(0), o2.get(0));
}
return Integer.compare(o1.size(), o2.size());
Your comparator is broken. Test it separately: Forget the TreeSet, just make List<Integer> objects with test data and run comparator.compare(a, b) and debug this. Your loop that loops through all indices that both lists share always returns, meaning, it never really loops: It runs once, on the first number (Which in your example is 1 for both of the lists), and returns a value.
Presumably, you do NOT want to return 0 if the values are equal, instead, continue;. Or just let the for loop run to its end brace naturally (so two ifs: If smaller, return -1. If larger, return +1. That's it - the remaining case (they are equal) will loop.
The problem here lies on the comparator. I'm gonna break down why this does not work:
First block:
for (int i = 0; i < Math.min(o1.size(), o2.size()); ++i) {
//Checking the order of the number
if (o1.get(i) < o2.get(i)) {
return -1;
} else if (o1.get(i) > o2.get(i)) {
return 1;
} else {
return 0;
}
}
Here, you have some problems:
If the lists are not the same size, you don't care. You iterate through the minimum length, which is not correct. If the length of the arrays are different, you should just return 0, as they can't be equal being different size.
Second, even if they were the same size, you are giving a return after checking the first item. So, if two arrays are not the same, but their first item is the same, you will return true (what is actually happening in your code)
So, what I would say is implementing the following conditions:
Check if length are equal
If length is not equal, return -1
If length is equal, then iterate through the list and compare each number. If the number is not equal, we finish iterating as we know they're not equal anymore. If the number is equal, keep comparing. You will return true when you reach the end of the list and all elements are equal.
Example code:
public int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) {
// length of the arrays is not equal
if (o1.size() != o2.size()) {
return -1;
} else
// length is equal, so continue
{
Boolean equal = true;
// we iterate through the array length while the elements are equal
for (int i = 0; i < o1.size() && equal; ++i) {
if (o1.get(i) != o2.get(i)) {
equal = false;
}
}
// if all elements were equal, return 0. And we return -1 otherwise
if equal {
return 0
} else {
return -1
}
}
}

Fixed Point (Value equal to index) in a given array using Linear Search - Logic question

Can someone provide an explanation why using this method below returns only the first matching value within the array? For example if My array element is 0, 1, 2, 3 and 4. It will return 0, instead of 4. Every value within the array matches to its index 4, should using the for loop return 4 after the last iteration is completed?
static int linearSearch(int arr[], int n)
{
int i;
for(i = 0; i < n; i++)
{
if(arr[i] == i)
return i;
}
/* If no fixed point present
then return -1 */
return -1;
}
//main function
It's because in your if you immediately call return, and your method is supposed to return a single int. If you want to collect all fixed points, you can modify your method like this:
static List<Integer> linearSearch(int arr[], int n)
{
List<Integer> fixedPoints = new ArrayList<>();
for(int i = 0; i < n; i++)
{
if(arr[i] == i)
fixedPoints.add(i);
}
return fixedPoints;
}
This will return 4 as it has an updated index for each i matching to its value in an array.
static int linearSearch(int arr[], int n)
{
int i,index = -1;
for(i = 0; i < n; i++)
{
if(arr[i] == i)
index = i;
}
/* If no fixed point present
then return -1 */
return index;
}
//main function
Q: Can someone provide an explanation why using this method below
returns only the first matching value within the array?
A method returns to the code that invoked it when reaches a return statement.
From doc:
Returning a Value from a Method
A method returns to the code that invoked it when it
completes all the statements in the method,
reaches a return statement, or
throws an exception,
whichever occurs first.
The statement if(arr[i] == i) returns true at the first step of the for loop:
i=0
arr[0]=0
Then the line return i; executed.
Q: Every value within the array matches to its index 4, should using
the for loop return 4 after the last iteration is completed?
In this condition the last iteration is the first iteration of the for loop. It runs only for i=0. The value of i never reaches to 4.

Sorting Integer array using Comparable

I am working on a project in which I have to sort an array of Integer objects by using Comparable.
My add method takes an item of type E. If my size variable (which tracks the elements in my array theData[]) is = 0 (which it is initialized to), I simply put the item in theData[0].
If it is not, I use item.compareTo to compare the item against each item already in the array. If the result of compareTo is < 0 for a number in the array, I shift everything at that number and after to the right, and insert the item before it.
If compareTo returns a 0, meaning the item is equal to the number in the array, I do nothing as I don't want duplicates in the array.
If none of the compareTo statements in the loop return a -1 or a 0, I put the item in theData[size], the end of the array, as it must be larger than all the other numbers.
However, this doesn't work. Any time I make a new Set and add a few numbers to it, then try to print out the contents of my set using a for loop,I keep getting a java.lang.ArrayIndexOutOfBoundsException: 10 error for this line:
theData[j + 1] = theData[j];
I've tried starting from scratch and re-writing my loop with different logic, and each time I keep hitting this wall. I know I must either be shifting incorrectly or not increasing the size of the array correctly with my reallocate method, but I can't wrap my head around it.
import java.util.*;
public class Set<E extends Comparable<E>> {
String s;
String name;
private static final int INITIAL_CAPACITY = 10;
private E[] theData;
private int size = 0;
private int capacity = INITIAL_CAPACITY;
#SuppressWarnings("unchecked")
public Set() {
theData = (E[]) new Comparable[capacity];
}
public Set(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void add(E item) {
if (size == capacity) {
reallocate();
}
if (size == 0) { // If size is 0, add item to theData[0]
theData[size] = item;
size++;
return;
}
else { // Else compare the item to every item in loop.
for (int i = 0; i < size; i++) {
int result = item.compareTo(theData[i]);
if (result < 0) {
for (int j = 0; j < size; j++) { //If item is less than a number, shift everything
theData[j + 1] = theData[j]; //after that index to the right, and add item
theData[j] = item;
}
}
if (result == 0) {
return;
}
else { //If item is not less than or equal to any
theData[size] = item; //numbers in the array, add it to the end
size++;
}
}
}
}
/*
* if (size>=1){ int result = item.compareTo(theData[size-1]); if(result<0){
* E temp = theData[size-1]; theData[size-1] = item; theData[size] = temp; }
* if(result>1){ return; } }
*/
public E get(int index) {
if (index < 0 || index >= size) {
throw new ArrayIndexOutOfBoundsException(index);
}
return theData[index];
}
public int size() {
return size;
}
private void reallocate() {
capacity = 2 * capacity;
theData = Arrays.copyOf(theData, capacity);
}
}
Edit: The driver method I'm using to test it -
public class Driver {
String one = "two";
public static void main(String[] args){
Set<Integer> one = new Set<Integer>();
one.add(63);
one.add(20);
one.add(127);
one.add(10);
one.add(26);
one.add(15);
for(int i = 0; i < one.size(); i++){
System.out.println(one.get(i));
}
}
}
When j == size - 1, theData[j+1] will take you out of the array.
You want to loop to one before the end instead.
for (int j = 0; j < size - 1; j++) { //If item is less than a number, shift everything
theData[j + 1] = theData[j]; //after that index to the right, and add item
theData[j] = item;
}
So I've also taken a look at the logic you've got for the insertion, and it doesn't make a lick of sense. Why do you delay the insertion at all? If you've got the room, just add it!
Next, the double loops are essentially implementing bubble sort, but there's a fatal flaw with it: you don't ever complete the swap; you only overwrite your values repeatedly. You're also not comparing in the right direction; you want to swap if the value on the left is larger than the value on the right, since you're starting from the beginning of the array.
So, with that...this is what an implementation would have the form of...
public void add(E item) {
if (size == capacity) {
reallocate();
}
theData[size++] = item;
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - 1; j++) {
if (theData[j].compareTo(theData[j + 1]) > 0) {
// perform the swap (you need an extra variable!
}
}
}
}
I leave implementing the swap as an exercise for the reader.
First, in your shift loop, you are inserting the new item in every position instead of shifting then inserting in [i] because you copy theData[j] to the next position, but always assign item to theData[j], is that right?
Second, you are starting from the beginning of array since j starts with 0. J should start with i.
Third and main bug, you verify if result < 0 then you verify IF result == 0, change for a ELSE IF so the else don't get executed even when result < 0
shift elements to right can be done from right to left, like:
for (int j = size; j > i; j--) { // If item is less than a
// number, shift
// everything
theData[j] = theData[j - 1]; // after that index to the
// right, and add item
}
size++;
theData[i] = item;
break;// after insert the number, we can just break the for loop
once the new number is inserted, break the for loop, else, the size variable will not be correct
else { // If item is not less than or equal to any
theData[size] = item; // numbers in the array, add it to the end
size++;
break;
}

Finding elements in array with binary search

Trying to use Arrays.binarySearch() to search for a string in an array and return the index. However each time I call Arrays.binarySearch() I get the following exception -
Exception in thread "main" java.lang.NullPointerException
at java.util.Arrays.binarySearch0(Unknown Source)
at java.util.Arrays.binarySearch(Unknown Source)
at project.ArrayDirectory.lookupNumber(ArrayDirectory.java:97)
at project.test.main(test.java:12)
Here is my ArrayDirectory class -
public class ArrayDirectory implements Directory {
static Entry[] directory = new Entry[50];
#Override
public void addEntry(String surname, String initials, int extension) {
int n = 0;
for (int i = 0; i < directory.length; i++) { // counting number of
// entries in array
if (directory[i] != null) {
n++;
}
}
if (n == directory.length) {
Entry[] temp = new Entry[directory.length * 2]; // if array is full
// double the
// length.
for (int i = 0; i < directory.length; i++)
temp[i] = directory[i];
directory = temp;
}
int position = -1;
for (int i = 0; i < directory.length; i++) {
position = i;
if (directory[i] != null) { // sorting the array into alphabetical
// order by surname.
int y = directory[i].getSurname().compareTo(surname);
if (y > 0) {
break;
}
}
else if (directory[i] == null) {
break;
}
}
System.arraycopy(directory, position, directory, position + 1,
directory.length - position - 1);
directory[position] = new Entry(initials, surname, extension); // placing
// new
// entry
// in
// correct
// position.
}
#Override
public int lookupNumber(String surname, String initials) {
// TODO Auto-generated method stub
Entry lookup = new Entry(surname, initials);
int index = Arrays.binarySearch(directory, lookup);
return index;
}
}
Any ideas how I use binary search to find the correct index?
Thank you for you help.
edit -
I have also overridden comapreToin my Entry class -
public int compareTo(Entry other) {
return this.surname.compareTo(other.getSurname());
}
In your invocation of
int index = Arrays.binarySearch(directory,lookup);
directory seems to contain only null elements. Check that you are initializing elements correctly.
I note two things:
static Entry [] directory = new Entry [1];
First, that code allocates space for one Entry in the array. It doesn't actually instantiate an Entry. That is, directory[0] is null. Secondly, a binary-search on an array with one entry is crazy. There is only one element. It must be directory[0]. Finally, you should sort your array to do a binary search on it.
The basic concept behind a binary search is the recursion of the following steps(Note the search assumes the list or array of elements is sorted in some form and the element exists there.):
Go to the middle element of the array.
check if the searched element is equal to the element at the middle. If it is then return its index.
if not then check if the searched element is 'smaller' or 'larger' than the element in the middle.
if it is smaller then go to step 1 using only the lower/first half of the array instead of the whole.
else go to step 1 using only the upper/last half of the array instead of the whole.
As the array is continuously divided in 2 it will eventually reach the size of 1 giving the result.
Now, suppose you are looking for an integer in an int array. Here is what the code would be like:
public static int binarySearch(int number, int[] array)
{
boolean isHere = false;
Integer index =0;
for(int i=0;i<array.length;i++)
{
if(array[i] == number)
{
isHere = true;
i = array.length;
}
}
if(!isHere)
{
index = -1;
}
else
{
int arrayStart = 0;
int arrayEnd = array.length;
index = binarySearch(number, arrayStart, arrayEnd, array);
}
return index;
}
private static int binarySearch(int number, int start, int end, int[] array)
{
// this formula ensures the index number will be preserved even if
// the array is divided later.
int middle = (start+ end)/ 2;
if(array[middle] == number)
{
return middle;
}
else
{
if(number < array[middle])
{
//searches the first half of the array
return binarySearch(number, start, middle, array);
}
else
{
// searches the last half of the array
return binarySearch(number, middle, end, array);
}
}
}
You can use the compareTo() method instead of <,>, & == operators in your example. The logic should still be the same.

Why doesn't this return the position for the largest item in the array list

public static int findLargestMark(ArrayList<Result> array)
{
int last = 0;
int largestPOS = 0;
for (int i = 1; i <= array.size(); i++)
{
for (Result s : array)
{
int num = s.getMark();
if (num > last)
{
last = num;
largestPOS = i++;
}
}
}
Does anyone have any idea why this isn't returning the position of the largest value?
I'm sorry but I'm a bit of a newbie to Java.
largestPOS = i++;
This is incrementing i which means it skips the next number. If that next number is the biggest, you'll miss it.
Your code won't compile. You need a return statement.
Your outer loop skips the first element because it starts at 1 instead of 0. Arrays and lists are 0 based.
You only need one loop to accomplish this. I'd remove the inner loop since you're trying to return the index and a foreach loop doesn't give you the index.
If your array is empty, it will set largestPOS to 0. That is not correct. Other algorithms in this situation would return -1 to mean "index not found". See String.indexOf for example.
If you want to find the largest mark, no need to reinvent the wheel. Use Collections.max and provide a custom Comparator :
Result r = Collections.max(array, new Comparator<Result>() {
#Override
public int compare(Result o1, Result o2) {
return Integer.compare(o1.getMark(), o2.getMark());
}
});
Then if you really want to find the position of this object in the list you can use indexOf :
array.indexOf(r);
Note that will return the index of the first occurrence of the specified element in the list.
If you want to get the index of the last occurrence, you can use :
array.lastIndexOf(r);
There are several reasons to this program's failure:
You need to check that your array has at least one item
You need to start the last at the initial mark, not at zero
You need to loop from one, inclusive, to array.size(), exclusive
You do not need a nested loop
You need to add a return statement
Here is how you can fix your code:
public static int findLargestMark(ArrayList<Result> array) {
if (array.size() == 0) return -1; //
int last = array.get(0).getMark();
int largestPOS = 0;
for (int i = 1; i < array.size(); i++) {
int num = array.get(i).getMark();
if (num > last) {
last = num;
largestPOS = i;
}
}
return largestPOS;
}
Because you're iterating through the same array using two nested loops. Keep it simple. Iterate only once through the entire array and find the maximum value and its index.
Try this..
public static int findLargestMark(ArrayList<Result> array)
{
int last = array.get(0).getMark();
int largestPOS = 0;
for (int i = 1; i <= array.size(); i++)
{
Result s = array.get(i);
int num = s.getMark();
if (num > last)
{
last = num;
largestPOS = i;
}
}
return largestPOS;
}
Your code even not compile, java is 0 index based. you should have received a ArrayIndexOfBoundException. However, i would just use Collections.max(array, Comparator):
Result x = Collections.max(array, new Comparator<Result>(){
#Override
public int compare(Result o1, Result o2) {
return Integer.compare(o1.getMark(), o2.getMark());
}
});
And then the index by array.indexOf(x) function, where array is an instance of type ArrayList<Result>

Categories