Moving array elements to the left - java

Writing a code that shifts array elements left by an int n (keyboard input) and replaces space with zeros.
Ex. int[] data = { -1, 1, 3, 7, 5} and I want to see { 3, 7, 5, 0, 0}.
Suppose I have:
public static void shiftLeft( int[] data, int n )
{
System.arraycopy( data, 1, data, 0, data.length - 1 );
data[data.length - 1] = 0;
}
Any quick help would be great.

You were close, but your srcPos argument should be n and the length argument should be data.length - n. You can then use the overloaded Arrays#fill method that accepts a start/end index to fill the rest of the array with 0:
public static void shiftLeft(int[] data, int n) {
System.arraycopy(data, n, data, 0, data.length - n);
Arrays.fill(data, data.length - n, data.length, 0);
}
Testing this with your example input yields the following:
int[] data = { -1, 1, 3, 7, 5};
shiftLeft(data, 2);
System.out.println(Arrays.toString(data));
Output:
[3, 7, 5, 0, 0]

Related

When building array program in Java, it does not return the last number of the array when following the array.length - 1 method

I am writing a small program to take an input array, nums and create a new array that is double the size and returns the last number from the previous array as the last and only different number in the new array.
When I try to return this number using the nums.length - 1 formula to get the end of the array, it returns the number in the middle of the new array. Below is my program.
public int[] makeLast(int[] nums) {
int lengonewarr = nums.length;
int officiallength = lengonewarr * 2;
int [] makezero = new int [officiallength];
makezero [nums.length-1] = nums[nums.length-1];
return(makezero);
}
These are the outputs I should be making:
makeLast([4, 5, 6]) → [0, 0, 0, 0, 0, 6]
makeLast([1, 2]) → [0, 0, 0, 2]
makeLast([3]) → [0, 3]
But I instead get something like:
makeLast([1, 2, 3, 4]) → [0, 0, 0, 0, 0, 0, 0, 4] (My output) [0, 0, 0, 4, 0, 0, 0, 0]
makeLast([2, 4]) → [0, 0, 0, 4] (My output) [0, 4, 0, 0]
Any advice is greatly appreciated.
the array makezero's length is officiallength, not nums.length, just replace the first nums.length by makezero.length or officiallength.
makezero [makezero.length -1] = nums[nums.length-1];
BTW: It's better to name the variable with camelCase style, which will make the code more readable. Like makeZero or officialLength
I modified your and here it is:
public int[] makeLast(int[] nums) {
int lengonewarr = nums.length;
int officiallength = lengonewarr * 2;
int [] makezero = new int [officiallength];
makezero [makezero.length-1] = nums[nums.length-1];
return(makezero);
}
As the array makezero is double size, the length of lengonewarr is always in the middle of makezero.

Best performance to search a number in a column of a 2d array without cloning the array

I am trying to search for a number in a particular column of a two dimensional array. I tried a few different approach and would like to use stream in Java 8. However, it doesn't seem to be the best performance. Wonder if someone can help?
boolean isInColumn(int col, int number) {
return IntStream.range(0, board.length)
.map(i -> board[i][col])
.filter(num -> num == number )
.findFirst()
.isPresent();
}
trying to search in a block as well. Any hints?
public boolean isInBlock(int row, int col, int number) {
int r = row - row % 3;
int c = col - col % 3;
for (int i = r; i < r + 3; i++) {
for (int j = c; j < c + 3; j++) {
if (board[i][j] == number)
return true;
}
}
return false;
}
the input data is the following array.
public static int[][] PUZZLE = {
{9,0,0,1,0,0,0,0,5},
{0,0,5,0,9,0,2,0,1},
{8,0,0,0,4,0,0,0,0},
{0,0,0,0,8,0,0,0,0},
{0,0,0,7,0,0,0,0,0},
{0,0,0,0,2,6,0,0,9},
{2,0,0,3,0,0,0,0,6},
{0,0,0,2,0,0,9,0,0},
{0,0,1,9,0,4,5,7,0},
};
This 'stream'-version seems a little bit optimzed, but I think searching for a hit in an array will always be faster the old fashioned way, see Java performance tutorial – How fast are the Java 8 streams?
boolean isInColumn(int col, int number) {
return IntStream.range(0, board.length)
.anyMatch(i -> (board[i][col] == number) );
}
I made a short attempt with a parallel stream, but the overhead made it far worse.
I think it would be different if the action wasn't a simple compare...
If it's only about speed for a Sudoku-solver/generator maybe you shouldn't loop at all but write the 9 conditions in one return statement
return board[0,col] == number || board[1,col] == number ...
Since this seems to be Sudoku what you could do is store the data redundantly. Don't only store the numbers in "normally" in a two dimensional array, but also have two-dimensional boolean arrays, where you store whether the row/column/block contains the number.
class Sudoku {
private final int[][] puzzle = new int[9][9];
private final boolean[][] rows = new boolean[9][9];
private final boolean[][] columns = new boolean[9][9];
private final boolean[][] blocks = new boolean[9][9];
public void setCell(int row, in column, int number) {
puzzle[row][column] = number;
rows[row][number - 1] = true;
columns[column][number - 1] = true;
blocks[calcBlockId(row, column)][number - 1] = true;
}
// returns a number (0 - 8) identifying a block
// 0 - 2 is first line, 3 - 5 second line, etc.
private int calcBlockId(int row, int column) {
// Left as an exercise to the reader
}
public boolean isInColumn(int col, int number) {
return columns[col][number - 1];
}
public boolean isInBlock(int row, int column, int number) {
return blocks[calcBlockId(row, column)][number - 1];
}
}
This code searches for an element in a 2d array and returns the coordinates of the first match, if such an element is present, or null otherwise:
public static int[] findElement(int[][] arr, int element) {
return IntStream
// iterate through the indexes
// of the rows of the array
.range(0, arr.length)
// for each row
.mapToObj(i -> {
// look for the element in this row
int j = IntStream
// iterate through the indexes
// of the elements of the row
.range(0, arr[i].length)
// filter a matching element
.filter(el -> arr[i][el] == element)
// take first match
.findFirst().orElse(-1);
// if element is present
if (j >= 0)
// return its coordinates
return new int[]{i, j};
else
// or null otherwise
return null;
})
// take first non-null coordinates, if they are present
.filter(Objects::nonNull).findFirst()
// or null otherwise
.orElse(null);
}
// test
public static void main(String[] args) {
int[][] puzzle = {
{9, 0, 0, 1, 0, 0, 0, 0, 5},
{0, 0, 5, 0, 9, 0, 2, 0, 1},
{8, 0, 0, 0, 4, 0, 0, 0, 0},
{0, 0, 0, 0, 8, 0, 0, 0, 0},
{0, 0, 0, 7, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 2, 6, 0, 0, 9},
{2, 0, 0, 3, 0, 0, 0, 0, 6},
{0, 0, 0, 2, 0, 0, 9, 0, 0},
{0, 0, 1, 9, 0, 4, 5, 7, 0}};
int[] coordinates = findElement(puzzle, 7);
System.out.println(Arrays.toString(coordinates)); // [4, 3]
}
See also:
• Difference between anyMatch and findAny in java 8
• First unique character in a string using LinkedHashMap

Insert column in desired location of 2D array

I'm looking to choose a column of my array, lets say column 2. I want this column to be inserted at a specific location in the 2D array, lets say column 4.
For example:
1 3 5 5 2
2 4 6 2 1
3 6 9 1 1
The desired output would be:
1 5 5 3 2
2 6 2 4 1
3 9 1 6 1
I know I could loop the following code until I 1 by 1 swap every column until the column is in the desired location.
for (int[] array1 : array) {
int temp = array1[col1];
array1[col1] = array1[col1];
array1[col2] = temp;
}
However, if I'm using large matrices such as 30 columns wide, this would be incredibly inefficient. Is there a way to insert the column anywhere in the 2D array without iterating through each swap until it is in the right spot?
Possibly, a performance may be improved by using parallel processing with streams.
IntStream of row indexes should be used to handle each row separately.
// basic shift method
// from, to - indexes starting from 1
public static void shiftArray(int[] arr, int from, int to) {
int tmp = arr[from - 1];
for (int i = from; i < to; i++) {
arr[i - 1] = arr[i];
}
arr[to - 1] = tmp;
}
public static void main(String[] args) {
int[][] arr2d = {
{1, 3, 5, 5, 2},
{2, 4, 6, 2, 1},
{3, 6, 9, 1, 1}
};
int fromColumn = 2;
int toColumn = 4;
IntStream.range(0, arr2d.length)
.parallel()
.forEach(i -> shiftArray(arr2d[i], fromColumn, toColumn)); // shift each row in parallel
// print the 2D array after shift
Arrays.stream(arr2d)
.map(Arrays::toString)
.forEach(System.out::println);
}
Output:
[1, 5, 5, 3, 2]
[2, 6, 2, 4, 1]
[3, 9, 1, 6, 1]
Try this.
public static void moveColumn(int[][] matrix, int from, int to) {
--from; --to; // If column number begins with zero, remove this line.
int srcPos = from < to ? from + 1 : to;
int destPos = from < to ? from : to + 1;
int length = Math.abs(from - to);
for (int[] array : matrix) {
int temp = array[from];
System.arraycopy(array, srcPos, array, destPos, length);
array[to] = temp;
}
}
and
int[][] matrix = {
{1, 3, 5, 5, 2},
{2, 4, 6, 2, 1},
{3, 6, 9, 1, 1}
};
moveColumn(matrix, 2, 4);
for (int[] row : matrix)
System.out.println(Arrays.toString(row));
output
[1, 5, 5, 3, 2]
[2, 6, 2, 4, 1]
[3, 9, 1, 6, 1]

Finding the Largest through Reduce and Conquer

I have a problem I need help solving, basically, the problem asks me to use a Reduce and Conquer Algorithm to find the largest element.
Problem Description: Return the largest element in a non-empty array of integers. We'll use the convention of considering only part of the array that begins at a given index and ends at another. In this way, a recursive call can work through any part of the array. The initial call will pass in index 0 and the index to the last element.
Some of the things I thought of was to approach this problem using recursion but I been struggling with recursion as it is a concept I don't have a full grasp of. Can any one point me into the right direction? Any ideas or suggestions are welcomed. Thank you.
Here is what I thought of so far:EDIT: Updated code
public int max(int[] nums, int begin, int end) {
int maxVal = begin;
if (begin == end) return nums[0];
else if(begin < end){
maxVal = max(nums, begin+1, end);
if (maxVal > nums[end-begin]) return maxVal;
else return nums[end-begin];
}
return maxVal;
}
This would be the outputs:
max([2, 1, -2, 3, 8], 0, 4) → 8
max([6, 2, -4], 0, 2) → 6
max([3], 0, 0) → 3
Do it as follows:
public class Main {
public static void main(String[] args) {
// Tests
System.out.println(max(new int[] { 2, 1, -2, 3, 8 }, 0, 4));
System.out.println(max(new int[] { 2, 1, -2, 8, 3 }, 0, 4));
System.out.println(max(new int[] { 2, 1, 8, -2, 3 }, 0, 4));
System.out.println(max(new int[] { 2, 8, 1, -2, 3 }, 0, 4));
System.out.println(max(new int[] { 8, 2, 1, -2, 3 }, 0, 4));
}
static int max(int[] nums, int begin, int end) {
if (begin >= end) {
return nums[end];
}
if (nums[begin] > nums[end]) {
return max(nums, begin, end - 1);
} else {
return max(nums, begin + 1, end);
}
}
}
Output:
8
8
8
8
8

Making a copy of the second half of an array

I want to make a function that takes as parameters an array and a boolean. The boolean tells the function if the rest of the division of the array is to be included. It then returns a new array which is the copy of the second half of the first:
secondHalf({1, 2, 3, 4, 5}, true) → {3, 4, 5}
secondHalf({1, 2, 3, 4, 5}, false) → {4, 5}
For this assignment, I'm not supposed to use any other classes.
Here's what I've attempted:
static int[] secondHalf(int[] vector, boolean include) {
int size = vector.length/2;
if(vector.length%2 == 0)
include = false;
if(include)
size ++;
int[] vector_2 = new int[size];
int i = 0;
while(i < size){
if(include)
vector_2[i] = vector[i+size-1];
vector_2[i] = vector[i+size+1];
i++;
}
return vector_2;
To find the size of vector_2, I've decided to use compound assignment operators. So the first part of this solution checks for the required condition and assigns a value to size in a single statement.
Since we know how many times to iterate over the loop, I think a for loop would be more appropriate than a while loop.
The loop retrieves all the values in vector from the middle of the array to the end of the array and places each value into vector_2.
static int[] secondHalf(int[] vector, boolean include) {
int size = vector.length/2 + (include && vector.length%2 != 0 ? 1 : 0);
int[] vector_2 = new int[size];
for(int i = 0; i < size; i++)
vector_2[i] = vector[vector.length - size + i];
return vector_2;
}
People have hinted at System#arraycopy, but with Arrays.copyOfRange there is an even simpler method, where you only have to define the proper start index and directly receive the copy.
The start index is array.length / 2 by default. Iff the include flag is true, then you have to add the remainder of dividing the array length by 2 to that.
An MCVE:
import java.util.Arrays;
public class ArrayPartCopy
{
public static void main(String[] args)
{
int array0[] = { 1, 2, 3, 4, 5 };
System.out.println("For " + Arrays.toString(array0));
System.out.println(Arrays.toString(secondHalf(array0, true)));
System.out.println(Arrays.toString(secondHalf(array0, false)));
int array1[] = { 1, 2, 3, 4 };
System.out.println("For " + Arrays.toString(array1));
System.out.println(Arrays.toString(secondHalf(array1, true)));
System.out.println(Arrays.toString(secondHalf(array1, false)));
}
static int[] secondHalf(int[] array, boolean include)
{
int start = array.length / 2;
if (include)
{
start += array.length % 2;
}
return Arrays.copyOfRange(array, start, array.length);
}
}
The output is
For [1, 2, 3, 4, 5]
[4, 5]
[3, 4, 5]
For [1, 2, 3, 4]
[3, 4]
[3, 4]

Categories