Lowest value is always 0 in 2d array - java

New guy here trying 2D arrays. I have these codes but whenever I run it, the lowest value would always end up with 0 even if I input non-zero digits. Any idea how to fix this?
import javax.swing.JOptionPane;
public class TwoDArrayActivity {
public static void main(String[] args){
// declaration of array
int a[][] = new int[3][3];
int i = 0; // rows
int j = 0; // columns
String display = "";
int low = a[i][j];
for(i=0; i < a.length; i++) { // count the number of rows
for(j = 0; j < 3; j++) { // count the number of columns
a[i][j] = Integer.parseInt(JOptionPane.showInputDialog("Enter a Number to Array [" + i + "]" + "[" + j + "]"));
if(a[i][j] < low)
low = a[i][j];
display = display + a[i][j] + " ";
} // end of inner for
display = display + "\n"; //new line
} // end of outer for
JOptionPane.showMessageDialog(null,"Values in Array\n" + display + "Lowest value is " + low, "Values in Array", JOptionPane.INFORMATION_MESSAGE);
} // end of method
} // end of class

Replace :
int low = a[i][j];
with :
int low = Integer.MAX_VALUE;

// declaration of array
int a[][] = new int[3][3];
The issue is here, when you instantiate the array it automatically fills every emtry with 0, as this is the equivalent of the undefined value for an integer type. eg.
new int[3][3]
>> [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
Therefore your low variable always has the value 0 and is never replaced by something lower

When you initialize an array implicitly in Java, the memory gets set to null, 0, 0L, 0.0f, false, or 0.0, etc, as appropriate for the datatype.
That means that your statement int low = a[i][j]; is setting low to an initial value of zero. All further comparisons will be against that, so your only chance to change that value is to enter a negative number, like -1.
You can add a test to your loop to initialize low with the first element of the loop you get:
if((i == 0 && j == 0) || a[i][j] < low)
Another option is to initialize low to the largest possible integer instead of implicit zero. In this simple example, that's probably the simplest approach to take:
int low = Integer.MAX_VALUE;
A third option is to add a boolean flag:
int low = ...;
boolean isFirst = true;
...
if(isFirst || a[i][j] < low)
...
isFirst = False;

You have to input negative numbers for it to change.
Otherwise, you can change it to
if(a[i][j] < low)
low = a[i][j];
but the name low wouldn't make sense anymore (it will be a "max").

Related

Trying to create a array with the intersection of two arrays but fails at creating array with the proper structure

So, I am trying to create 2 randomly generated arrays,(a, and b, each with 10 unique whole numbers from 0 to 20), and then creating 2 arrays with the info of the last two. One containing the numbers that appear in both a and b, and another with the numbers that are unique to a and to b. The arrays must be listed in a "a -> [1, 2, 3,...]" format. At the moment I only know how to generate the 2 arrays, and am currently at the Intersection part. The problem is, that I can create a array with the correct list of numbers, but it will have the same length of the other two, and the spaces where it shouldn't have anything, it will be filled with 0s when its supposed to create a smaller array with only the right numbers.
package tps.tp1.pack2Arrays;
public class P02ArraysExtractUniqsAndReps {
public static void main(String[] args) {
int nbr = 10;
int min = 0;
int max = 20;
generateArray(nbr, min, max);
System.out.println();
}
public static int[] generateArray(int nbr, int min, int max) {
int[] a = new int[nbr];
int[] b = new int[nbr];
int[] s = new int[nbr];
s[0] = 0;
for (int i = 0; i < a.length; i++) {
a[i] = (int) (Math.random() * (max - min));
b[i] = (int) (Math.random() * (max - min));
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
i--;
}
if (b[i] == b[j]) {
i--;
}
}
}
System.out.println("a - > " + Arrays.toString(a));
System.out.println("b - > " + Arrays.toString(b));
for (int k = 0; k < a.length; k++) {
for (int l = 0; l < b.length; l++) {
if (a[k] == b[l]) {
s[l] = b[l];
}else {
}
}
}
System.out.println("(a ∪ (b/(a ∩ b)) - > " + Arrays.toString(s));
return null;
}
public static boolean hasValue(int[] array, int value) {
for (int i = 0; i < array.length; i++) {
if (array[i] == value) {
return true;
}
}
return false;
}
}
Is there any way to create the array without the incorrect 0s? (I say incorrect because it is possible to have 0 in both a and b).
Any help/clarification is appreciated.
First, allocate an array large enough to hold the intersection. It needs to be no bigger that the smaller of the source arrays.
When you add a value to the intersection array, always add it starting at the beginning of the array. Use a counter to update the next position. This also allows the value 0 to be a valid value.
Then when finished. use Array.copyOf() to copy only the first part of the array to itself, thus removing the empty (unfilled 0 value) spaces. This works as follow assuming count is the index you have been using to add to the array: Assume count = 3
int[] inter = {1,2,3,0,0,0,0};
inter = Arrays.copyOf(inter, count);
System.out.println(Arrays.toString(inter);
prints
[1,2,3]
Here is an approach using a List
int[] b = {4,3,1,2,5,0,2};
int [] a = {3,5,2,3,7,8,2,0,9,10};
Add one of the arrays to the list.
List<Integer> list = new ArrayList<>();
for(int i : a) {
list.add(i);
}
Allocate the intersection array with count used as the next location. It doesn't matter which array's length you use.
int count = 0;
int [] intersection = new int[a.length];
Now simply iterate thru the other array.
if the list contains the value, add it to the intersection array.
then remove it from the list and increment count. NOTE - The removed value must be converted to an Integer object, otherwise, if a simple int value, it would be interpreted as an index and the value at that index would be removed and not the actual value itself (or an Exception might be thrown).
once finished the intersection array will have the values and probably unseen zeroes at the end.
for(int i = 0; i < b.length; i++) {
int val = b[i];
if (list.contains(val)) {
intersection[count++] = val;
list.remove(Integer.valueOf(val));
}
}
To shorten the array, use the copy method mentioned above.
intersection = Arrays.copyOf(intersection, count);
System.out.println(Arrays.toString(intersection));
prints
[3, 2, 5, 0, 2]
Note that it does not matter which array is which. If you reverse the arrays for a and b above, the same intersection will result, albeit in a different order.
The first thing I notice is that you are declaring your intersection array at the top of the method.
int[] s = new int[nbr];
You are declaring the same amount of space for the array regardless of the amount you actually use.
Method Arrays.toString(int []) will print any uninitialized slots in the array as "0"
There are several different approaches you can take here:
You can delay initializing the array until you have determined the size of the set you are dealing with.
You can transfer your content into another well sized array after figuring out your result set.
You could forego using Array.toString, and build the string up yourself.

RodCutting: when the rod is bigger than the array length

How can I modify the methods cutRod and bottomUpCutRod to hold lengths that are bigger than the array length. For example, currently p has length 11, how can I cut the rod of length 15, 20 , etc, having this same array. For example
p = {0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30};
if I call cutRod(p,10), I get 30, but it crashes of course in cutRod(p,15) or
cutRod(p,20). (same applies for bottomUpCutRod). Any ideas how to do this?. This is dynamic programming problem, my idea to implement bottomUpCutRod method is to traverse p and for each element calculate every permutation of itself and its neighbors and update if necessary the resulting array, r.
public class Main {
private static final double MINUS_INFINITY = Double.NEGATIVE_INFINITY;
public static void main(String[] args) {
// price array
double[] p = {0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30};
// test cutRod
cutRod(p,10);
// test bottomUpCutRod
bottomUpCutRod(p,10);
}//end of main
// an optimal cut for a rod of length n
// p is the price array
// use recursion
private static double cutRod(double[] p, int value) {
double[] r = new double[value+1];
double out = 0;
// initialize r to NEGATIVE_INFINITY;
for (int i = 1; i < r.length; i++)
r[i] = MINUS_INFINITY;
// call the helper method
out = helpCutRod(p,r.length-1,r);
// print r
System.out.println("Result ");
System.out.println("r[" + (r.length-1) + "] = " + r[r.length-1]);
return out;
}//end of method
// helpCutRod computes an optimal cut for a rod
// p is the price array and r[i] is the optimal cut for a rod of length i
// n is the length of the rod that is currently being computed
private static double helpCutRod(double[] p, int n, double[] r) {
double q = MINUS_INFINITY;
if (r[n] >= 0) // the whole r was computed
return r[n];
if (n == 0)
q = 0;
else {
for (int i = 1; i <= n; i++) {
q = RodCutting.max(q, p[i] + helpCutRod(p,n-i,r));
}
r[n] = q;
}
return q;
}
// use the bottom-up approach
// do NOT use recursion
private static double bottomUpCutRod(double[] p, int len) {
// r[i] is the optimal cut for a rod of length i
double[] r = new double[len+1];
r[0] = 0;
for (int j = 1; j < p.length; j++) {
// compute r[j]
double q = MINUS_INFINITY;
// r[j] is the maximum over i of p[i] + r[j-i]
// where 1<= i <= j
for (int i = 1; i <= j; i++)
q = max(q, p[i] + r[j-i]);
// update value of r[j]
r[j] = q;
}//end of for outer
// print r
System.out.println("The r array from the bottomUpCutRod:");
System.out.println("r[" + len + "] = " + r[len]);
return r[len] ;
}//end of method
public static double max(double a, double b){
if(a<=b){
return b;
}else{
return a;
}
}//end of max
}//end of class
If I understand the rod cutting problem correctly, your price array, p, tells the prices at which you can sell rod pieces of lenghts 0 through p.length - 1. So if the array length is 11, you know the prices of pieces up to length 10 even if you have an inital rod of length 15, 20 or 30. Since you don’t know the prices for lengths 11 and above, I assume you can safely set them to 0. I would then expect the algorithm to cut up your rod into pieces for which you know a positive price.
If all of this is correct, the solution is easy. To calculate, say, cutRod(p, 15), first do
p = Arrays.copyOf(p, 15 + 1);
This will copy p into a new array with indices 0 through 15, padded with zeores. Now run your methods. Similarly for other initial lengths, of course.
With this modification, your program prints for a rod length of 15:
Result
r[15] = 43.0
The r array from the bottomUpCutRod:
r[15] = 43.0
I assume it’s found pieces at 10, 3 and 2 yielding prices 30 + 8 + 5 = 43, but I haven’t checked.
EDIT: If the rod is very much longer than the price array, it is probably wasteful to have it calculate results with cuts longer than the maximum of the price array. So instead of the above quick fix, it is in fact possible to modify your methods to accept a shorter price array and a longer initial rod.
In the recursive helpCutRod(), change the for loop to:
for (int i = 1; i <= Math.min(n, p.length - 1); i++) {
This will make sure that only pieces for which we have prices will be considered.
For bottomUpCutRod(), two changes are needed:
The first for loop needs to run until j equals len:
for (int j = 1; j < r.length; j++) {
And again, the inner for loop should not pass the bounds of p:
for (int i = 1; i <= Math.min(j, p.length - 1); i++)
With these three modifications instead of the extension of the p array, the program prints the same results as above.

Creating a changing sequence of numbers in a for loop Java?

I'm trying to increment the following sequence in a for loop (Java):
1, 4, 9, 16, 25 etc the difference increasing by two each time. I tried using 'i+=3 + i' but I know that's wrong since it doesn't take into account that the variable i changes along the sequence.
Any help? Thanks
You could have an increment of i+=k and change k inside the loop in order to change the increment.
int k=1;
for (int i=1;i<1000;i+=k) {
k+=2;
}
If your i is changing, the simple logic is, use another variable that is declared outside the scope of the loop. This will make sure that it is not recreated everytime the loop runs.
int num = 1;
for(int i=1; i<maxValue; num+=2,i+=num){
//Use the value of `i` here, it will be as you wanted.
}
The sequence is to start with j=1 and k=4 and then derive next values of the series n times. The formula as follow:
Initial loop (i=0):
j = 1, k = 4;
Loop (i > 0 less than n):
Repeat below n times:
temp = k;
k = k + (k - j + 2);
j = temp;
print value of j being the series;
I assume that you take n as input from user and then generate the series nth times. Let's look at the following code example
int n = 10;
for(int i = 0, temp = 0, j = 1, k = 4; i < n; i++, temp = k, k += (k-j+2), j = temp) {
System.out.println(j);
}
Assuming that user inputs n = 10, the loop initializes i = 0 and continues until i < n is satisfied. It initializes j = 1 and k = 4 and then execute the body of the loop (printing j) followed by backing up the value of k, calculating new value for k and replacing the old value of j. The output for n = 10 is as follow:
1
4
9
16
25
36
49
64
81
100
Read Series number from the user and generate series based on given number.
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int ans;
for(int i = 1; i <= n; i++){
ans = i * i;
System.out.println(ans);
}

Else if statements

I'm a beginner to java... if statements followed by else if statements are evaluated in order until one that evaluates to true is found, and I've seen many examples of this. But in this program, both statements (the if and the else if) are evaluated. Why?
public int centeredAverage(int[] nums) {
int[] nums = {1, 1, 5, 5, 10, 8, 7};
int sum = 0;
int centered = 0;
int min = nums[0];
int max = nums[0];
int i = 0;
for (i = 0; i < nums.length; i++){
if (nums[i] < min){
min = nums[i];
} else if (nums[i] > max){
max = nums[i];
}
sum += nums[i];
centered = ((sum-max-min)/(nums.length-2));
}
return centered;
}
Because they're in a loop that changes i and so changes nums[i] and so changes what if's are true.
Your passing in array of doubles by reference called nums and the defining an array of the same name in the method which seems odd. Also your start index for your for loop should be 1
Im guessing this is the same problem from codingbat, next time copy and paste the problem desciption for others!
public int centeredAverage(int[] nums) {
Arrays.sort(nums); //sorts the array smallest to biggest
int total = 0;
//nums is already sorted, so the smallest value is at spot 0
//and the biggest value is at the end.
for(int a = 1; a < nums.length - 1; a++){ //avoid the first and last numbers
total += nums[a];
}
return total / (nums.length - 2); //need ( ) so we can substract 2 first
//Another way could simply sum all the elements then subtract from that sum
//the biggest and smallest numbers in the array, then divide by nums.length- 2, it is a
//little more complex, but allows a for : each loop.
}
But for you, well since you are a beginner, restate your strategy (algorithm), find the smallest and biggest numbers in the array, subtract that out of the sum of all elements in the array then divide that number by nums.length - 2, since we are ignoring 2 numbers.
Working of If statement followed by else-if is fine here. We are getting expected result here. Both the statements if and else-if are not executed. Only that statement is executed which comes TRUE as per logic.
Here we can identify the working of the program using "System.out.println". Code and console output is given below...
int[] nums = {1, 1, 5, 5, 10, 8, 7};
int sum = 0;
int centered = 0;
int min = nums[0];
int max = nums[0];
int i = 0;
for (i = 0; i < nums.length; i++)
{
if (nums[i] > min)
{
min = nums[i];
System.out.println("inside first if: " + i);
// taking value of i in SOP to get the iteration value
}
else if (nums[i] > max)
{
max = nums[i];
}
sum += nums[i];
centered = ((sum-max-min)/(nums.length-2));
System.out.println("inside else if: " + i);
// taking value of i in SOP to get the iteration value
}
System.out.println("centered value "
+ " " + centered);
You can make a good usage of SOP in every program to get the execution order.

finding longest sequence of consecutive numbers

Problem H (Longest Natural Successors):
Two consecutive integers are natural successors if the second is the successor of the first in the sequence of natural numbers (1 and 2 are natural successors). Write a program that reads a number N followed by N integers, and then prints the length of the longest sequence of consecutive natural successors.
Example:
Input 7 2 3 5 6 7 9 10 Output 3 this is my code so far and i have no idea why it does not work
import java.util.Scanner;
public class Conse {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int x = scan.nextInt();
int[] array = new int[x];
for (int i = 0; i < array.length; i++) {
array[i] = scan.nextInt();
}
System.out.println(array(array));
}
public static int array(int[] array) {
int count = 0, temp = 0;
for (int i = 0; i < array.length; i++) {
count = 0;
for (int j = i, k = i + 1; j < array.length - 1; j++, k++) {
if (Math.abs(array[j] - array[k]) == 1) {
count++;
} else {
if (temp <= count) {
temp = count;
}
break;
}
}
}
return temp + 1;
}
}
Why two loops? What about
public static int array(final int[] array) {
int lastNo = -100;
int maxConsecutiveNumbers = 0;
int currentConsecutiveNumbers = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == lastNo + 1) {
currentConsecutiveNumbers++;
maxConsecutiveNumbers = Math.max(maxConsecutiveNumbers,
currentConsecutiveNumbers);
} else {
currentConsecutiveNumbers = 1;
}
lastNo = array[i];
}
return Math.max(maxConsecutiveNumbers, currentConsecutiveNumbers);
}
This seems to work:
public static int longestConsecutive(int[] array) {
int longest = 0;
// For each possible start
for (int i = 0; i < array.length; i++) {
// Count consecutive.
for (int j = i + 1; j < array.length; j++) {
// This one consecutive to last?
if (Math.abs(array[j] - array[j - 1]) == 1) {
// Is it longer?
if (j - i > longest) {
// Yup! Remember it.
longest = j - i;
}
} else {
// Start again.
break;
}
}
}
return longest + 1;
}
public void test() {
int[] a = new int[]{7, 2, 3, 5, 6, 7, 9, 10};
System.out.println("Longest: " + Arrays.toString(a) + "=" + longestConsecutive(a));
}
prints
Longest: [7, 2, 3, 5, 6, 7, 9, 10]=3
Since your question has "Problem H" associated with it, I'm assuming you are just learning. Simpler is always better, so it usually pays to break it down into "what has to be done" before starting on a particular road by writing code that approaches the problem with "how can this be done."
In this case, you may be over-complicating things with arrays. A number is a natural successor if it is one greater than the previous number. If this is true, increment the count of the current sequence. If not, we're starting a new sequence. If the current sequence length is greater than the maximum sequence length we've seen, set the max sequence length to the current sequence length. No arrays needed - you only need to compare two numbers (current and last numbers read).
For example:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int N = scan.nextInt();
int maxSequenceLen = 0; // longest sequence ever
int curSequenceLen = 0; // when starting new sequence, reset to 1 (count the reset #)
int last = 0;
for(int i = 0; i < N; i++) {
int cur = scan.nextInt();
if ((last+1) == cur){
++curSequenceLen;
}
else{
curSequenceLen = 1;
}
if (curSequenceLen > maxSequenceLen){
maxSequenceLen = curSequenceLen;
}
last = cur;
}
System.out.println(maxSequenceLen);
Caveat: I'm answering this on a computer that does not have my Java development environment on it, so the code is untested.
I'm not sure I understand this question correctly. The answer's written here assumes that the the natural successors occur contiguously. But if this is not the same then the solution here might not give the correct answer.
Suppose instead of [7 2 3 5 6 7 9 10] the input was [7 2 6 3 7 5 6 9 10] then the answer becomes 2 while the natural successor [5 6 7] is present in the array.
If the input is not sorted we'll have to use a different approach. Like using HashSet
Load the entire array into a HashSet which removes duplicates.
Pick the first value from the HashSet and assigned it to start and end and remove it from the set.
Now decrements start and check if it is present in the HashSet and continue till a particular value for start is not present int the HashSetwhile removing the value being searched from the set.
Do the same for end except that you will have to increase the value of end for each iteration.
We now have to continuous range from start to end present in the set and whose range is current_Max = end - start + 1
In each iteration we keep track of this current_Max to arrive at the longest natural successor for the entire array.
And since HashSet supports Add, Remove, Update in O(1) time. This algorithm will run in O(n) time, where n is the length of the input array.
The code for this approach in C# can be found here

Categories