finding sums in 2 dimentional arrays java - java

A project I am doing requires me to find horizontal and vertical sums in 2 dimensional arrays. So pretty much its a word search (not using diagonals) but instead of finding words, the program looks for adjacent numbers that add up to int sumToFind. The code below is what I have come up with so far to find horizontal sums, and we are supposed to implement a public static int[][] verticalSums as well. Since I have not yet completed the program I was wondering, first of all, if what I have will work and, secondly, how the array verticalSums will differ from the code below. Thank you
public static int[][] horizontalSums(int[][] a, int sumToFind) {
int i;
int start;
int sum = 0;
int copy;
int [][] b = new int [a[0].length] [a.length];
for (int row = 0; row < a.length; row++) {
for ( start = 0; start < a.length; start++) {
i = start;
sum = i;
do {
i++;
sum = sum + a[row][start];
}
while (sum < sumToFind);
if(sum == sumToFind) {
for (copy = start; copy <= i; copy++) {
b[copy] = a[copy];
}
}
for (i = 0; i < a[0].length; i++) {
if (b[row][i] != a[row][i])
b[row][i] = 0;
}
}
}
return b;
}

Your code won't work.... (and your question is "if what I have will work?" so this is your answer).
You declare the int[][] b array as new int [a[0].length] [a.length] but I think you mean: new int [a.length] [a[0].length] because you base the row variable off a.length, and later use a[row][i].
So, if your array is 'rectangular' rather than square, you will have index-out-of-bounds problems on your b array.
Your comments are non-existent, and that makes your question/code hard to read.
Also, you have the following problems:
you set sum = i where i = start and start is the index in the array, not the array value. So, your sum will never be right because you are summing the index, not the array value.
in the do..while loop you increment i++ but you keep using sum = sum + a[row][start] so you just keep adding the value to itself, not the 'next' value.
At this point it is obvious that your code is horribly broken.
You need to get friendly with someone who can show you how the debugger works, and you can step through your problems in a more contained way.

Test is very simple
public static void main(String[] args) {
int[][] a = {{1, 2}, {1, 0}};
int[][] result = Stos.horizontalSums(a, 1);
System.out.println(Arrays.deepToString(result));
}
Result
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
When you fix this problem, then this should print something like this
[[1, 2], [1, 0]]

Related

How do 2D arrays and deepToString work?

import java.util.Arrays;
public class main {
public static void main (String[] args ) {
int rand = (int)Math.random()*17;
int[][] output = array(rand);
//System.out.println(Arrays.deepToString(output));
}
public static int[][] array(int n) { //btw n is y/height
int x = (int)Math.pow(2, n-1); //# of col
int max = (int)Math.pow(2, n) - 1;
int [][] out = new int[n][x];
for (int i = 0; i < n; i++) {
for (int j = 0; j < x; j++) {
out[i][j] = (int) (Math.random() * (max + 1));
}
}
return out;
}
}
I'm learning how to code and a cousin gave me their old laptop and I found some small java files here and there. This one is called "itsmagic.java" but I don't really understand what the purpose is?
From what I understand it seems that we are creating a 2D array of some sort and then what? I understand that deepToString is supposed to be used to convert multidimensional arrays to strings, but how does that work? Why is it commented out?
What I understood from your code is:
-Pick a random int n from 0 to 17.
-setting a x = 2^(n-1)
-setting a max= 2^n
-Creating a double entry tab dimensions n*x
-Filling each case with a random number between 0 and max
So the result is a double entry tab of dimensions [0 to 17][2^(0 to 16)] filled with numbers between 0 and 2^(0 to 17)
Arrays.deepToString() is used for either single or multidimensional arrays, it's usually used for multidimensional arrays as it can clearly output each array.
You will be able to output both the first and second array of "output" in your example.
If you run a test and add in the array manually, you will see it prints both the arrays together instead of showing just the first dimension.

Two sum - Doesn't work

Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Consider input [3,2,4] and target is 6. I added (3,0) and (2,1) to the map and when I come to 4 and calculate value as 6 - 4 as 2 and when I check if 2 is a key present in map or not, it does not go in if loop.
I should get output as [1,2] which are the indices for 2 and 4 respectively
public int[] twoSum(int[] nums, int target) {
int len = nums.length;
int[] arr = new int[2];
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i = 0;i < len; i++)
{
int value = nums[i] - target;
if(map.containsKey(value))
{
System.out.println("Hello");
arr[0] = value;
arr[1] = map.get(value);
return arr;
}
else
{
map.put(nums[i],i);
}
}
return null;
}
I don't get where the problem is, please help me out
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice. Consider input [3,2,4] and target is 6. I added (3,0) and (2,1) to the map and when I come to 4 and calculate value as 6 - 4 as 2 and when I check if 2 is a key present in map or not, it does not go in if loop.
Okay, let's take a step back for a second.
You have a list of values, [3,2,4]. You need to know which two will add up 6, well, by looking at it we know that the answer should be [1,2] (values 2 and 4)
The question now is, how do you do that programmatically
The solution is (to be honest), very simple, you need two loops, this allows you to compare each element in the list with every other element in the list
for (int outter = 0; outter < values.length; outter++) {
int outterValue = values[outter];
for (int inner = 0; inner < values.length; inner++) {
if (inner != outter) { // Don't want to compare the same index
int innerValue = values[inner];
if (innerValue + outterValue == targetValue) {
// The outter and inner indices now form the answer
}
}
}
}
While not highly efficient (yes, it would be easy to optimise the inner loop, but given the OP's current attempt, I forewent it), this is VERY simple example of how you might achieve what is actually a very common problem
int value = nums[i] - target;
Your subtraction is backwards, as nums[i] is probably smaller than target. So value is getting set to a negative number. The following would be better:
int value = target - nums[i];
(Fixing this won't fix your whole program, but it explains why you're getting the behavior that you are.)
This code for twoSum might help you. For the inputs of integer array, it will return the indices of the array if the sum of the values = target.
public static int[] twoSum(int[] nums, int target) {
int[] indices = new int[2];
outerloop:
for(int i = 0; i < nums.length; i++){
for(int j = 0; j < nums.length; j++){
if((nums[i]+nums[j]) == target){
indices[0] = i;
indices[1] = j;
break outerloop;
}
}
}
return indices;
}
You can call the function using
int[] num = {1,2,3};
int[] out = twoSum(num,4);
System.out.println(out[0]);
System.out.println(out[1]);
Output:
0
2
You should update the way you compute for the value as follows:
int value = target - nums[i];
You can also check this video if you want to better visualize it. It includes Brute force and Linear approach:

Java how to find the middle of a 2d array

I'm writing a function that tries to find the middle of a 2d array, and here's what I have so far:
int findMiddle(int[][] grid,int [] m) {
int[] list = new int[grid.length*grid[0].length];
int listPos = 0;
for(int i = 0 ; i < grid.length; i++) {
for(int j = 0; j < grid.length; j++) {
list[listPos++] = grid[i][j];
}
}
int middle = m.length/2;
if (m.length%2 == 1) {
return m[middle];
} else {
return (m[middle-1] + m[middle]) / 2.0;
}
}
Suppose I have an array of
{{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 0, 1}}
It should return 6, as it is integer division.
Also, the definition of middle in this code is the middle integer of the whole original array (needless to say if it is sorted or not).
How would I do this? ( my code also doesn't compile)
This compiles, and will give you the middle number in your sequence, or the average of the middle two if it splits the middle:
static double findMiddle(int[][] grid) {
int[] list = new int[grid.length*grid[0].length];
int listPos = 0;
for(int i = 0 ; i < grid.length; i++) {
for(int j = 0; j < grid[i].length; j++) {
list[listPos++] = grid[i][j];
}
}
int middle = list.length/2;
if ((list.length%2) == 1) {
return list[middle];
}
return (list[middle-1] + list[middle]) / 2.0;
}
However, I suspect you'll want to sort you numbers after you combine them into a single array, before you find the middle numbers. (as piyush121 commented)
Assuming your definition of 'median' is correct (the middle number of an odd length set or the average of the two middle numbers of an even length set), and if grid[][] is sorted, and if grid[][] is a square array (i.e. grid.length = grid[i].length for all i in 0..length-1, then you don't need to copy data to another array. The following should suffice:
static int findMiddle(int[][] grid) {
int l = grid.length;
if (l%2 == 1) {
return grid[l/2][l/2];
} else {
return (grid[l/2-1][l-1]+grid[l/2][0])/2;
};
Looking at your existing code it seems you are defining 'median' as the middle value in the matrix if all values were put into a single row-wise list. In other words you don't need to cope with odd numbers of rows (when two numbers from the same column are in the middle) or odd numbers of rows and columns (when there are four numbers in the middle).
If that definition is correct then you can cope with all the complexity of uneven rows by streaming all values and then selecting the middle ones.
For your interest, here's a Java 8 solution that does that:
int[] flat = Arrays.stream(grid).flatMapToInt(Arrays::stream).toArray();
double middle = Arrays.stream(flat).skip(flat.length / 2).limit(1 + flat.length % 2)
.average().getAsDouble();

JAVA: Method that takes an int "n" as input, and returns an array that contains the first n prime numbers

Here is what I got so far
public static int[] firstPrimeNumbers(int n) {
int[] k = new int[n];
int m = 0;
for (int i = 0; i < n; i++) {
if (isPrime(i)) {
k[m] = i;
m++;
}
}
return k;
}
Problem is, when I try to print the resulting array, I get a bunch of 0's at the end. For example when I took n = 10, the program printed
2, 3, 5, 7, 0, 0, 0, 0, 0, 0
Hows that even possible? What am I doing wrong?
What happens here is fairly easy.
k has size 10 and initially filled with zeros.
Then you check the first 10 natural numbers and check whether they are prime.
So for each non-prime number you should get a 0
Maybe replace i<n by m<n but that depends a bit on what you want to achieve.
You should modify your for loop. What you are doing is actually returning in an array of n elements the primitive numbers less than n
public static int[] firstPrimeNumbers(int n) {
int[] k = new int[n];
int nr = 2;
int m = 0;
while(m<n){
if(isPrime(nr)){
k[m] = nr;
m++;
}
nr++;
}
return k;
}
You are just counting until i == n (so only looking at number up to n) - you need to keep incrementing i until m == n so you are considering whether numbers > n are prime.
If you used better variable names like nextPrimeIndex or primesFound instead of m this would probably be easier to spot.

Transferring the contents of a one-dimensional array to a two-dimensional array

I'm trying to make an encryption program where the user enters a message and then converts the "letters into numbers".
For example the user enters a ABCD as his message. The converted number would be 1 2 3 4 and the numbers are stored into a one dimensional integer array. What I want to do is be able to put it into a 2x2 matrix with the use of two dimensional arrays.
Here's a snippet of my code:
int data[] = new int[] {10,20,30,40};
*for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
for (int ctr=0; ictr<data.length(); ictr++){
a[i][j] = data[ctr];}
}
}
I know there's something wrong with the code but I am really lost.
How do I output it as the following?
10 20
30 40
(instead of just 10,20,30,40)
Here's one way of doing it. It's not the only way. Basically, for each cell in the output, you calculate the corresponding index of the initial array, then do the assignment.
int data[] = new int[] {10, 20, 30, 40, 50, 60};
int width = 3;
int height = 2;
int[][] result = new int[height][width];
for(int i = 0; i < height; i++) {
for(int j = 0; j < width; j++) {
result[i][j] = data[i * width + j];
}
}
Seems like you want to output a 2xn matrix while still having the values stored in a one-dimensional array. If that's the case then you can to this:
Assume the cardinality m of your set of values is known. Then, since you want it to be 2 rows, you calculate n=ceil(m/2), which will be the column count for your 2xn matrix. Note that if m is odd then you will only have n-1 values in your second row.
Then, for your array data (one-dimension array) which stores the values, just do
for(i=0;i<2;i++) // For each row
{
for(j=0;j<n;j++) // For each column,
// where index is baseline+j in the original one-dim array
{
System.out.print(data[i*n+j]);
}
}
But make sure you check the very last value for an odd cardinality set. Also you may want to do Integer.toString() to print the values.
Your code is close but not quite right. Specifically, your innermost loop (the one with ctr) doesn't accomplish much: it really just repeatedly sets the current a[i][j] to every value in the 1-D array, ultimately ending up with the last value in the array in every cell. Your main problem is confusion around how to work ctr into those loops.
There are two general approaches for what you are trying to do here. The general assumption I am making is that you want to pack an array of length L into an M x N 2-D array, where M x N = L exactly.
The first approach is to iterate through the 2D array, pulling the appropriate value from the 1-D array. For example (I'm using M and N for sizes below):
for (int i = 0, ctr = 0; i < M; ++ i) {
for (int j = 0; j < N; ++ j, ++ ctr) {
a[i][j] = data[ctr];
}
} // The final value of ctr would be L, since L = M * N.
Here, we use i and j as the 2-D indices, and start ctr at 0 and just increment it as we go to step through the 1-D array. This approach has another variation, which is to calculate the source index explicitly rather than using an increment, for example:
for (int i = 0; i < M; ++ i) {
for (int j = 0; j < N; ++ j) {
int ctr = i * N + j;
a[i][j] = data[ctr];
}
}
The second approach is to instead iterate through the 1-D array, and calculate the destination position in the 2-D array. Modulo and integer division can help with that:
for (int ctr = 0; ctr < L; ++ ctr) {
int i = ctr / N;
int j = ctr % N;
a[i][j] = data[ctr];
}
All of these approaches work. Some may be more convenient than others depending on your situation. Note that the two explicitly calculated approaches can be more convenient if you have to do other transformations at the same time, e.g. the last approach above would make it very easy to, say, flip your 2-D matrix horizontally.
check this solution, it works for any length of data
public class ArrayTest
{
public static void main(String[] args)
{
int data[] = new int[] {10,20,30,40,50};
int length,limit1,limit2;
length=data.length;
if(length%2==0)
{
limit1=data.length/2;
limit2=2;
}
else
{
limit1=data.length/2+1;
limit2=2;
}
int data2[][] = new int[limit1][limit2];
int ctr=0;
//stores data in 2d array
for(int i=0;i<limit1;i++)
{
for(int j=0;j<limit2;j++)
{
if(ctr<length)
{
data2[i][j] = data[ctr];
ctr++;
}
else
{
break;
}
}
}
ctr=0;
//prints data from 2d array
for(int i=0;i<limit1;i++)
{
for(int j=0;j<limit2;j++)
{
if(ctr<length)
{
System.out.println(data2[i][j]);
ctr++;
}
else
{
break;
}
}
}
}
}

Categories

Resources