Java OOP-Accessing the last element in an array of objects - java

I am practicing object orientation here entering in basketball player names and how many points scored and rebounds grabbed.
How would I go through each element in an array of objects to find the last player with an even amount of points?
This is the code I have so far to enter the information. What do I need to do in my second forloop to examine each element and then display the last element that fits my criteria?
class basketballObj
{
public static void main (String[]args)
{
Basketball bbArray[];
String theName;
int thePoints;
int theRebounds;
int index;
int noOfElements = 0;
bbArray = new Basketball[3];
for(index = 0; index < bbArray.length; index++)
{
System.out.println("Enter a name ");
theName = EasyIn.getString();
System.out.println("Enter points scored ");
thePoints = EasyIn.getInt();
System.out.println("Enter rebounds grabbed ");
theRebounds = EasyIn.getInt();
bbArray[index] = new Basketball(theName, thePoints, theRebounds);
noOfElements++;
}
for(index = 0; index < bbArray.length; index++)
{
if(bbArray[index].getPoints() % 2 == 0)
{
}
}
}
}

Well if you want to find the last player with an even amount of points, you don't actually want to go through each element ;-). Try:
for(index = bbArray.length-1; index >= 0; index--)
{
if(bbArray[index].getPoints() % 2 == 0)
{
//add whatever relevant code here.
break; //this line breaks the for loop (because you've found a player with an even amount of score
}
}
we start at bbArray.length-1 because while you array contains 3 elements, arrays are zero-indexed. Meaning that to get the first element, you will have to call bbArray[0]. Similarly call bbArray[2] for the last element.

Simple. Iterated your array backwards.
boolean found = false;
for(int index=array.length-1; index>-1 && !found; index--) {
if(array[index].getPoints()%2 == 0) {
// found element. Break out of for loop
found=true;
}
}

You've pretty much got it.
Create a temporary, uninitialized variable Basketball temp; before the for loop that iterates through the bbArray and then set it equal to the bbArray[index] if the if condition is met.
If you want to save the index it was found at then create an int indexFound; as well.
Looping through it backwards as user2651804 suggested yields this:
public class basketballObj
{
public static void main(String[] args)
{
...
Basketball temp;
int indexFound = -1;
...
for(index = bbArray.length - 1; index >= 0; index++)
{
if(bbArray[index].getPoints() % 2 == 0)
{
temp = bbArray[index];
indexFound = index;
break;
}
}
//note temp will be null if no scores were even
//if (temp != null)
//you can use the above if statement if you don't want to use indexFound
//you can also just check if indexFound == -1
if (indexFound != -1)
{
System.out.println("Found at index: " + indexFound);
//
}
}
}

Related

Array needle in haystack

I have an assignment to create an int array that is serched in another method for a user input int value then displays the index of that element in the array. I have that part working just fine and I personaly chose to make the elements in the array random values from 1 - 10.I also need to have the program display a message ("Element not found in array") in the event that the given number isn't in the array. I cannot seem to get this part to work correctly and am hoping I can get some advice here.
import java.util.Scanner;
public class NeedleInHaystack {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Please provide an Integer for the needle: ");
int needle = scan.nextInt();
int[] haystack = new int[10];
System.out.println("The array being used is: ");
for (int i = 0; i < 10; i++) {
int j = (int) (Math.random() * 9 + 1);
haystack[i] = j;
System.out.print(haystack[i] + " ");
}
returnIndex(haystack, needle);
}
public static int returnIndex(int[] haystack, int needle) {
int index = needle;
System.out.println("\nThe needle is found at index: ");
for (int i = 0; i < haystack.length; i++) {
if (haystack[i] == index) {
System.out.println(i);
}
}
return index;
}
}
The program is an int needle in a hastack array. What is the best way to make the program end "gracefully" in the event that the input value is not present in the random array?
The assignment was worded as follows:
"Create a Java program with a method that searches an integer array for a specified integer value (see help with starting the method header below). If the array contains the specified integer, the method should return its index in the array. If not, the method should throw an Exception stating "Element not found in array" and end gracefully. Test the method in main with an array that you make and with user input for the "needle"."
Problem is in for-loop your are checking the needle in array but not return it, and also since you have assigned int index = needle; at the beginning, even though if needle is not in array it will return needle
So in that case assign index=0 in beginning and iterate the array, if found return the index else return the needle
public static int returnIndex(int[] haystack, int needle) {
int index;
System.out.println("\nThe needle is found at index: ");
for (index = 0; index < haystack.length; index++) {
if (haystack[index] == needle) {
System.out.println("value found at index"+index);
return index;
}
}
System.out.println("The value not found in array");
return needle;;
}
You could add some sort of boolean flag in the method that you set to true if it is found. If not, the flag will remain false. After iterating through the array, you could check whether the flag is false and if so, then you could print some error message.
public static int returnIndex(int[] haystack, int needle) {
boolean found = false;
int index = needle;
System.out.println("\nThe needle is found at index: ");
for (int i = 0; i < haystack.length; i++) {
if (haystack[i] == index) {
System.out.println(i);
found = true;
}
}
if (found) return index;
else {
System.out.println("Not found.");
return null;
}
}
}
Since you are supposed to return the index and not the needle value you should just return inside the for-loop once the object is found. Very Similar to what Deadpool did.
But as you state the method is supposed to throw a exception when the needle isn‘t found you should get rid of the second return statement and just throw a exception.
public static int returnIndex(int[] haystack, int needle) {
System.out.println("\nThe needle is found at index: ");
for (int i = 0; i < haystack.length; i++) {
if (haystack[i] == needle) {
System.out.println(i);
return i;
}
}
throw new NoSuchElementException(„Element not found in array“);
}

Increasing number sequence in a string java

Problem: Check if the numbers in the string are in increasing order.
Return:
True -> If numbers are in increasing order.
False -> If numbers are not in increasing order.
The String sequence are :
CASE 1 :1234 (Easy) 1 <2<3<4 TRUE
CASE 2 :9101112 (Medium) 9<10<11<12 TRUE
CASE 3 :9991000 (Hard) 999<1000 TRUE
CASE 4 :10203 (Easy) 1<02<03 FALSE
(numbers cannot have 0 separated).
*IMPORTANT : THERE IS NO SPACES IN STRING THAT HAVE NUMBERS"
My Sample Code:
// converting string into array of numbers
String[] str = s.split("");
int[] numbers = new int[str.length];
int i = 0;
for (String a : str) {
numbers[i] = Integer.parseInt(a.trim());
i++;
}
for(int j=0;j<str.length;j++)
System.out.print(numbers[j]+" ");
//to verify whether they differ by 1 or not
int flag=0;
for(int j=0;j<numbers.length-1;j++){
int result=Integer.parseInt(numbers[j]+""+numbers[j+1]) ;
if(numbers[j]>=0 && numbers[j]<=8 && numbers[j+1]==numbers[j]+1){
flag=1;
}
else if(numbers[j]==9){
int res=Integer.parseInt(numbers[j+1]+""+numbers[j+2]) ;
if(res==numbers[j]+1)
flag=1;
}
else if(result>9){
//do something
}
}
This is the code I wrote ,but I cant understand how to perform for anything except one-digit-numbers ( Example one-digit number is 1234 but two-digit numbers are 121314). Can anyone have a solution to this problem?. Please share with me in comments with a sample code.
I'm gonna describe the solution for you, but you have to write the code.
You know that the input string is a sequence of increasing numbers, but you don't know how many digits is in the first number.
This means that you start by assuming it's 1 digit. If that fails, you try 2 digits, then 3, and so forth, until you've tried half the entire input length. You stop at half, because anything longer than half cannot have next number following it.
That if your outer loop, trying with length of first number from 1 and up.
In the loop, you extract the first number using substring(begin, end), and parse that into a number using Integer.parseInt(s). That is the first number of the sequence.
You then start another (inner) loop, incrementing that number by one at a time, formatting the number to text using Integer.toString(i), and check if the next N characters of the input (extracted using substring(begin, end)) matches. If it doesn't match, you exit inner loop, to make outer loop try with next larger initial number.
If all increasing numbers match exactly to the length of the input string, you found a good sequence.
This is code for the pseudo-code suggested by Andreas .Thanks for the help.
for (int a0 = 0; a0 < q; a0++) {
String s = in.next();
boolean flag = true;
for (int i = 1; i < s.length() / 2; i++) {
int first = Integer.parseInt(s.substring(0, i));
int k=1;
for (int j = i; j < s.length(); j++) {
if (Integer.toString(first + (k++)).equals(s.substring(j, j + i)))
flag = true;
else{
flag=false;
break;
}
}
if (flag)
System.out.println("YES");
else
System.out.println("NO");
}
I would suggest the following solution. This code generates all substrings of the input sequence, orders them based on their start index, and then checks whether there exists a path that leads from the start index to the end index on which all numbers that appear are ordered. However, I've noticed a mistake (I guess ?) in your example: 10203 should also evaluate to true because 10<203.
import java.util.*;
import java.util.stream.Collectors;
public class PlayGround {
private static class Entry {
public Entry(int sidx, int eidx, int val) {
this.sidx = sidx;
this.eidx = eidx;
this.val = val;
}
public int sidx = 0;
public int eidx = 0;
public int val = 0;
#Override
public String toString(){
return String.valueOf(this.val);
}
}
public static void main(String[] args) {
assert(check("1234"));
assert(check("9101112"));
assert(check("9991000"));
assert(check("10203"));
}
private static boolean check(String seq) {
TreeMap<Integer,Set<Entry>> em = new TreeMap();
// compute all substrings of seq and put them into tree map
for(int i = 0; i < seq.length(); i++) {
for(int k = 1 ; k <= seq.length()-i; k++) {
String s = seq.substring(i,i+k);
if(s.startsWith("0")){
continue;
}
if(!em.containsKey(i))
em.put(i, new HashSet<>());
Entry e = new Entry(i, i+k, Integer.parseInt(s));
em.get(i).add(e);
}
}
if(em.size() <= 1)
return false;
Map.Entry<Integer,Set<Entry>> first = em.entrySet().iterator().next();
LinkedList<Entry> wlist = new LinkedList<>();
wlist.addAll(first.getValue().stream().filter(e -> e.eidx < seq
.length()).collect(Collectors.toSet()));
while(!wlist.isEmpty()) {
Entry e = wlist.pop();
if(e.eidx == seq.length()) {
return true;
}
int nidx = e.eidx + 1;
if(!em.containsKey(nidx))
continue;
wlist.addAll(em.get(nidx).stream().filter(n -> n.val > e.val).collect
(Collectors.toSet()));
}
return false;
}
}
Supposed the entered string is separated by spaces, then the code below as follows, because there is no way we can tell the difference if the number is entered as a whole number.
boolean increasing = true;
String string = "1 7 3 4"; // CHANGE NUMBERS
String strNumbers[] = string.split(" "); // separate by spaces.
for(int i = 0; i < strNumbers.length - 1; i++) {
// if current number is greater than the next number.
if(Integer.parseInt(strNumbers[i]) > Integer.parseInt(strNumbers[i + 1])) {
increasing = false;
break; // exit loop
}
}
if(increasing) System.out.println("TRUE");
else System.out.println("FALSE");

Is there something wrong with my binary search algorithm?

I'm writing a program where you can enter a words which will get stored in an ArrayList. You can then search for these words, by entering them in a textField and pressing a button. (You can also sort them, if pressing another button). If the word is found the place in the ArrayList of the word should be printed out and if it's not found that should be printed out. I thought this worked until just recently when I tested it (it have worked before): I entered a word I knew was in the ArrayList which made it print out the position of the word in the ArrayList (which is what I want it to do). I then entered a word which I knew didn't exist in the ArrayList which made it print out that the word doesn't exist (which is also what I want it to do). But when I after that searched for a word I knew existed in the ArrayList, it printed out that the word couldn't be found. I then tried this with another word I knew existed in the ArrayList, but I couldn't find that either. I have after this restarted the program several times and sometimes it works and sometimes it doesn't and I have no idea why or why not...
The array gets sorted before I run the algorithm so I know that's not the problem...
Down below is the class with my search algorithm:
public class SearchAlg {
public static String binary (ArrayList<String> list, String user) {
int first = 0;
int found = 0;
int middle = 0;
int last = list.size();
String strFound = "";
while (first < last && found == 0) {
middle = ((first + last) / 2);
if (user.compareTo(list.get(middle)) > 0) {
first = middle + 1;
} else if (user.compareTo(list.get(middle)) == 0) {
found = 1;
} else if (user.compareTo(list.get(middle)) < 0) {
last = middle - 1;
}
}
if (found == 1) {
strFound = "The word " + user + " exists on the place " + middle + " in the Arraylist";
} else {
strFound = "The word " + user + " does not exist in the Arraylist";
}
return strFound;
}
}
Here is my sorting algorithm:
public class Sort {
static private String strTemp;
static private int i;
static private int n;
public static ArrayList bubbelSort (ArrayList<String> list) {
for (i = 0; i < list.size(); i++) {
for (n = 0; n < list.size() - i - 1; n++) {
if (list.get(n).compareTo(list.get(n + 1)) > 0) {
strTemp = list.get(n);
list.set(n, list.get(n + 1));
list.set(n + 1, strTemp);
}
}
}
return list;
}
And this is my Main class:
ArrayList<String> list = new ArrayList();
private void btnEnterActionPerformed(java.awt.event.ActionEvent evt) {
txtaOutput.setText("");
String wrd = txtfEnter.getText();
list.add(wrd);
for (int i = 0; i < list.size(); i++) {
txtaOutput.append(list.get(i) + "\n");
}
}
private void btnSortActionPerformed(java.awt.event.ActionEvent evt) {
txtaOutput.setText("");
Sort.bubbelSort(list);
}
private void btnSearchActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
String user = txtfSearch.getText();
txtaOutput.setText("");
String bin = SearchAlg.binary(list, user);
txtaOutput.append(bin);
}
I have no idea what's causing this, so any help is appreciated!
EDIT: I now know that the problem is that the first item in the ArrayList ins't searchable. So if the ArrayList consists of a, b, c for example, then only b and c are searchable. If I try and search for a, it says that it can't be found.
int first= 0;
int last= a.length - 1;
while (first<= last) {
int middle = first+ (last- first) / 2;
if (user.compareTo(list.get(middle)) < 0) last = middle - 1;
else if (user.compareTo(list.get(middle)) > 0) first= middle + 1;
else {
found =1 ;
break;
}
}
and don't forget to sort your list as mentioned in the previous post
The problem is in the very last step of your search. There is a chance you update the 'first' and 'last', and in the next iteration you would find the value, but instead you break from the loop.
Solution: remove the variable found entirely, and also these two lines:
} else if (user.compareTo(list.get(middle)) == 0) {
found = 1;
and where you now write...
if (found == 1) {
...instead do...
if (user.compareTo(list.get(first)) == 0) {
You're off by one.
You initialize the method with last = list.size(), implying that you're searching the half open interval [first, last> (from and including first, to but excluding last).
However, in your loop, you set last = middle - 1, which would work if your search range was the closed interval [first, last] (from and including first, to and including last).
You should make up your mind as to whether last should point on the last element, or after the last element. Here's your loop if you go with the latter:
while (first < last && found == 0) {
middle = ((first + last) / 2);
if (user.compareTo(list.get(middle)) > 0) {
first = middle + 1;
} else if (user.compareTo(list.get(middle)) == 0) {
found = 1;
} else if (user.compareTo(list.get(middle)) < 0) {
last = middle; // <-- Remove -1
}
}

IntegerList help in Java

So in class we follow the lab manual instructions. I was able to do step one and two, I just need help with step three.
Lab Manuel Instructions:
Add a method void removeFirst(int newVal) to the IntegerList class that removes the first occurrence of a value from the list. If the value does not appear in the list, it should do nothing (but it’s not an error). Removing an item should not change the size of the array, but note that the array values do need to remain contiguous, so when you remove a value you will have to shift everything after it down to fill up its space. Also remember to decrement the variable that keeps track of the number of elements.
Add an option to the menu in IntegerListTest to test your new method.
IntegerList
public class IntegerList
{
private int count;
private double totalInt;
int[] list; //values in the list
//-------------------------------------------------------
//create a list of the given size
//-------------------------------------------------------
void addElement(int newVal)
{
if (count == list.length)
increaseSize();
list[count] = newVal;
count++;
}
void removeFirst(int newVal2)
{
for (int i = 0; i < list.length-1; i++)
{
if (newVal2 == list[i])
{
list[list.length] = (Integer) null;
list[i] = list [i-1];
}
}
}
public IntegerList(int size)
{
list = new int[size];
count = 0;
}
public void randomize()
{
for (int i=0; i<list.length; i++)
{
list[i] = (int)(Math.random() * 100) + 1;
count++;
}
}
public void print()
{
for (int i=0; i<count; i++)
System.out.println(i + ":\t" + list[i]);
}
private void increaseSize()
{
int[] temp = new int[list.length * 2];
for (int lst = 0; lst < list.length; lst++)
temp[lst] = list[lst];
list = temp;
}
}
IntegerListTest
import java.util.Scanner;
public class IntegerListTest
{
static IntegerList list = new IntegerList(10);
static Scanner scan = new Scanner(System.in);
public static void main(String[] args)
{
printMenu();
int choice = scan.nextInt();
while (choice != 0)
{
dispatch(choice);
printMenu();
choice = scan.nextInt();
}
}
public static void dispatch(int choice)
{
int loc;
switch(choice)
{
case 0:
System.out.println("Bye! ") ;
break;
case 1:
System.out.println("How big should the list be?");
int size = scan.nextInt();
list = new IntegerList(size);
list.randomize();
break;
case 2:
list.print();
break;
case 3:
System.out.println("What number would you like to add?");
int newVal = scan.nextInt();
list.addElement(newVal);
break;
case 4:
System.out.println("What number do you want to remove? (Removes first occurance.)");
int newVal2 = scan.nextInt();
list.removeFirst(newVal2);
default:
System.out.println("Sorry, invalid choice");
}
}
public static void printMenu()
{
System.out.println("\n Menu ");
System.out.println(" ====");
System.out.println("0: Quit");
System.out.println("1: Create a new list (** do this first!! **)");
System.out.println("2: Print the list");
System.out.println("3: Add to the list");
System.out.println("4: Remove Integer");
System.out.print("\nEnter your choice: ");
}
}
Any help is greatly appreciated. It would be cool if you could also explain why so I can learn from this. Thanks! :D
So you can loop the array to find the first element that matches a given value.
If it is found, save its position to index and shift all elements after it by one position:
void removeFirst(int newVal2) {
int index = -1;
for (int i = 0; i < count; i++) {
if (index == -1 && newVal2 == list[i]) {
// element found - save index
index = i;
}
if (index != -1) {
// this code handles after found case
if (i == count-1) {
// zero-out last element
list[i] = 0;
count--;
}
else {
// shift value
list[i] = list[i+1];
}
}
}
}
public void removeFirst(int val){
//the position at which the algorithm currently is
int i = 0;
boolean found = false;
//search for the first occurence of val in the array
for(; i < count && list[i] != val ; i++);
//i is now the index of the first value equal to val in list
//if a match was found, the index must be smaller than the array-size
found = (i < count);
//shift all elements that are right of the value to the left
//to leave no empty space. Since the value at i is the searched value
//it's left out (i += 1)
i += 1;
for(; i < count ; i++)
list[i - 1] = list[i];//move the current element one to the left
//check if a match was found and decrement the sizecounter, if one was found
if(found)
--count;
}
i don't really have time to give u much details and i know this is not really an efficient way, but what u could do is to always create a new array of "size-1" and then take note of the index of the array element you want to remove, then copy everything before and after that array element into your new array, once all of this is done you could copy it back into the original array like this oldArray = newArray.

Enter Integers into an Array and terminating input before reaching limit

I'm doing a practice question in my textbook to add integers (negative and positive) into an array. I want the user to be able to terminate entering numbers into the array before it reaches the end [50].
This is what I've come up with:
The user enters the numbers which is stored in a string. If keepLooping is true and index < size of the array; it will parse token by token the string and place the number into the int array.
There must be an easier way to do this and I can't get my code working, any help would be much appreciated:
// Create Objects to use in program
Scanner keyboard = new Scanner(System.in);
int[] arrayOfNumbers = new int[50];
// Prompt for input
System.out.println("Enter upto 50 integers separated by a space.");
System.out.println("Type x to signal no more integers to enter.");
int index = 0;
boolean keepLooping = true;
while (index < arrayOfNumbers.length && keepLooping) {
String numToAdd = keyboard.nextLine();
if ( numToAdd.equals("x") || numToAdd.equals("X") ) {
keepLooping = false;
}
if ( !numToAdd.equals("x") || !numToAdd.equals("X") ) {
arrayOfNumbers[index] = Integer.parseInt(numToAdd);
}
}
// DEBUG, Print Array
for (int k=0; k < arrayOfNumbers.length; k++) {
System.out.println(arrayOfNumbers[k]);
}
You can simplify a little bit with a for loop, and break out of the loop to exit:
for (int index = 0; index < arrayOfNumbers.length; ++index) {
String numToAdd = keyboard.nextLine();
if (numToAdd.equals("x") || numToAdd.equals("X")) {
break;
}
arrayOfNumbers[index] = Integer.parseInt(numToAdd);
}
If you debugged your program step-by-step (e.g. Stepping with F6 in Eclipse), you would have noticed that index's value does not change. Quickest fix would be:
while (index < arrayOfNumbers.length && keepLooping) {
String numToAdd = keyboard.nextLine();
if ( numToAdd.equals("x") || numToAdd.equals("X") ) {
keepLooping = false;
}
if ( !numToAdd.equals("x") || !numToAdd.equals("X") ) {
arrayOfNumbers[index] = Integer.parseInt(numToAdd);
}
index++;
}
But of course, this solves just the filling-of-array issue. Then come the good practice in programming concerns, which are thoroughly covered by the rest of the answers.
int index = 0;
boolean keepLooping = true;
while (index < arrayOfNumbers.length && keepLooping) {
String numToAdd = keyboard.nextLine();
if (numToAdd.equalsIgnoreCase("x")) { // Use EqualsIgnoreCase to shorten it
keepLooping = false;
} else { // Use an else statement instead of evaluating the inverse
arrayOfNumbers[index] = Integer.parseInt(numToAdd);
}
index++; // Increment the index to avoid eternal loop and actually fill the array
}

Categories

Resources