Java array removal gives unexpected results? - java

The following code is part of a program which takes the values of array ar except for variable z, and copies it onto a different array called ar2. The result should be all the numbers except negative two (19, 1, 17, 17), but currently the result is 19 1 17 17 -2 19 1 17 17 -2 19 1 17 17 -2 19 1 17 17 -2.
public class Second_tiny {
public static void main(String[] args) {
int[] ar = { 19, 1, 17, 17, -2 };
int z = ar[0];
for (int i = 0; i < (ar.length); i++) {
if (z > ar[i]) {
z = ar[i];
}
}
// second pass
int[] ar2 = new int[ar.length];
int zero = 0;
for (int x = 0; x < (ar.length); x++) {
if (ar[x] == z) {
continue; // If it is equal to z go back to the loop again
}
ar2[zero++] = ar[x];
for (int i = 0; i < ar.length; i++) {
System.out.println(ar[i]);
}
/*
* //2nd pass copy all items except smallest one to 2nd array int[] ar2= new int[ar.length-1]; int curIndex = 0; for (i=0; i<ar.length; i++) { if (ar[i]==z) continue; ar2[curIndex++] =
* ar[i]; }
*/
}
}
}

Java 8 way:
int[] ar = { 19, 1, 17, 17, -2 };
int min = Arrays.stream(ar).min().getAsInt();
int[] ar2 = Arrays.stream(ar).filter(s -> s!=min).toArray();
System.out.println(Arrays.toString(ar2));

You're printing out your original array 4 times in this block:
for (int i = 0; i < ar.length; i++) {
System.out.println(ar[i]);
}
That block should be outside of your loop, and should reference ar2 instead of ar.
for (int x = 0; x < (ar.length); x++) {
if (ar[x] == z) {
continue; // If it is equal to z go back to the loop again
}
ar2[zero++] = ar[x];
}
for (int i = 0; i < ar2.length; i++) {
System.out.println(ar2[i]);
}
This will give you the following result:
19
1
17
17
0
The last 0 appears because 0 is the default value for ints. Your ar2 array is 5 elements long, and for the last element the default value is never replaced.

You could use Math.min(int, int) to determine your lowest value. Your second array should be one element smaller. I suggest guarding against removing more than one value. And you could use Arrays.toString(int[]) to print the second array. Something like,
int[] ar = { 19, 1, 17, 17, -2 };
int z = ar[0];
for (int i = 1; i < ar.length; i++) {
z = Math.min(z, ar[i]);
}
// second pass
int[] ar2 = new int[ar.length - 1];
boolean first = true;
for (int x = 0; x < ar.length; x++) {
if (ar[x] == z && first) {
first = false;
continue; // If it is equal to z go back to the loop again
}
int y = x - (!first ? 1 : 0);
ar2[y] = ar[x];
}
System.out.println(Arrays.toString(ar2));
Output is
[19, 1, 17, 17]

you code is right mistakenly you have given one extra for loop.i have done comment on that for loop.use the following code u will get the desired output.
public class HelloWorld {
public static void main(String[] args) {
int[] ar = { 19, 1, 17, 17, -2 };
int z = ar[0];
for (int i = 0; i < (ar.length); i++) {
if (z > ar[i]) {
z = ar[i];
}
}
// second pass
int[] ar2 = new int[ar.length];
int zero = 0,i=0;
for (int x = 0; x < (ar.length); x++) {
if (ar[x] == z) {
continue; // If it is equal to z go back to the loop again
}
ar2[zero++] = ar[x];
// for (int i = 0; i < ar.length; i++) {
System.out.println(ar[i]);
i++;
// }
/*
* //2nd pass copy all items except smallest one to 2nd array int[] ar2= new int[ar.length-1]; int curIndex = 0; for (i=0; i<ar.length; i++) { if (ar[i]==z) continue; ar2[curIndex++] =
* ar[i]; }
*/
}
}
}
output is:
19
1
17
17

Related

How to find numbers that appear only once in a matrix?

I have a given matrix called m and its dimensions are n by n and it contains whole numbers. I need to copy the numbers that appear just once to a new array called a.
I think the logic would be to have a for loop for each number in the matrix and compare it to every other number, but I don't know how to actually do that with code.
I can only use loops (no maps or such) and this is what I've come up with:
public static void Page111Ex14(int[][] m) {
int previous = 0, h = 0;
int[] a = new int[m.length*m[0].length];
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[0].length; j++) {
previous = m[i][j];
if (m[i][j] != previous) {
a[h] = m[i][j];
h++;
}
}
}
It's probably not correct though.
Loop through it again to see if there's any repeated one. Assuming you can use labels, the answer might look a bit like that:
public static int[] getSingleInstanceArrayFromMatrix(int[][] m) {
int[] a = new int[m.length * m[0].length];
// Main loop.
for (int x = 0; x < m.length; x++) {
for (int y = 0; y < m[0].length; y++) {
// Gets the current number in the matrix.
int currentNumber = m[x][y];
// Boolean to check if the variable appears more than once.
boolean isSingle = true;
// Looping again through the array.
checkLoop:
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[0].length; j++) {
// Assuring we are not talking about the same number in the same matrix position.
if (i != x || j != y) {
// If it is equal to our current number, we can update the variable and break.
if (m[i][j] == currentNumber) {
isSingle = false;
break checkLoop;
}
}
}
}
if (isSingle) {
a[(x * m.length) + y] = currentNumber;
}
}
}
return a;
}
Not sure if it's the most efficient, but I think it will work. It's somewhat hard to form your final array without the help of Lists or such. Since the unassigned values will default to 0, any actual zero (i.e. it's "supposed" to be there based on the matrix) will be undetected if you look up the returned array. But if there's such limitations I imagine that it's not crucially important.
This is one of those problems you can just throw a HashMap at and it just does your job for you. You traverse the 2d array, use a HashMap to store each element with its occurence, then traverse the HashMap and add all elements with occurence 1 to a list. Then convert this list to an array, which is what you're required to return.
This has O(n*n) complexity, where n is one dimension of the square matrix m.
import java.util.*;
import java.io.*;
class GetSingleOccurence
{
static int[] singleOccurence(int[][] m)
{
// work with a list so that we can append to it
List<Integer> aList = new ArrayList<Integer>();
HashMap<Integer, Integer> hm = new HashMap<>();
for (int row = 0; row < m.length; row++) {
for (int col = 0; col < m[row].length; col++) {
if (hm.containsKey(m[row][col]))
hm.put(m[row][col], 1 + hm.get(m[row][col]));
else
hm.put(m[row][col], 1);
}
}
for (Map.Entry entry : hm.entrySet())
{
if (Integer.parseInt(String.valueOf(entry.getValue())) == 1)
a.add(Integer.parseInt(String.valueOf(entry.getKey())));
}
// return a as an array
return a.toArray(new int[a.size()]);
}
public static void main(String args[])
{
// A 2D may of integers with some duplicates
int[][] m = { { 1, 2, 3, 4, 5 },
{ 6, 7, 8, 9, 10 },
{ 11, 12, 12, 14, 15 },
{ 16, 17, 18, 18, 20 },
{ 21, 22, 23, 24, 25 } };
a = singleOccurence(m);
}
}
It may be better to use a boolean array boolean[] dups to track duplicated numbers, so during the first pass this intermediate array is populated and the number of singles is counted.
Then create the resulting array of appropriate size, and if this array is not empty, in the second iteration over the dups copy the values marked as singles to the resulting array.
public static int[] getSingles(int[][] arr) {
int n = arr.length;
int m = arr[0].length;
boolean[] dups = new boolean[n * m];
int singles = 0;
for (int i = 0; i < dups.length; i++) {
if (dups[i]) continue; // skip the value known to be a duplicate
int curr = arr[i / m][i % m];
boolean dup = false;
for (int j = i + 1; j < dups.length; j++) {
if (curr == arr[j / m][j % m]) {
dup = true;
dups[j] = true;
}
}
if (dup) {
dups[i] = true;
} else {
singles++;
}
}
// debugging log
System.out.println("singles = " + singles + "; " + Arrays.toString(dups));
int[] res = new int[singles];
if (singles > 0) {
for (int i = 0, j = 0; i < dups.length; i++) {
if (!dups[i]) {
res[j++] = arr[i / m][i % m];
}
}
}
return res;
}
Test:
int[][] mat = {
{2, 2, 3, 3},
{4, 2, 0, 3},
{5, 4, 2, 1}
};
System.out.println(Arrays.toString(getSingles(mat)));
Output(including debugging log):
singles = 3; [true, true, true, true, true, true, false, true, false, true, true, false]
[0, 5, 1]
Your use of previous is merely an idea on the horizon. Remove it, and fill the one dimensional a. Finding duplicates with two nested for-loops would require n4 steps. However if you sort the array a, - order the values - which costs n² log n², you can find duplicates much faster.
Arrays.sort(a);
int previous = a[0];
for (int h = 1; h < a.length; ++h) {
if (a[h] == previous)...
previous = a[h];
...
It almost looks like this solution was already treated in class.
It doesn't look good:
previous = m[i][j];
if (m[i][j] != previous) {
a[h] = m[i][j];
h++;
}
you assigned m[i][j] to previous and then you check if if (m[i][j] != previous)?
Are there any limitations in the task as to the range from which the numbers can come from?

Print Pascal's Triangle using recursion

I'm trying to develop a program that prints out Pascal's Triangle using recursion. Here are my codes:
public class PascalTriangle {
public static int[] computePT(int k) {
int[] pt = new int[k + 1];
if (k == 0) {
pt[0] = 1;
return pt;
} else {
int[] ppt = computePT(k - 1);
pt[0] = pt[k] = 1;
for (int i = 1; i < ppt.length; i++) {
pt[i] = ppt[i - 1] + ppt[i];
}
}
return pt;
}
}
public class PascalTriangleDriver {
public static void main(String args[]) {
int k = 10;
int arr[] = PascalTriangle.computePT(k);
for (int i = 0; i < arr.length; i++)
System.out.print(arr[i] + " ");
System.out.println();
}
}
The code runs perfectly, however my issue is that I want to modify my PascalTriangle code (not the PascalTriangleDriver code) such that when k=10, for example, it prints out:
1 9 36 84 126 126 84 36 9 1
instead of:
1 10 45 120 210 252 210 120 45 10 1
You seem to have made an off-by-1 error. One simple way to solve this is to write another method that calls your original method with k-1:
// this is your original method, just renamed:
private static int[] computePTImpl(int k) {
int[] pt = new int[k + 1];
if (k == 0) {
pt[0] = 1;
return pt;
} else {
int[] ppt = computePT(k - 1);
pt[0] = pt[k] = 1;
for (int i = 1; i < ppt.length; i++) {
pt[i] = ppt[i - 1] + ppt[i];
}
}
return pt;
}
// you will call this method:
public static int[] computePT(int k) {
return computePT(k - 1);
}
Alternatively, you can actually fix your code by replacing ks with k-1s:
public static int[] computePT(int k) {
int[] pt = new int[k]; // note the change
if (k == 1) { // note the change
pt[0] = 1;
return pt;
} else {
int[] ppt = computePT(k - 1);
pt[0] = pt[k - 1] = 1; // note the change
for (int i = 1; i < ppt.length; i++) {
pt[i] = ppt[i - 1] + ppt[i];
}
}
return pt;
}
Note that we don't change the recursive call because if we did, we would be saying that the k-th row of Pascal's triangle depends on the k-2-th row, which is not true.
You can iteratively populate an array of binomial coefficients as follows: the first row and column are filled with ones, and all other elements are equal to the sum of the previous element in the row and column.
T[i][j] = T[i][j-1] + T[i-1][j];
You can create two methods: one returns a 2d array containing a triangle, and the second returns the base of that triangle. It is more useful for clarity.
Output:
Triangle:
1 1 1 1 1 1 1 1 1 1
1 2 3 4 5 6 7 8 9
1 3 6 10 15 21 28 36
1 4 10 20 35 56 84
1 5 15 35 70 126
1 6 21 56 126
1 7 28 84
1 8 36
1 9
1
Base:
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
Code:
public static void main(String[] args) {
int n = 10;
System.out.println("Triangle:");
int[][] arr = binomialTriangle(n);
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++)
if (arr[i][j] > 0)
System.out.printf("%2d ", arr[i][j]);
System.out.println();
}
int[] base = binomial(arr);
System.out.println("Base:");
System.out.println(Arrays.toString(base));
}
public static int[][] binomialTriangle(int n) {
// an array of 'n' rows
int[][] arr = new int[n][];
// iterate over the rows of the array
for (int i = 0; i < n; i++) {
// a row of 'n-i' elements
arr[i] = new int[n - i];
// iterate over the elements of the row
for (int j = 0; j < n - i; j++) {
if (i == 0 || j == 0) {
// elements of the first row
// and column are equal to one
arr[i][j] = 1;
} else {
// all other elements are the sum of the
// previous element in the row and column
arr[i][j] = arr[i][j - 1] + arr[i - 1][j];
}
}
}
return arr;
}
public static int[] binomial(int[][] arr) {
int[] base = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
// the last element in the row
base[i] = arr[i][arr[i].length - 1];
}
return base;
}
See also: Finding trinomial coefficients using dynamic programming

how to get minimum in 2d array java

I need help, please! I am building up the following code to extract the minimum value of each column of the distance
I have tried to compute the code but to no avail
public static void main(String[] args) {
int data[] = {2, 4, -10, 12, 3, 20, 30, 11};//,25,17,23}; // initial data
int noofclusters = 3;
int centroid[][] = new int[][]{
{0, 0, 0},
{2, 4, 30}
};
getCentroid(data, noofclusters, centroid);
}
public static int[][] getCentroid(int[] data, int noofclusters, int[][] centroid) {
int distance[][] = new int[noofclusters][data.length];
int cluster[] = new int[data.length];
int clusternodecount[] = new int[noofclusters];
centroid[0] = centroid[1];
centroid[1] = new int[]{0, 0, 0};
System.out.println("========== Starting to get new centroid =========");
for (int i = 0; i < noofclusters; i++) {
for (int j = 0; j < data.length; j++) {
//System.out.println(distance[i][j]+"("+i+","+j+")="+data[j]+"("+j+")-"+centroid[0][i]+"="+(data[j]-centroid[0][i]));
distance[i][j] = Math.abs(data[j] - centroid[0][i]);
System.out.print(distance[i][j] + " ,");
}
System.out.println();
}
int[] result = new int[distance.length];
for (int i = 0; i < distance.length; i++) {
//int min = distance;
int min = distance[i][0];
for (int j = 0; j < distance[0].length; j++) {
if (distance[i][j] < min) {
min = distance[i][j];
}
result[j] = min;
System.out.println(result[j] + ", ");
}
}
return result;
}
}
The result of the computation for distance gives
row 1: 0 ,2 ,12 ,10, 1 ,18 ,28 ,9
row 2: 2 ,0 ,14 ,8 , 1 ,16 ,26 ,7
row 3: 28,26,40 ,18, 27 ,10 ,0 ,19
I want to go through each column to get the minimum value
0 0 12 8 1 10 0 7
Thanks for your help in advance
To get the minimum value in each column, first, you need to iterate the column in the outer loop. By doing so, we can access the matrix colunm-wise.
Assign the first value of each column to a variable. Then iterate through the rows in the inner loop.
Check if the current value is less than the minimum value. If so, assign the smallest value to minimum.
When we use an array, we get an array of minimum values of the column.
To obtain the minimun value in each row, swap the loops and use min[i].
Below is an example code:
int []min = new int[column_lenght];
for(int j = 0; j < column_length; j++) {
min[j] = array[i][j];
for(int i = 0; i < row_length; i++) {
if(array[i][j] < min[j]) {
min[j] = array[i][j];
}
}
}
The min[] will contain the minimum value of each column.

Java: Compare a value with an array; Getting the first 3 numbers bigger that the value

I have a number x=27 and an array of values int[] y=[15,20,25,30,35,40,45].
How can I compare the two in order to get the first 3 numbers from the array that are bigger than x?
I guess a for loop needs to be used here but I'm a beginner so this is beyond me.
There is a working solution using arrays:
public class Main {
public static void main(String[] args) {
int x = 27;
int[] y = {15, 20, 25, 30, 35, 40, 45};
int[] result = new int[3];
int z = 0;
for(int i = 0; i < y.length; i++) {
if(y[i] > x && z < 3) {
result[z] = y[i];
z++;
}
}
System.out.println(result[0] + " " + result[1] + " " + result[2]); //Print 30 35 40
}
}
If the array is sorted and contains no duplicates (as is the case in the example given), you can get this result out quickly using a binary search:
int pos = java.util.Arrays.binarySearch(
y,
0/*inclusive as per function spec*/,
y.length/*exlusive as per function spec*/,
x
);
if (pos >= 0){
// x is found at position 'pos', but we want elements greater than this.
++pos;
} else {
int i = -pos - 1; // this is where x would be inserted to preserve sortedness
pos = i + 1;
}
// ToDo - your elements are at `pos`, `pos + 1`, and `pos + 2`,
// subject to your not running over the end of the array `y`.
try this:
int[] y={15,30,29,30,35,40,45};
int x=27;
for(int i = 0,index = 3; i < y.length; i++){
if(i < index && y[i] > x){
System.out.print(y[i]+" ");
}
}
output:
30 29
Fascinating how everybody sticks to loops... Stream-based, we have 2016 after all:
int[] y = {15, 20, 25, 30, 35, 40, 45};
int x = 17;
IntStream.of(y).filter(v -> v > x).limit(3).forEach(System.out::println);

Java sorting program, getting a confusing output

public static void main(String[] args) throws Exception {
// declarations
int i, z, x, greatest;
int[] array = { 2, 3, 4, 55, 6 };
int[] copyarray = { 0, 0, 0, 0, 0 };
int zz;
greatest = array[0];
for (zz = 0; zz < 5; zz++) {
for (x = 0; x < 5; x++) {
if (array[x] > greatest) {
greatest = array[x];
}
}
copyarray[zz] = greatest; // this will contain the sorted array
// part of the nested loop
for (z = 0; z < 5; z++) {
if (greatest == array[z]) {
array[z] = 0;
}
}
}
// not part of the nested loop
for (i = 0; i < 5; i++) {
System.out.println("sorted array: " + copyarray);
}
}
Output:
sorted array: [I#1a16869
sorted array: [I#1a16869
sorted array: [I#1a16869
sorted array: [I#1a16869
sorted array: [I#1a16869
This is just a basic little program and I'm trying to get the logic right. I can't improve it or make it into a class or method because I'm not even getting the output right.
If you are trying to use your own algorithm, i would suggest you try using IDE and debug the code.
If you want to use algorithm that JDK provides, you could use:
Arrays.sort(array);
Regarding the output, you are trying to print array and array is an object without toString implementation in java. Hence you should change your print statement to :
System.out.println("sorted array: "+Arrays.toString(copyarray));//without surrounding for loop to get what its after each step of sorting elements.
Or if you want to keep your for loop then you could use index based access to array like:
System.out.print(copyarray[i] + " ");
Actually, none of the answers here are right.
The heart of the problem is that you are not re-initializing the variable greatest for each iteration. It is set to array[0]; in the beginning and it is never changed again. This should go inside the loop.
public static void main(String[] args) throws Exception {
// declarations
int i, z, x, greatest;
int[] array = { 2, 3, 4, 55, 6 };
int[] copyarray = { 0, 0, 0, 0, 0 };
int zz;
// greatest = array[0]; <---- Don't do it here
for (zz = 0; zz < 5; zz++) {
greatest = array[0]; // <--- Initialize greatest here and not before the loop
for (x = 0; x < 5; x++) {
if (array[x] > greatest) {
greatest = array[x];
}
}
copyarray[zz] = greatest; // this will contain the sorted array
// part of the nested loop
for (z = 0; z < 5; z++) {
if (greatest == array[z]) {
array[z] = 0;
}
}
}
// not part of the nested loop
for (i = 0; i < 5; i++) {
System.out.println("sorted array: " + copyarray[i]);
}
}
As a side note, you are printing the array incorrectly, you should use copyarray[i] and not copyarray.
Whit these two changes, here's the output:
sorted array: 55
sorted array: 6
sorted array: 4
sorted array: 3
sorted array: 2
You are printing the reference not the value
use:
for(int i = 0; i < copyarray.length; i++ ) {
System.out.println("Value : " + copyarray[i]);
}
i would also recommend using Arrays.sort(array);
just write
private int[] values = { 9,2,5,3,1,7,0 };
public void printSorted() {
Arrays.sort(values);
for(int i = 0; i < values.length; i++) {
System.out.println("Value: " + values[i]);
}
}

Categories

Resources