Add 0 and 1 is alternate array cells in java - 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]);
}

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

Running several iterations in a while loop

I am trying to solve a problem of finding the smallest and second smallest element in an array.
I am thinking of putting two pointers on the 0th index of the array. Both the pointers move from left to right traversing the entire array. First pointer ptr1 determines the min element while the second pointer intends to determine the second min element. The first pointer works ok but the second pointer doesn't traverse. While loop exits only after 1 iteration of the second pointer.
Is it possible to have n pointers in a while loop & make them traverse
from left to right turn by turn?
Or I am doing something wrong.
Below is the code
int arr[] = {12,13,1,10,34,1};
int ptr1 = 0;
int ptr2 =0;
int min = Integer.MAX_VALUE;
int minSec = Integer.MAX_VALUE;
int arrLen=arr.length-1;
while(ptr1<arrLen && ptr2<arrLen){
if(arr[ptr1]<min){ // this if works great finds the min element
min=arr[ptr1];
ptr1++;
}else{
ptr1++;
}
//flow enters once & exits the while loop
if(ptr1==arrLen && arr[ptr2]<minSec && arr[ptr2]>min){
minSec=arr[ptr2];
ptr2++;
}else if(ptr1==arrLen){
ptr2++;
}
}
System.out.println("min: " + min + " second min: "+ minSec)
output: min: 1 second min: 12
the correct output should be min: 1 second min: 10
I am able to solve the problem with another approach, code below. I just need to know about the while loop approach.
for (int i = 0; i <= arrLen ; i ++)
{
/* If current element is smaller than first
then update both first and second */
if (arr[i] < min)
{
minSec = min;
min = arr[i];
}
/* If arr[i] is in between first and second
then update second */
else if (arr[i] < minSec && arr[i] != min)
minSec = arr[i];
}
Because ptr2 value is 0 until loop reach the end
if(ptr1==arrLen && arr[ptr2]<minSec && arr[ptr2]>min){
minSec=arr[ptr2];
ptr2++;
}
and enter into the if condition only ptr1==arrLen then you select the minSec value as minSec=arr[ptr2]. No point of putting this condition here.
So second if condition will be like
if(arr[ptr2]<minSec && arr[ptr2]>min){
minSec=arr[ptr2];
ptr2++;
}else{
ptr2++;
}
Your problem is that the first if statement still works even if you found the smallest number. So all over traversed elements are either greater as or equal to the smallest number. That means pointer 1 is incremented every "while step". In your second if statement you check if pointer 1 is equal to array length but this case is present in only one "while step".
PS: Just let java sort your array. The work is already done for you ;)
You do not need two pointers
int arr[] = {12,13,1,10,34,1};
final int arrLen=arr.length;
int min = Integer.MAX_VALUE;
int minSec = Integer.MAX_VALUE;
for (int e=0; e<arrLen; e++) {
final int v = arr[e];
if (v<minSec && v>min)
minSec = v;
if (v<min && v<minSec)
min = v;
}
if (min>minSec)
min = minSec;
The problem is in this while(ptr1<arrLen && ptr2<arrLen) statement coupled with moving the second pointer only when ptr1 is at length.
What happens is ptr1 is at arrLen so the second pointer iterates once, but because you use an && when ptr1<arrLen is evalued to be false the entire loop exits. Using an or will not fix this because you have other problems in the code that will cause an IndexOutOfBoundsError.

Array not looping correctly - 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;

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

Pseudo code needed if possible?

I was wondering if I could have some pseudo code for working out the following
i need to loop through a 2d array(the method i am working on takes an int). It starts at the position of the value passed in and then goes down until it hits the same value on the left hand side. As its doing this every int in the 2d array is added to a local variable.
Now we are at position (x,x) i guess? Then from here i need to loop across to the right adding all variables to the same previous local var and then return that number
The 2d array for illustration purposed looks something like this for example
1 2 3 4
2 3 4 5
1 2 3 4
3 2 1 4
So if i were to pass in 2 we would start at the number 3 top line i guess, we would loop down until position 3,3 ( 3 + 4 + 3) and then loop to the right until the end (+ 4)
those numbers would be added and returned.
I hope pseudo code is possible and I haven't just given it already myself lol (thus proving i cant actually code it lol :D )
if not any examples you could provide me with that my help me out :D
thanks guys
I think this pseudocode should do what you're looking for:
array[][] := ...
position := ...
sum := 0
//add the contents of the outer array
for i := 0 to array.length do
sum := sum + array[i][position]
//if we're at (pos, pos) then start looping over the inner array
if i = position then
//note we start at pos + 1 so as not to count array[i][position] twice
for j := position + 1 to array[j].length do
sum := sum + array[i][j]
end
break from loop
end
end
Not sure what you are trying to achieve, I assume this is just an assignment.
If you are looping to the right, shouldn't 1 be included if not the 2 as well?
i.e. then loop to the right until the end (+1 + 4)
The answer depends on whether you store the columns or the rows of matrix. Assuming you have a n * n size matrix and you store the rows, so
A = [[1,2,3,4], [2,3,4,5], [1,2,3,4], [3,2,1,4]]
and the starting point is i, you should go from the array no. m = i div n (the integer part of the division, rounding down), and inside the array, the staring element should be the no. p = i mod n (the modulus). And from that point, you can select every array from m to n, and in every array, the pth element, until the most recent element is the same as your original.
In Java-like code:
int n = 4;
int[][] A = new int[n][n];
... // initialize A
int sumValues(int i) {
int original = A[i/n][i%n];
int sum = original;
int p = i % n;
for (m = i/n + 1, m<n, ++m) {
if (A[m][p] != orginal) sum += A[m][p];
else break;
}
return sum;
}
If you are storing the columns, so
A = [[1,2,1,3], [2,3,2,2], [3,4,3,1], [4,5,4,4]]
then m and p are inversed, meaning that from A you should select array no. m = i mod n and inside that array, element no. p = i div n. After this, you stay in your selected array, and just increase p until A[m][p] equals to the originally selected value.
In Java-like code:
int n = 4;
int[][] A = new int[n][n];
... // initialize A
int sumValues(int i) {
int original = A[i%n][i/n];
int sum = original;
int p = i / n;
for (p = i/n +1, p<n, ++p) {
if (A[m][p] != orginal) sum += A[m][p];
else break;
}
return sum;
}
But correct me, if I'm wrong :)

Categories