Array not looping correctly - Java - java

I have an array with 60 values, and when I click the next button, it will cycle through all of the values of my array in ascending order until the number 60, then it starts at number one again.
I also have a previous button, so I can go down values instead of going up. When I hit the previous button on the first array value [0], my app crashes and I am not sure why.
Here is my code:
public String nextFact() {
i++;
if(i >= facts.length) {
i = 0;
}
return facts[i];
}
public String previousFact() {
i--;
if(i < 0) {
i = facts.length;
}
return facts[i];
}

You are getting an ArrayIndexOutOfBoundsException when you change i to facts.length, because valid array indexes range from 0 through facts.length - 1. Set i to facts.length - 1.
if(i < 0) {
i = facts.length - 1;
}
Your wrapping-around code for greater than or equal to the length should be working fine.

Your array is of size array.length. So the last index will be array.length-1. In your previous function, you assign array.length to i. This is larger index than max index for array and therefore it crashes down. You must be getting am indexoutofbound error too.
You should replace that line with this:
i = facts.length - 1;

Related

Trying to display the last index of a item in array Java

I am trying to display the last index of an item in array, an example:
{6,4,7,3,11,4} Last index of 4 = 5
I have written this method so far:
public int lastIndexOf(int[] nums, int num) {
int found = 0;
for (int i = nums.length; i < 0 ; i--) {
if (nums[i] == num) {
return i;
}
}
return -1;
}
Why does this not work? I am under the impression that you need to start the for loop at the start of the arrays length and then work backwards. I want to be able to use a for loop to do this, I set up a condition if there are no occurrences of the number to return -1 but when I am running this code I always return -1 no matter what numbers I am putting in.
How would I solve this using a for loop?
Your for loop conditions are not correct. Should be
for (int i = nums.length-1; i >= 0 ; i--) {
The "i<0" from before prevented it from entering the loop.
But the "i = nums.length" would have given you an Index out of bounds error. Need to subtract by 1 because Arrays are 0 indexed
You can also turn the array into list and use List's lastIndexOf method so you don't have to implement yourself.
Arrays.asList(nums).lastIndexOf(num)
note that lastIndexOf return -1 if num is not found in nums

Algorithm to check to output largest value in array or display if empty

I am trying to practice algorithms before i start my undergrad in computer science and i am struggling really bad to write algorithms. I understand them once i've been taught them and break them down but when I am trying to do my own, it fails miserable. I am trying a exercise question in a programming textbook, where i have an array and i have to output the largest value or if the array is empty, i have to display -1.
This was the best i can come up with but it still falls way short. Any pointers on what exactly I'm doing wrong.
for(i = 0;i < array.length-1;i++)
if(array[i] == 0){
empty = true;
n = -1;
System.out.println(n);
}else{
largest = array[0];
if(array[i] > largest){
largest = array[i];
System.out.println(array[i]);
}
}
I see that -1 displayed 10 times but i have found no solution for this and if the array is full, it provides me one then one value.
If you're struggling with algorithms, it helps sometimes not to look at them as algorithms but real-world problems.
Say you are in a shop buying cheese and your task is to pick a pack of cheese which has the latest expiration date. Now imagine the situation: standing at the cheese section looking for the best yummy cheese...
First, you look if there is any. If not, return empty handed.
If there are some packs, go through them looking for the best. You've got probably only one hand free, holding the basket in the other one, so...
Initially, pick the first cheese
Then go through the packs one by one. If you find cheese better than you have in your hand, put the one you're holding down and take the better one.
Now, let's put this to a programing language:
int[] cheeseExpirations = new int[] { ... };
if (cheeseExpirations.length == 0) {
System.out.println(-1); // no cheese :(
} else {
int myCheese = cheeseExpirations[0]; // take the first pack; better a sparrow in the hand than a pigeon on the roof...
for (int i = 0; i < cheeseExpirations.length; i++) { // idiomatic array iteration
int currentCheese = cheeseExpirations[i];
if (currentCheese > myCheese ) { // found a better one
myCheese = currentCheese; // just take it
}
}
System.out.println(bestCheese);
}
Is it clearer now? Like Richard Feynman said, using your imagination and examples is important:
I had a scheme, which I still use today when somebody is explaining something that I'm trying to understand: I keep making up examples.
For instance, the mathematicians would come in with a terrific theorem, and they're all excited. As they're telling me the conditions of the theorem, I construct something which fits all the conditions. You know, you have a set (one ball)-- disjoint (two balls). Then the balls turn colors, grow hairs, or whatever, in my head as they put more conditions on.
Finally they state the theorem, which is some dumb thing about the ball which isn't true for my hairy green ball thing, so I say "False!" [and] point out my counterexample.
You are checking the length of the array in each loop. This means it won't be checked unless the array has some object, which is just what we don't want.
But, in fact, you are not checking the array length:
if(array[i] == 0) tests if the item of array at index i is 0. To test the length of the array, you have to do if (array.length > 0). Remember you have to do this before the for loop, so it would be something like this:
if(array[i] == 0){
empty = true;
n = -1;
System.out.println(n);
}
for(i = 0;i < array.length-1;i++)
largest = array[0];
if(array[i] > largest){
largest = array[i];
System.out.println(array[i]);
}
}
But, in each loop you are reassigning largest to the first array element, which breaks the algorithm. So you must move that line before the for loop.
if(array[i] == 0){
empty = true;
n = -1;
System.out.println(n);
}
largest = array[0];
for(i = 0;i < array.length-1;i++)
if(array[i] > largest){
largest = array[i];
System.out.println(array[i]);
}
}
A few things:
if(array[i] == 0)
does not check if the array is empty, it checks if the value stored at index i of the array is equal to zero. You probably want something like:
if(array != null && array.length == 0) {
return -1;
}
before the for loop executes.
The rest of your code looks close. The print statement inside of the else clause is unnecessary. You just need to return the value of largest after the for loop executes.
This code is rather strange in general. Why do you consider an array empty as soon as you reach an element that is 0? And why do you continue search, if the array is empty? Last but not least: why do you ignore the last element in the array?
There are plenty of solutions for this that are a lot simpler:
Without any java-api:
if(array.length == 0)
return -1;
int max = Integer.MIN_VALUE;
for(int i = 0 ; i < array.length ; i++)
if(max < array[i])
max = array[i];
return max;
A lazy solution using Arrays.sort() (not exactly elegant, but short)
Arrays.sort(array);
return array[array.length - 1];
Using java8:
return Arrays.stream(array).min((a , b) -> new Integer(a).compareTo(b)).orElse(-1);
Lets take a look at your code
for(i = 0;i < array.length-1;i++)//You will never reach the last number
if(array[i] == 0){//Here you check if the first item equals zero. Gives error if there is no first item.
empty = true;//why do you need this, you never use it.
n = -1;
System.out.println(n);
}else{
largest = array[0];//Why setting largest, do dont know if it is actually bigger
if(array[i] > largest){
largest = array[i];
System.out.println(array[i]);
}
}
Improved version:
largest = -1;//set it by default
for(i = 0;i < array.length;i++)//if length is 10 iMax = 9, which is the tenth item.
if(array[i]>largest){//if larger set the new value
largest = array[i];
}
}
System.out.println(largest);//print the largest number.
if(array.length == 0){
empty = true;
n = -1;
System.out.println(n);
}else{
largest = array[0];
for(i = 1; i < array.length; i++)
if(array[i] > largest){
largest = array[i];
}
System.out.println(largest);
}
First what i did is check if the array is empty. If it is then skip the else and output the -1. If the array is not empty set the largest to the first element and then loop through all other elements. Noticed I changed i = 1 because element 0 is already the largest. Also I removed the -1 to the array length because i will stop 1 before the length (which will be the last index of final element). Finally I moved the print of the largest value outside of the if statement and for loop so that it only gets printed once at the very end.
First check if the array is empty
if(array != null && array.length == 0) {
If it is print -1
System.out.println(-1 + "");
}
Now you are ready to go through the array. But before you do create a variable that will keep track of the largest value. I set it to the first element in the array (since we know that it has at least one element since we already determined that it isn't empty)
else {
int largest = array[0];
Then, loop through the array
for(i = 0;i < array.length-1;i++) {
Get every element one at a time using i to access the ith element
int current = array[i];
Then compare it to the largest. If it's greater than the largest so far, save it as the largest.
if (current>largest) {
current = largest;
}
Keep doing that until finished looping through the array
}
Then print out the largest
System.out.println(largest + "");
}

Remove every 3rd element in arraylist

I am trying to loop through an arraylist and gradually remove an element every 3 indices. Once it gets to the end of the arraylist I want to reset the index back to the beginning, and then loop through the arraylist again, again removing an element every 3 indices until there is only one element left in the arraylist.
The listOfWords is an array with a length of 3 that was previously filled.
int listIndex = 0;
do
{
// just to display contents of arraylist
System.out.println(listOfPlayers);
for(int wordIndex = 0; wordIndex < listOfWords.length; wordIndex++
{
System.out.print("Player");
System.out.print(listOfPlayers.get(wordIndex));
System.out.println("");
listIndex = wordIndex;
}
listOfPlayers.remove(listOfPlayers.get(listIndex));
}
while(listOfPlayers.size() > 1);
I have tried to implement for several hours yet I am still having trouble. Here's what happens to the elements of the arraylist:
1, 2, 3, 4
1, 2, 4
1, 2
Then it throws an 'index out of bounds error' exception when it checks for the third element (which no longer exists). Once it reaches the last element I want it to wrap around to the first element and continue through the array. I also want it to start where it left off and not from the beginning once it removes an element from the arraylist.
Maybe I have just missed the boat, but is this what you were after?
import java.util.ArrayList;
import java.util.Random;
public class Test {
public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<Integer>();
Random r = new Random();
//Populate array with ten random elements
for(int i = 0 ; i < 4; i++){
numbers.add(r.nextInt());
}
while(numbers.size() > 1){
for(int i = 0; i < numbers.size();i++){
if(i%3 == 0){//Every 3rd element should be true
numbers.remove(i);
}
}
}
}
}
You could move every third element to a temporary list then use List#removeAll(Collection) to remove the items when you finish each loop...until the master list was empty...
Lets back up and look at the problem algorithmically.
Start at the first item and start counting.
Go to the next item and increment your count. If there is no next item, go to the beginning.
If the count is '3', delete that item and reset count. (Or modulo.)
If there is one item left in the list, stop.
Lets write pseudocode:
function (takes a list)
remember what index in that list we're at
remember whether this is the item we want to delete.
loop until the list is size 1
increment the item we're looking at.
increment the delete count we're on
should we delete?
if so, delete!
reset delete count
are we at the end of the list?
if so, reset our index
Looking at it this way, it's fairly easy to translate this immediately into code:
public void doIt(List<String> arrayList) {
int index = 0;
int count = 0;
while(arrayList.size() != 1) {
index = index + 1;
count = count + 1; //increment count
String word = arrayList.get(index);//get next item, and do stuff with it
if (count == 3) {
//note that the [Java API][1] allows you to remove by index
arrayList.remove(index - 1);//otherwise you'll get an off-by-one error
count = 0; //reset count
}
if (index = arrayList.size()) {
index = 0; //reset index
}
}
}
So, you can see the trick is to think step by step what you're doing, and then slowly translate that into code. I think you may have been caught up on fixing your initial attempt: never be afraid to throw code out.
Try the following code. It keeps on removing every nth element in List until one element is left.
List<Integer> array = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
int nth = 3;
int step = nth - 1;
int benchmark = 0;
while (array.size() > 1) {
benchmark += step;
benchmark = benchmark > array.size() - 1 ? benchmark % array.size() : benchmark;
System.out.println(benchmark);
array.remove(array.get(benchmark));
System.out.println(array);
}
You could use a counter int k that you keep incrementing by three, like k += 3. However, before you use that counter as an index to kick out any array element, check if you already went beyond and if so, subtract the length of this array from your counter k. Also make sure, to break out of your loop once you find out the array has only one element left.
int k = -1;
int sz = list.length;
while (sz > 1)
{
k += 3;
if (k >= sz)
{
k -= sz;
}
list.remove(k);
sz --;
}
This examples shows that you already know right away how often you will evict an element, i.e. sz - 1 times.
By the way, sz % 3 has only three possible results, 0, 1, 2. With a piece of paper and a cup of coffee you can find out what the surviving element will be depending on that, without running any loop at all!
You could try using an iterator. It's late irl so don't expect too much.
public removeThirdIndex( listOfWords ) {
Iterator iterator = listOfWords.iterator
while( iterator.hasNext() ){
iterator.next();
iterator.next();
iterator.next();
iterator.remove();
}
}
#Test
public void tester(){
// JUnit test > main
List listOfWords = ... // Add a collection data structure with "words"
while( listOfWords.size() < 3 ) {
removeThirdIndex( listOfWords ); // collections are mutable ;(
}
assertTrue( listOfWords.size() < 3 );
}
I would simply set the removed to null and then skip nulls in the inner loop.
boolean continue;
do {
continue = false;
for( int i = 2; i < list.length; i += 3 ){
while( list.item(i++) == null && i < list.length );
Sout("Player " + list.item(--i) );
continue = true;
}
} while (continue);
I'd choose this over unjustified shuffling of the array.
(The i++ and --i might seem ugly and may be rewritten nicely.)

ArrayList and IndexOutOfBounds exception

So I'm getting an index out of bounds exception on some code i'm writing. What I don't understand is that I know for a fact that the index element I'm trying to work with exists.
Here's the code:
I have a constructor for an array list
public StixBoard(int number)
{
stixGame = new ArrayList<Integer>(number);
for (int i = 0; i < number; i++)
{
stixGame.add(i);
}
}
This block generates a random variable 1-3
public int computeMove()
{
int numberOfStix = (int) (3.0 * Math.random()) + 1;
return numberOfStix;
}
Really straight forward, now here I have a method that takes the parameter supplied and attempts to remove those number of elements from the array list. As you can see, the parameter must be between 1 and 3, and it must be less than or equal to the size of the array list. Otherwise, the user is prompted to enter another number
public boolean takeStix(int number)
{
boolean logicVar = false;
placeHolder = stixGame.size();
if ((number >= 1 && number <= 3) && number <= placeHolder)
{
for (int i = 0; i < number; i++)
{
stixGame.remove(i);
logicVar = true;
}
} else if (number > 3 || number > placeHolder)
{
do
{
System.out
.println("Please enter a different number, less than or equal to three.");
Scanner numberScan = new Scanner(System.in);
number = numberScan.nextInt();
} while (number > 3 || number > placeHolder);
}
return logicVar;
}
So as this program runs, the computeMove() method generates a random int (assuming the role of a computerized player) and attempts to translate that value to the number of indexes to be removed from the array list.
This ultimately brings me to this:
How many stix on the table? 4
|||||||||| 4 stix on the table
It's the computer's turn!
The computer chose 3
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.remove(ArrayList.java:387)
at StixBoard.takeStix(StixBoard.java:38)
at StixGame.main(StixGame.java:55)
So as you can see, the array list is of size 4, but when the computer rolls a 3, (which should leave me with 1), I am left with this error. How does my array list go from being of size 4 indexes to size 2?
You iterate through your list, from beginning to end, and remove an element at each step. This makes all the elements in the list shift to the left.
First iteration: i = 0
[1, 2, 3]
Second iteration: i = 1
[2, 3]
Third iteration: i = 2
[2] -> IndexOutOfBoudsException. There is no index 2 in this list.
Iterate from the end to the beginning instead. That willmake it correct, and faster since the list won't have to copy all the elements from right to left.
The problem is in this loop:
for (int i = 0; i < number; i++)
{
stixGame.remove(i);
logicVar = true;
}
Once you remove the elements then list size is also decreased. If you start with list size 3 then in 3rd iteration, the index becomes 2 as initially 0 then 1 then 2 while size becomes 1 as intially 3 then 2 then 1. Hence IndexOutOfBoundException.
Try this:
for (int i = 0; i < number; i++){
stixGame.remove(0);//remove 0th index as previous element was removed
logicVar = true;
}
Look at it this way.
When you start your for-loop the ArrayList is of size x.
When you call remove() you take an element from the list. So the size is x-1.
But if you're constantly increasing the element you're removing, eventually you'll be removing an index that no longer exists. Remember, when you call remove() the contents of the array list are shifted. So if you had 0,1,2,3 before and removed 2. The list is 0,1,3. if you call remove(4) which was valid initially, you'll get an Out Of Bounds exception

Add 0 and 1 is alternate array cells in java

I have any array with value 0,0,0,0,0,0,0,0,1,1,1
Now my required output should be like each zero will be in odd index and 1 will be in even and if 0 left after that it should be copied after 1 and viceversa.
Means the output will be 0,1,0,1,0,1,0,0,0,0,0....
But the above operation must be done in a single pass of array
So I created an array with same size ,
then I started traversing the main array and one's 0 is encoutered I put a counter to set the value in odd index and viceversa
In the end when the index crossed the length of new array created , I started adding the 0 into the new cell in even mode from backward.
What can be the other better solution.
You don't need an extra array for this. You can do it in-place. Just keep two pointers, one which stops after every odd step and one which finds the 1s. When the second pointer encounters a 1 just swap it with the first pointer, increment the first pointer. Do this for the length of the array.
Lets try inplace in one pass
Keep one pointer at the beginning of the array and one at the end of the array.
I am assuming that number of zeroes is greater than number of ones
int begin = 0, end = length - 1;
while (begin < end){
if (A[begin] == 0 && A[end] == 1){
if (begin % 2 != 0){
int tmp = A[end];
A[end] = A[begin];
A[begin] = temp;
end--;
}
begin++;
}
else
break;
}
Remember, above solution won't work for cases when number of ones is greater than number of zeroes
#include<stdio.h>
main()
{
int arr[]={1,0,0,1,0,1,1,1,0,1};
int n=10;
int odd,one,tmp;
odd=one=0;
while(true)
{
while(odd<n && arr[odd])
odd+=2;
while(one<n && (((one<=odd)&&(one%2==0)) || !arr[one]))
one++;
if(odd<n && one<n)
{
arr[one]=arr[one]^arr[odd];
arr[odd]=arr[one]^arr[odd];
arr[one]=arr[one]^arr[odd];
}
else
break;
}
for(int i=0;i<n;i++)
printf("%d ",arr[i]);
}

Categories