Merging two 2D arrays (M + N) - java

I am a first year programming trying to solve this challenge that was given to us students at uni.
Question image
There's a typo at where it says (N + K) whereas in fact it's actually (M+K) columns.
My attempt for this question goes as follows
public static int[][] mergeArrays(int[][] arrayA, int[][] arrayB){
int rows = 3;
int columns = arrayA[0].length + arrayB[0].length;
int[][] mergedArray = new int[rows][columns];
int k = 0;
for (int i = 0; i < rows; i++)
{
for ( int j = 0 ; j < columns; j++)
{
try
{
mergedArray[i][j] = arrayA[i][j];
}
catch (ArrayIndexOutOfBoundsException e)
{
mergedArray[i][j] = arrayB[i][k];
k += 1;
}
}
}
return mergedArray;
}
public static void main(String [] args)
{
int [][] a1 = { {1,2,3,3,3} , {3,2,1,6,3} , {4,5,6,1,3} };
int [][] a2 = { {1,9,7,2,3} , {0,7,8,3,2} , {3,8,9,7,2} };
int[][] m = mergeArrays(a1,a2);
for (int[] x : m)
{
for (int y : x)
{
System.out.print(y + " ");
}
System.out.println();
}
}
The program doesn't work for some reason. I don't know what's wrong with my approach here. Would really appreciate if someone helps me out.

Without using any libraries, in a manual way, here is my working answer.
I didn't use any of them, since we were not allowed, when I was a student.
public class Main {
private static int[][] mergeArrays(int[][] a1, int[][] a2) {
// Count rows and cols length.
int rows = a1.length;
int cols_a1 = a1[0].length;
int cols_a2 = a2[0].length;
// Total number of cols
int cols = cols_a2 + cols_a1;
int [][] merged = new int[rows][cols];
for (int i = 0; i < rows ; ++i) {
for (int j = 0; j < cols_a1; ++j) {
merged[i][j] = a1[i][j];
}
// To not overwrite values,
// the trick is to add an offset, while assigning,
// which is the amount of elements (cols_a1) used by the previous loop.
// Basically, we are shifting the k-index by this constant,
// as to not overwrite the values assigned from the previous
// inner loop.
for (int k = 0; k < cols_a2; ++k) {
merged[i][cols_a1 + k] = a2[i][k];
}
}
// Return the merged array
return merged;
}
// I refactored your good printing code into a method, for readability.
private static void print2darray(int[][] array2d) {
for (int[] x : array2d) {
for (int y : x) {
System.out.print(y + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
int [][] a1 = {{1,2,3,3,3} , {3,2,1,6,3} , {4,5,6,1,3}};
int [][] a2 = {{1,9,7,2,3} , {0,7,8,3,2} , {3,8,9,7,2}};
int [][] merged = mergeArrays(a1, a2);
print2darray(merged);
}
}
The result is the same, as expected, from your question image:
1 2 3 3 3 1 9 7 2 3
3 2 1 6 3 0 7 8 3 2
4 5 6 1 3 3 8 9 7 2

Since you're a student I think to better if we give a hint, but since the solution is already there you can check this one as well:
public static int[] merge(int[] first,int[] second) {
return ArrayUtils.addAll(first, second);
}
public static void main(String[] args) {
int [][] a1 = { {1,2,3,3,3} , {3,2,1,6,3} , {4,5,6,1,3}};
int [][] a2 = { {1,9,7,2,3} , {0,7,8,3,2} , {3,8,9,7,2}};
int [][] a3 = new int[a1.length][];
for (int i = 0; i < a1.length; i++) {
a3[i] = merge(a1[i],a2[i]);
}
for (int[] ints : a3) {
StringJoiner joiner = new StringJoiner(",","[","]");
for (int i1 : ints) {
joiner.add(i1+"");
}
System.out.println(joiner.toString());
}
}

You are not merging it properly. Your logic is that if arrayA column index is out of bounds, you are adding from arrayB's columns. But what if that is also out of bounds, as in your case. Since you are always incrementing its index k. You could simply iterate over 2 arrays separately and merge into resulting array.
public static int[][] mergeArrays(int[][] arrayA, int[][] arrayB) {
int rows = 3;
int columns = arrayA[0].length + arrayB[0].length;
int[][] mergedArray = new int[rows][columns];
int k = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < arrayA[0].length; j++) {
mergedArray[i][k++] = arrayA[i][j];
}
for (int j = 0; j < arrayB[0].length; j++) {
mergedArray[i][k++] = arrayB[i][j];
}
k=0;
}
return mergedArray;
}

Related

java array for zigzag works, but tester keeps telling me there's an error?

I have this line of code to create a zigzag array, its fairly simple and I already have the code for it. here's the summary of the question:
This method creates and returns a new two-dimensional integer array, which in Java is really just a one-dimensional array whose elements are one-dimensional arrays of type int[]. The returned array must have the correct number of rows that each have exactly cols columns. This array must contain the numbers start, start + 1, ..., start + (rows * cols - 1) in its rows in order, except that the elements in each odd-numbered row must be listed in descending order.
For example, when called with rows = 4, cols = 5 and start = 4, this method should create and return the two-dimensional array whose contents are
4 5 6 7 8
13 12 11 10 9
14 15 16 17 18
23 22 21 20 19
I've tried talking with my colleagues but they can't spot the problem too
public class P2J1
{
public static int[][] createZigZag(final int rows, final int cols, int start)
{
final int[][] array = new int[rows][cols];
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
array[i][j] = start;
start++;
}
}
return array;
}
}
/// heres the tester program
#Test public void testCreateZigZag() {
Random rng = new Random(SEED);
CRC32 check = new CRC32();
for(int i = 0; i < TRIALS; i++) {
int rows = rng.nextInt(20) + 1;
int cols = rng.nextInt(20) + 1;
int start = rng.nextInt(100);
int[][] zig = P2J1.createZigZag(rows, cols, start);
assertEquals(rows, zig.length);
for(int j = 0; j < rows; j++) {
assertEquals(cols, zig[j].length);
for(int e: zig[j]) { check.update(e); }
}
}
assertEquals(3465650385L, check.getValue());
}
Your column index always goes from 0 to cols-1, in that order. You need to alternate the order every other row.
You can do this by using variables for the start, end, and increment of the inner loop and assign those variables based on the row index being odd or even.
Something like this (untested):
public static int[][] createZigZag(final int rows, final int cols, int start) {
final int[][] array = new int[rows][cols];
for (int i = 0; i < rows; i++) {
boolean backwards = ((i & 1) == 1);
final int jStart = backwards ? cols-1 : -1;
final int jEnd = backwards ? 0 : cols;
final int jStep = backwards ? -1 : 1;
for (int j = jStart; j != jEnd; j += jStep) {
array[i][j] = start;
start++;
}
}
return array;
}
You could also just write two different inner loops, selected on the same condition. One would fill starting from 0, the other would fill starting from cols-1 and going backwards.
public static int[][] createZigZag(final int rows, final int cols, int start) {
final int[][] array = new int[rows][cols];
for (int i = 0; i < rows; i++) {
if ((i & 1) == 1) {
for (int j = cols-1; j >= 0; j--) {
array[i][j] = start;
start++;
}
} else {
for (int j = 0; j < cols; j++) {
array[i][j] = start;
start++;
}
}
}
return array;
}

Random Number Sort Arrays

For my java class, I have this problem:
Write a program that generates 100 random integers in the range 0 to 25, and stores them in an array. Then, the program should call a class method that sorts the odd numbers into an array and returns the array. The program should then call another method that sorts the even numbers into a separate array and returns the array. Both arrays should then be displayed.
This is my code:
public class Assignment8
{
public static void main(String [] args)
{
int [] randomNums = new int [100];
for (int i = 0; i < randomNums.length; i++) {
randomNums[i] = (int) (Math.random() * 26);
int[] oddNums = sortOdd(randomNums);
System.out.println("The odd numbers are ");
for (int n = 0; n<=oddNums.length; n++) {
System.out.print(n);
}
int[] evenNums = sortEven(randomNums);
System.out.println("The even numbers are ");
for (int o = 0; o<=evenNums.length; o++) {
System.out.print(o);
}
}
}
public static int[] sortOdd(int[] randomNums)
{
int numOdds = 0;
for (int x : randomNums){
if(x % 2 == 1){
++numOdds;
}
}
int[] oddNums = new int[numOdds];
int z = 0;
for (int n : randomNums){
if(n % 2 == 1){
oddNums[z] = n;
z++;
}
}
return oddNums;
}
public static int[] sortEven(int[] randomNums)
{
int numEvens = 0;
for (int x : randomNums){
if(x % 2 == 0){
++numEvens;
}
}
int[] evenNums = new int[numEvens];
int z = 0;
for (int n : randomNums){
if(n % 2 == 0){
evenNums[z] = n;
z++;
}
}
return evenNums;
}
}
It is just printing out a bunch of numbers and the words "The even numbers are" and "The odd numbers are". What should I fix in my code to make it fulfill my assignment?
Your code seems fine, but you are missing a proper sort methodology, ascending or descending won't matter much, but the algorithm you choose to sort the array is unknown in this case. Let me introduce you to the worst method to sort an array, bubble-sort and there are many others like Insertion Sort, Merge Sort, QuickSort, BucketSort etc etc, built-in java methods can handle sorts at super fast speeds, but for the sake of simplicity, take bubble sort as the sorting method, this is how it looks in code
public static void sortArray( int[] data )
{
for( int x = 0; x < data.length; x++ )
{
for( int y = 0; y < data.length - 1; y++ )
{
if( data[y] < data[y + 1] )
{
int hold = data[y];
data[y] = data[y + 1];
data[y + 1] = hold;
}
}
}
}
Simply arranges the array in descending order. Now you would also like to generate a random array of fixed size, with elements no greater than 25. You should avoid your approach of generating such an array, because you are going to get simply 0's out of it, Math.random() is generating floating points, try this method to generate random array
public static int[] generateRandomArrayWithLimitAndSize( int limit , int size )
{
final java.util.Random rand = new java.util.Random();
final int[] data = new int[size];
for( int x = 0; x < data.length; x++ )
{
data[x] = rand.nextInt(limit);
}
return data;
}
Here is how you would have gone to sort even's
public static int[] sortEven( int[] data )
{
int len = 0;
int[] copyData;
for( int x = 0; x < data.length; x++ )
{
if( data[x] % 2 == 0 )
{
len++;
}
}
copyData = new int[len];
for( int x = 0 , y = 0; x < data.length; x++ )
{
if( data[x] % 2 == 0 )
{
copyData[y++] = data[x];
}
}
sortArray( copyData );
return copyData;
}
You can well imagine what the code for sortOdd should have looked like. Now you can try to visualize the result by trying this
public static void main(String[] args)
{
int[] myArray = generateRandomArrayWithLimitAndSize( 25 , 100 ); // limit,size
System.out.println( "Actual Array: " + java.util.Arrays.toString( myArray ) );
System.out.println( "\r\nSorting Evens: \r\n" + java.util.Arrays.toString( sortEven( myArray ) ) );
System.out.println( "\r\nSorting Odds: \r\n" + java.util.Arrays.toString( sortOdd( myArray ) ) );
}
And if you are still facing troubles in You can well imagine what the code for sortOdd should have looked like , then this is sortOdd(int[]) definition
public static int[] sortOdd( int[] data )
{
int len = 0;
int[] copyData;
for( int x = 0; x < data.length; x++ )
{
if( data[x] % 2 != 0 )
{
len++;
}
}
copyData = new int[len];
for( int x = 0 , y = 0; x < data.length; x++ )
{
if( data[x] % 2 != 0 )
{
copyData[y++] = data[x];
}
}
sortArray( copyData );
return copyData;
}
Open to further questions if any, but all this should work fine for you
import java.util.ArrayList;
import java.util.List;
public class Assignment8
{
public static void main(String [] args)
{
int [] randomNums = new int [100];
for (int i = 0; i < randomNums.length; i++)
{
randomNums[i] = (int) (Math.random() * 26);
System.out.println(randomNums[i] +"\n");
}
Integer[] oddNums = sortOdd(randomNums);
System.out.println("The odd numbers are ");
for (int n = 0; n< oddNums.length; n++)
{
System.out.print(oddNums[n] +"\n");
}
Integer[] evenNums = sortEven(randomNums);
System.out.println("The even numbers are ");
for (int o = 0; o< evenNums.length; o++)
{
System.out.print(evenNums[o] + "\n");
}
}
public static Integer[] sortOdd(int[] randomNums)
{
List<Integer> oddNums = new ArrayList<>();
for (int x : randomNums){
if(x % 2 == 1){
oddNums.add(x);
}
}
return oddNums.toArray(new Integer[oddNums.size()]);
}
public static Integer[] sortEven(int[] randomNums)
{
List<Integer> evenNums = new ArrayList<>();
for (int x : randomNums){
if(x % 2 == 0){
evenNums.add(x);
}
}
return evenNums.toArray(new Integer[evenNums.size()]);
}
}

2D Array Methods & Demo

I have an assignment to design and implement methods to process 2D Arrays.
It needs to have an implementation class (Array2DMethods) that has the following static methods:
readInputs() to read the number of rows and columns fro the user then reads a corresponding entry to that size. Ex: if a user enters 3 for # of rows and 3 for # of columns it'll declare an array of 10 and reads 9 entries.
max(int [][] anArray) it returns the max value in the 2D parameter array anArray
rowSum(int[][] anArray) it returns the sum of the elements in row x of anArray
columnSum(int[][] anArray) it returns the sum of the elements in column x of anArray **careful w/ rows of different lengths
isSquare(int[][] anArray) checks if the array is square (meaning every row has the same length as anArray itself)
displayOutputs(int[][] anArray) displays the 2 Dim Array elements
It also needs a testing class (Arrays2DDemo) that tests the methods.
I've commented the parts I'm having problems with. I'm not sure how to test the methods besides the readInputs method and also not sure how to format the part where you ask the user to enter a number for each row.
Here's my code so far:
import java.util.Scanner;
class Array2DMethods {
public static int [][] readInputs(){
Scanner keyboard = new Scanner(System.in);
System.out.print(" How many rows? ");
int rows = keyboard.nextInt();
System.out.print(" How many columns? ");
int columns = keyboard.nextInt();
int [][] ret = new int[rows][columns];
for (int i = 0; i<ret.length; i++) {
for (int j = 0; j < ret[i].length; j++) {
System.out.print("please enter an integer: "); //Need to format like Enter [0][0]: ... Enter [0][1]: ...etc.
ret[i][j] = keyboard.nextInt();
}
}
return ret;
}
public static int max(int [][] anArray) {
int ret = Integer.MIN_VALUE;
for (int i = 0; i < anArray.length; i++) {
for (int j = 0; j < anArray[i].length; j++) {
if (anArray[i][j] > ret) {
ret = anArray[i][j];
}
}
}
return ret;
}
public static void rowSum(int[][]anArray) {
int ret = 0;
for (int i = 0; i<anArray.length; i++) {
for (int j = 0; j < anArray[i].length; j++) {
ret = ret + anArray[i][j];
}
}
}
public static void columnSum(int[][]anArray) {
int ret = 0;
for (int i = 0; i < anArray.length; i++) {
for (int j = 0; j < anArray[i].length; j++) {
ret = ret + anArray[i][j];
}
}
}
public static boolean isSquare(int[][]anArray) {
for (int i = 0, l = anArray.length; i < l; i++) {
if (anArray[i].length != l) {
return false;
}
}
return true;
}
public static void displayOutputs(int[][]anArray) {
System.out.println("Here is your 2Dim Array:");
for(int i=0; i<anArray.length; i++) {
for(int j=0; j<anArray[i].length; j++) {
System.out.print(anArray[i][j]);
System.out.print(", ");
}
System.out.println();
}
}
}
Class Arrays2DDemo:
public class Arrays2DDemo {
public static void main(String[] args){
System.out.println("Let's create a 2Dim Array!");
int [][] anArray = Array2DMethods.readInputs();
Array2DMethods.max(anArray);
Array2DMethods.rowSum(anArray);
//need to print out and format like this: Ex Sum of row 1 = 60 ...etc
Array2DMethods.columnSum(anArray);
//need to print out and format like this: Ex Sum of column 1 = 60 ...etc.
Array2DMethods.isSquare(anArray);
//need to print out is this a square array? true
Array2DMethods.displayOutputs(anArray);
//need it to be formatted like [10, 20, 30] etc
}
}
Assuming you want anArray to be the array you read in during your inputting, you should name that variable, as such...
public static void main(String[] args){
System.out.println("Let's create a 2Dim Array!");
int[][] anArray = Array2DMethods.readInputs();
System.out.println("max " + Array2DMethods.max(anArray));
Array2DMethods.rowSum(anArray);
Array2DMethods.columnSum(anArray);
System.out.println("Square " + Array2DMethods.isSquare(anArray));
Array2DMethods.displayOutputs(anArray);
}
Say you have a function f which takes a single input x. The problem is you're asking the computer to evaluate f(x) without ever telling it what x is. If you give x a value, however, such as x = 3, then asking f(x) becomes legal, because it becomes f(3), which can be evaluated.

Array method that returns a new array where every number is replicated by “itself” # of times

I am trying to write a method in Java that receives an array and returns a new array where each number is printed that number of times. Here is an example input and output: "1 2 3 0 4 3" ---> "1 2 2 3 3 3 4 4 4 4 3 3 3". I am stuck and my program will not compile. Does anyone see where I am going wrong?
public static int [] multiplicity(int [] nums) {
for (int i = 0 ; i < nums.length ; i++) {
int size = nums.length + 1;
int newNums[] = new int [size];
for (int j = 0 ; j < nums.length ; j++) {
int value = nums[j];
for (int v = 0 ; v < value ; v++) {
newNums[j + v] = value;
}
}
}
return newNums;
}
Your current code does not size your new array correctly, you could fix your compiler errors easily enough like
int size=nums.length+1;
int newNums [] = new int [size];
for (int i=0; i<nums.length; i++)
{
// int size=nums.length+1;
// int newNums [] = new int [size];
But that clearly won't allow you to populate all of your values. Instead (assuming you can't use a dynamic data-type like a Collection), you'll need to iterate the array once to get the final count of elements and then populate your array. Something like,
public static int[] multiplicity(int[] nums) {
// first pass
int count = 0;
for (int num : nums) {
for (int i = 0; i < num; i++) {
count++;
}
}
int[] ret = new int[count];
count = 0;
// second pass
for (int num : nums) {
for (int i = 0; i < num; i++) {
ret[count++] = num;
}
}
return ret;
}
Then you could test it like,
public static void main(String arg[]) {
int[] in = { 1, 2, 3, 0, 4, 3 };
int[] out = multiplicity(in);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < out.length; i++) {
if (i != 0) {
sb.append(' ');
}
sb.append(out[i]);
}
String expected = "1 2 2 3 3 3 4 4 4 4 3 3 3";
System.out.println(expected.equals(sb.toString()));
}
Output is
true
Once you initialise your int[] newNums, you can't dynamically resize it. Initialising it again will discard the previous array.
Here's another way to solve the problem:
public static int [] multiplicity (int [ ] nums)
{
// create a list to contain the output
List<Integer> newNums = new ArrayList<Integer>();
// for each incoming int
if(nums != null) {
for (final int i : nums)
{
// repeat adding the value
for(int j = 0; j < i; j++) {
newNums.add(i);
}
}
}
// now copy from the List<Integer> to the result int[]
int[] result = new int[newNums.size()];
for(int i=0; i < newNums.size(); i++) {
result[i] = newNums.get(i);
}
// return the result
return result;
}
You can't know the new array size until you explore the whole input array.
So you can
Explore the whole array and compute the lengh, then, re-explore the input array and fill the new. You need only 1 memory allocation (only 1 new int[])
Create a vector and fill it. Then use the .toarray method
Exemple to fill the array (check he had the right size)
int k = 0
for(int i: nums) {
for(int j = 0; j < i; j++) {
newArray[k] = i;
k++;
}
}

Write the integers of an array vertically

I know this is probably very simple but I really can't seem to understand how to write the integers vertically. For instance, there is an array that has 4 integers which are 9, 21, 63, and 501, the outcome would be the following
9 2 5 6
1 0 3
1
This is a small step of my program and probably the easiest but I can't understand how to do it :(
Can someone please help me or guide me so I can finish my program
Try this pseudo code
int[] list = new int[] {9,21,63,501};
bool finished = false;
if (list.Count > 0) {
for (var j=0;!finshed; j++) {
finished = true;
for (var i = 0; i<list.Count;i++) {
String val = list[i].ToString();
if (val.length>j) {
write(val.charAt(j));
finished = false;
}
}
}
}
I have created a very modular and easy to follow solution.
Edit: Converted digitAtIndex() to a purely numerical calculation.
Kept the original and called it digitAtStrIndex().
public class IntegerColumns {
public IntegerColumns() {
int[] arr = new int[] {9, 21, 501, 63};
printColumnMajorOrder(arr);
}
public static void main(String[] args) {
new IntegerColumns();
}
// --------------------- Primary Functions --------------------------
// Prints out an Array of Integers, each in a vertical column
public void printColumnMajorOrder(int[] arr) {
int cols = arr.length;
int rows = maxDigits(arr);
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
int d = digitAtIndex(arr[c], r);
System.out.printf("%s\t", d >= 0 ? Integer.toString(d) : " ");
}
System.out.println();
}
}
// Returns the length of an Integer
public int numDigits(int i) {
if (i <= 0) return 0;
return (int)Math.floor(Math.log10(i))+1;
}
// Numeric calculation to find a digit at a specified index
public int digitAtIndex(int num, int index) {
int digits = numDigits(num);
int deg = digits - index - 1;
int pow = (int)Math.pow(10, deg);
return pow > 0 ? (int)(num/pow)%10 : -1;
}
// Returns the number of digits for the longest Integer in an Array
public int maxDigits(int[] arr) {
int max = 0;
for (int i : arr) {
int size = numDigits(i);
if (size > max) max = size;
}
return max;
}
// ---------------------- Extra Functions ---------------------------
// Hybrid of Integer and Substrings - String manipulation = slow
public int digitAtStrIndex(int number, int i) {
String n = Integer.toString(number);
return n.length() > i ? Integer.parseInt(n.substring(i, i+1)) : -1;
}
// Prints the digits of a number vertically
public void printNumberVertical(int num) {
for (int i = 0; i < numDigits(num); i++)
System.out.println(digitAtIndex(num, i));
}
}
`public class VerticalPrintService {
private int[] data;
public VerticalPrintService( int[] intArray ) {
this.data = intArray;
}
public void printVertically(){
int cols = data.length; // # of columns
int rows = getRows(); // # of rows
System.out.println("cols: " + cols);
System.out.println("rows: " + rows);
String[][] matrix = new String[rows][cols];
int rowIndex = 0;
int colIndex = 0;
// populate 2d array
for ( int i : data ) {
String str = String.valueOf(i);
for ( int j = 0; j < str.length(); j++ ) {
matrix[rowIndex][colIndex] = String.valueOf(str.charAt(j));
rowIndex++;
}
colIndex++;
rowIndex = 0;
}
// print
for ( int i = 0; i < rows; i++ ) {
for ( int j = 0; j < cols; j++ ) {
if ( null == matrix[i][j] ) {
System.out.print("\t");
} else {
System.out.print( matrix[i][j] + "\t" );
}
}
System.out.println();
}
}
private int getRows(){
int max = 0;
for ( int i : data ) {
int len = String.valueOf(i).length();
if ( len > max ) {
max = len;
}
}
return max;
}
}`
and in your main method
`public static void main(String[] args) {
int[] array = { 9, 53, 501, 90 };
VerticalPrintService vps = new VerticalPrintService(array);
vps.printVertically();
}`

Categories