I am trying to design a program to swap the value 0 in an array with the preceding element if it is not a 0.
For instance, if the array is 1 1 0 1 1 1 then the program will keep swapping until it becomes 0 1 1 1 1 1
But when I run this IndexOutOfBoundException occurs. I even tried changing the for loop to:
for(int i = 1; i < newLane.length; i++)
that solved the out of bounds issue, but made it function incorrectly.
The below is my code:
public static int[] down(int[] lane) {
int lan = lane.length; // length of array
int[]newLane = new int[lan]; // creates new 1d matrix
for(int i = 1; i < newLane.length; i++) {
if(newLane[i-1] != 0 && newLane[i] == 0 ){ // getting out of bounds error
int tmp = newLane[i - 1];
newLane[i - 1] = newLane[i];
newLane[i] = tmp;
}
}
return newLane;
}
I think you can simply sort your array :
public static int[] down(int[] lane){
int lan = lane.length; // length of array
int[]newLane = Arrays.copyOf(lane,lan) // creates new 1d matrix
Arrays.sort(newLane);
return newLane;
}
As my comment already says: you're close.
Just add
if(newLane[0] == 0) newLane[0] == 1;
Before the for-loop.
You are nowhere using the elements of array Lane. Currently newLane is an empty array. I have assigned value of Lane to newLane
Change your function to below
public static int[] down(int[] lane){
int lan = lane.length; // length of array
int[]newLane = new int[lan]; // creates new 1d matrix
newLane = lane;
for(int i = 1; i < newLane.length; i++) {
if(newLane[i-1] != 0 && newLane[i] == 0 ){ // getting out of bounds error
int tmp = newLane[i - 1];
newLane[i - 1] = newLane[i];
newLane[i] = tmp;
}
}
if(newLane[0]!=0 && newLane[1]==0)
{
int tmp = newLane[0];
newLane[0] = newLane[1];
newLane[1] = tmp;
}
return newLane;
}
Update
Just after the for loop, check whether the 0th element is non-zero. If yes, then swap it with first.
if(newLane[0]!=0 && newLane[1]==0)
{
int tmp = newLane[0];
newLane[0] = newLane[1];
newLane[1] = tmp;
}
I will try this
public static int[] swapping(int[] lane)
{
int[] result = new int[lane.length];
for(int i = 0; i < result .length; i++) {
if ( result[i]==0)
{
if( i==0)
{
}
else
{
temp = result[i] ;
result[i] = result [i-1] ;
result [i-1] = temp ;
}
else
{
}
return result ;
}
Related
For this particular problem I am attempting to remove redundant elements in an sorted array and replace them all with 0s at the end of the array. For example, if I had an array consisting of the int elements
1,3,3,4,4,5,6,6,7
My output array should be
1,3,4,5,6,7,0,0,0
My first attempt at the problem was to create a swapper in order to push all the 0s to the end of the list after removing the elements, but it won't seem to push the zeros to the end of the list. Here is my code.
public void implode(int[] ary)
{
int swapper = -1;
int[] newARY = new int[ary.length];
int current = -1;
for (int i = 0; i < ary.length; i++)
{
if (current != ary[i])
{
newARY[i] = ary[i];
current = ary[i];
}
}
for (int i = 0; i < ary.length; i++)
{
if (ary[i] == 0)
{
if (ary[i + 1] != 0)
{
swapper = ary[i + 1];
ary[i] = swapper;
ary[i + 1] = 0;
}
}
}
ary = newARY;
for (int i = 0; i < newARY.length; i++)
{
System.out.print(newARY[i] + " ");
}
}
The array im testing it with is,
int[] aryIn2 = {1, 1, 2, 3, 4, 4, 5, 6};
However, when outputting the imploded array, I receive this one.
1 0 2 3 4 0 5 6
Is there something I am missing?
Thanks in advance.
not an answer to your problem, but using (if possible) java streams can shorten your way:
int[] arr = {1,3,3,4,4,5,6,6,7};
// distinct
List<Integer> list = Arrays.stream(arr).distinct().boxed().collect(Collectors.toList());
// pad with zero's
while(list.size() < arr.length) {
list.add(0);
}
// display
System.out.println(list.stream().map(String::valueOf).collect(Collectors.joining(",")));
will output
1,3,4,5,6,7,0,0,0
Two issue with you code that I observed.
1) Your swapper logic is performing swapping on a different array than the one in which you had done modification earlier
2) You need to have this logic in a bubble-sort way, i.e. loop inside a loop
Below is a working modified sample code of your method. I have modified only the second for-loop logic
public void implode(int[] ary) {
int swapper = -1;
int[] newARY = new int[ary.length];
int current = -1;
for (int i = 0; i < ary.length; i++) {
if (current != ary[i]) {
newARY[i] = ary[i];
current = ary[i];
}
}
for (int i = 0; i < newARY.length - 1; i++) {
if (newARY[i] == 0 && newARY[i + 1] != 0) {
for (int j = i; (j + 1) < newARY.length; j++) {
swapper = newARY[j + 1];
newARY[j] = swapper;
newARY[j + 1] = 0;
}
}
}
for (int i = 0; i < newARY.length; i++) {
System.out.print(newARY[i] + " ");
}
}
In this first loop:
for (int i = 0; i < ary.length; i++) {
if (current != ary[i]) {
newARY[i] = ary[i];
current = ary[i];
}
}
You fill newARY with elements in ary with duplicated value turns to 0:
newARY: 1 0 2 3 4 0 5 6
However, in the second loop:
for (int i = 0; i < ary.length; i++)
{
if (ary[i] == 0)
{
if (ary[i + 1] != 0)
{
swapper = ary[i + 1];
ary[i] = swapper;
ary[i + 1] = 0;
}
}
}
You're modifying your original ary array. So the newARY is not updated.
However, your attempt to push 0 to the end of array also fail if there are more than two 0s consecutive. And it is also vulnerable to ArrayOutOfBoundIndexException since you try to read ary[i+1] without restriction on i
One simple and straight forward way to push 0s to the end of the array is to create new array with non-0s elements and fill 0s later:
int[] result = new int[ary.lenght];
int resultIndex = 0;
for (int i = 0; i < newARY.length; i++) {
if (newARY[i] != 0) {
result[resultIndex++] = newAry[i];
}
}
for (int i = resultIndex; i < newARY.length; i++) {
result[i] = 0;
}
// Print result array
Hint: Using above strategy, you can simplify your code. No need to create immediate array newARY. Just loop over the original array, push unique elements to the result array, then fill any slot left with 0s.
I am having trouble to create a (recursive) function that prints all possible indexes for a multi dimensional table.
I got the information about the multi-dimensionality as an array.
Example:
int[]{6,6} would be a 2-dimensional table with 6x6 = 36 fields, so the result would be [0,0],[0,1],[1,1],[1,2],[2,2]... and so on.
Another example:
int[]{2,2,2} would be a 3-dimensional table with 8 possible indexes: [0,0,0],[0,0,1],[0,1,1]... and so on
I'm trying to do this in Java 7.
Edit: As requested, what I got so far. Code is producing OutOfBound Exception.
loop(new int[2], new int[]{6, 6}, 0);
private void loop(int[] index, int[] dimensionSizes, int dimensionIndex) {
if (index[dimensionIndex] < dimensionSizes[dimensionIndex] && dimensionIndex < dimensionSizes.length) {
System.out.println(Arrays.toString(index));
index[dimensionIndex] = index[dimensionIndex] + 1;
if (index[dimensionIndex] < dimensionSizes[dimensionIndex]) {
loop(index, dimensionSizes, dimensionIndex);
} else {
loop(index, dimensionSizes, dimensionIndex + 1);
}
}
}
I think this code could respond to your question:
public static void printAllIndex(int[] dimensions) {
int[] index = new int[dimensions.length];
int stepNumber = 0;
// Initialization
for (int i : index) { index[i] = 0; } // init index to 0
for (int d : dimensions) { stepNumber += d; } // count number of iteration needed
System.out.println(Arrays.toString(index)); // print first index [0,0,...]
for(int s = 0; s <= stepNumber - 1; s++) {
boolean allEquals = true;
int value = index[index.length - 1];
for (int i = index.length - 1; i >= 0; i--) {
if(index[i] != value) {
index[i]++;
allEquals = false;
break;
}
}
if (allEquals) { index[index.length - 1]++; }
System.out.println(Arrays.toString(index));
}
}
I am currently learning Java. Below is a list of methods from a simple Java program I have written. Is there anything that stands out in these methods would cause the execution of the program to go very slow? It's taking four seconds to execute using an array containing just 6 integers:
EDITED: here's the entire program as requested. I wrote it in Textpad. I realise it is not the most efficient algorithm. It does what it is supposed to do, but takes too long to do it.
import java.util.*;
public class Supermarket
{
public static void main(String [] args)
{
int[] custTimes =
{
1, 6, 7, 4, 4, 3, 5, 1, 2, 1, 3, 6, 4
};
int checkOuts = 6;
int answer;
answer = Solution.solveSuperMarketQueue(custTimes, checkOuts);
System.out.println("Answer is " + answer);
}
}//~public class Supermarket...
class Solution
{
static int myTotal;
static int solveSuperMarketQueue(int[] customers, int n)
{
// ******************* INITIALIATION ***********************
myTotal = 0;
int len = customers.length; // length of customer queue
if (len < 1)
{
return 0;
}
int[] till = new int[n]; // array to store all tills and till queues
int tillMin; // Minimum time
int tillMax; // Maximum time
// Put the customers into an arraylist:
ArrayList<Integer> times = new ArrayList<Integer>();
for (int i = 0; i < len; i = i + 1)
{
times.add(i, customers[i]);
}
// create the array of tills and set all queue intial values to 0
for (int i = 0; i < n; n = n + 1)
{
till[i] = 0;
}
// Move the queue to tills to start off
ReturnPair result = copyQueue(till, times);
till = result.getArr();
times = result.getList();
int s = times.size();
tillMax = getMaxTime(till);
tillMin = getMinTime(till);
// ***************** END OF INITIALIATION ******************
// *****************MAIN LOOP ******************************
while (tillMax > 0)
{
// Find customer(s) with least time use that time to move all queues
// and update myTotal time.
// STEP 1: get minimum time in tills array (ignore zero)
tillMin = getMinTime(till);
// STEP 2: subtract minimum value from all the tills, but not if till has a zero
if (tillMin > 0)
{
till = subtractTime(till, tillMin);
}
// Move the queue to tills
if (s > 0)
{
result = copyQueue(till, times);
till = result.getArr();
times = result.getList();
}
tillMax = getMaxTime(till);
tillMin = getMinTime(till);
}
return myTotal;
// **************** END OF LOOP *****************************
}//~public static int solveS...
// ****************** METHODS **********************************
// Method to move queue foward
// For each till, a time is copied from the customer array.
// The values are copied in order.
// The value is coped only if array value is zero.
private static ReturnPair copyQueue(int[] arr, ArrayList<Integer> arrList)
{
int n = arr.length; // for each till...
for (int i = 0; i < n; i = i + 1)
{
if (arr[i] == 0 && arrList.size() > 0) // only copy if it current till value is 0 AND arrayList value exists
{
arr[i] = arrList.get(0);
arrList.remove(0);
}
}
// returns an instance of the object myResult which is a container for an array and an arraylist
return new ReturnPair(arr, arrList);
}
// Method to get minimum time from array (but not zero).
private static int getMinTime(int[] arr)
{
int minValue = 0;
// make sure arr[i] isn't zero.
for (int i = 0; i < arr.length; i = i + 1)
{
if (arr[i] != 0)
{
minValue = arr[i];
break;
}
}
// Find minimum value that isn't zero.
for (int i = 1; i < arr.length; i = i + 1)
{
if (arr[i] != 0 && arr[i] < minValue)
{
minValue = arr[i];
}
}
return minValue;
}//~static int getMinTime(in...
// Method to subtract minimum time from tills
private static int[] subtractTime(int[] arr, int min)
{
int n = arr.length;
for (int i = 0; i < n; i = i + 1)
{
if (arr[i] != 0)
{
arr[i] = arr[i] - min;
}
}
// update myTotal
myTotal = myTotal + min;
return arr;
}//~static void subtractTime...
private static int getMaxTime(int[] arr)
{
int maxValue = arr[0];
for (int i = 1; i < arr.length; i = i + 1)
{
if (arr[i] > maxValue)
{
maxValue = arr[i];
}
}
return maxValue;
}
}//~class Solution...
// Special class designed to return an array and an array list as an object
class ReturnPair
{
// set up fields
int[] newArr;
ArrayList<Integer> newArrList;
// define method
public ReturnPair(int[] first, ArrayList<Integer> second)
{
this.newArr = first;
this.newArrList = second;
}
public int[] getArr()
{
return newArr;
}
public ArrayList<Integer> getList()
{
return newArrList;
}
}
for (int i = 0; i < n; n = n + 1)
This line is incrementing n instead of i. it will loop until n overflows. It should be:
for (int i = 0; i < n; i++)
Because int arrays are initialized to 0 anyway, you can remove this loop completely.
I have a 2d array
0 1 0
0 * 0
0 * 0
0 2 0
0 * 0
That I altered to be this
0 * 0
0 * 0
0 * 0
0 1 0
0 2 0
By doing this
Dot[][] tempDot = dotArray;
ArrayList<Descriptor> movedList = new ArrayList<Descriptor>();
for(int j=0; j<this.getHeight(); j++){
for (int i=this.getHeight()-1; i>0; i--){
if(dotArray[i][col] == null){
dotArray[i][col] = dotArray[i-1][col];
dotArray[i-1][col] = null;
}
}
}
Now I'm trying to figure out how compare the second column in the first one to the second column in the second one. I have to return a "Descriptor" object which contains the original location any non-null that moved down. I have tried doing nesting for loops to check the first value in each loop and then finding the first value in the second loop but that wasn't working. Any help would be great!
If Descriptor is defined like this,
private class Descriptor {
Descriptor(int from, int to, Dot[] dots) {
this.from = from;
this.to = to;
this.dots = dots;
}
public int from;
public int to;
public Dot[] dots;
}
you can do this way.
// Store original location(index) of each row.
Map<Dot[], Integer> originLocMap = new HashMap<Dot[], Integer>();
for (int i = 0; i < tempDot.length; i++) {
originLocMap.put(tempDot[i], i);
}
// Sort rows by second column (dot[*][1])
for (int i = tempDot.length - 1; i > 0; i--) {
if (tempDot[i][1] != null) {
continue;
}
for (int j = i - 1; j >= 0; j--) {
if (tempDot[j][1] != null) {
Dot[] temp = tempDot[i];
tempDot[i] = tempDot[j];
tempDot[j] = temp;
break;
}
}
}
// Collect location change data
ArrayList<Descriptor> movedList = new ArrayList<Descriptor>();
for (int i = tempDot.length - 1; i >= 0; i--) {
if (tempDot[i][1] == null) {
break;
}
Dot[] dots = tempDot[i];
int from = originLocMap.get(dots);
Descriptor descriptor = new Descriptor(from, i, dots);
movedList.add(descriptor);
}
Iterator<Descriptor> it = movedList.iterator();
while (it.hasNext()) {
Descriptor d = it.next();
System.out.println(d.from + " ==> " + d.to);
}
The following is NOT a homework problem, it's just a set of problems that I've been working through for practice and I was wondering if anybody else could figure it out:
http://codingbat.com/prob/p159339
Return an array that contains exactly the same numbers as the given array, but rearranged so that every 3 is immediately followed by a 4. Do not move the 3's, but every other number may move. The array contains the same number of 3's and 4's, every 3 has a number after it that is not a 3 or 4, and a 3 appears in the array before any 4.
*SOLVED - here is my working code:
public int[] fix34(int...nums)
{
int[] returnArray = new int[nums.length];
//ASSIGN ARRAY
//We know that all 3's can't be moved, and after every 3 there
//will automatically be a 4
for(int i = 0; i<nums.length; i++)
{
if(nums[i] == 3)
{
returnArray[i] = 3;
returnArray[i+1] = 4;
}
}
//REBUILD ARRAY - UNMOVED INDEXES
//If a value was not moved/affected by the above, it will get placed into the array
//in the same position
for (int i = 0; i < nums.length; i++)
{
if (returnArray[i] != 3 && returnArray[i] != 4 && nums[i] != 3 && nums[i] != 4)
{
returnArray[i] = nums[i];
}
}
//REBUILD ARRAY - MOVED INDEXES
//changed values = 0 in returnArray, as a result, any time we hit a 0 we
//can simply assign the value that was in the 4's place in the nums array
OuterLoop: for (int i = 0; i < nums.length; i++)
{
if (returnArray[i] == 0)
{
for (int n = 0; n < returnArray.length; n++)
{
if (returnArray[n] == 4)
{
returnArray[i] = nums[n];
continue OuterLoop;
}
}
}
}
return returnArray;
}
I don't know java, but maybe I can help anyway. i dont want to give you the solution, but think of it like this:
you can move every number that isn't a 3. that's our only limit. that being said:
the only spots you need to change are the spots following 3s....so....every time you loop through, your program should be aware if it finds a spot after a 3 that isn't a 4....
it should also be aware if it finds any 4s not preceded by a 3......
during each loop, once it's found the location of each of those two things, you should know what to do.
Initialize all the variables
for(int i = 0; i<n-1; i++)
{
if(arr[i] == 3)
{
if(arr[i+1] == 4)
continue;
else
{
temp = 0;
while(arr[temp] != 4)
temp++;
//Write your own code here
}
//Complete the code
}
I have NOT provided the entire code. Try completing it as you said it was for your practice.
public int[] fix34(int[] nums) {
int[] arr = new int[nums.length];
int index = 0;
int tempVal= 0,j=0;
for(int i=0;i<nums.length;i++){
if(nums[i]==3){
arr[i] = nums[i];
index=i+1;
tempVal = nums[i+1];
j=index;
while(j<nums.length){
if(j<nums.length && nums[j]==4){
//System.out.println(j+"\t="+nums[j]);
nums[j]=tempVal;
nums[index] = 4;
break;
}
j++;
}
tempVal=0;
index=0;
}else{
arr[i] = nums[i];
}
}
index =0;
for(int i=0;i<nums.length;i++){
if(nums[i]==3 && nums[i+1]==4){
i+=1;
}else if(nums[i]==4){
index = i;
j=index;
while(j<nums.length){
if(nums[j]==3 && nums[j+1]!=4){
arr[index] = nums[j+1];
arr[j+1] = 4;
}
j++;
}
}
}
return arr;
}
Here's mine: A little overkill, but is always right, anyways i make 2 additional arrays and I make 2 passes in the loop putting the correct elements in the correct places. See Logic Below.
public int[] fix34(int[] nums) {
int index1 = 0;
int index2 = 0;
int index3 = 0;
int[] only4 = fours(nums); //holds all 4's in nums
int[] misc = new int[count4(nums)]; //will hold numbers after 3
for(int a = 0; a < nums.length - 1; a++){
if(nums[a] == 3){
misc[index1] = nums[a + 1]; //get it for later use
index1++;
nums[a + 1] = only4[index2]; //now the number after 3 is a 4, from the
index2++; //only4 array
}
}
for(int b = 1; b < nums.length; b++){
if(nums[b] == 4 && nums[b - 1] != 3){ //finds misplaced 4's
nums[b] = misc[index3]; //replaces lone 4's with the
index3++; //right hand side of each 3 original values.
}
}
return nums;
}
public int count4(int[] nums){
int cnt = 0;
for(int e : nums){
if(e == 4){
cnt++;
}
}
return cnt;
}
public int[] fours(int[] nums){
int index = 0;
int[] onlyFours = new int[count4(nums)]; //must set length
for(int e : nums){
if(e == 4){
onlyFours[index] = e;
index++;
}
}
return onlyFours;
}
I solved mine using two ArrayLists which contain the places of 3's and 4's.
I hope this helps.
public int[] fix34(int[] nums)
{
//Create a copy of nums to manipulate.
int[] ret = nums;
//Create two ArrayLists which carry corresponding places of 3 and 4;
ArrayList<Integer> threePositions = new ArrayList<Integer>();
ArrayList<Integer> fourPositions = new ArrayList<Integer>();
//Get the places of 3 and 4 and put them in the respective ArrayLists.
for (int i = 0; i < ret.length; i++)
{
if (ret[i] == 3)
{
threePositions.add(i);
}
if (ret[i] == 4)
{
fourPositions.add(i);
}
}
//Swap all ints right after the 3 with one of the 4s by using the referenced
//ArrayLists values.
for (int i = 0; i < threePositions.size(); i++)
{
int temp = ret[threePositions.get(i) + 1];
ret[threePositions.get(i) + 1] = ret[fourPositions.get(i)];
ret[fourPositions.get(i)] = temp;
}
//Return the ret array.
return ret;
}