Odd problem with implementing max with for loop - java

I spend the last hour doing trial and error with this problem with no avail. We have to, using general coding guidelines (like scan.nextDouble) instead of actual numbers, find the max of a certain number of double values. The only catch is that we can only add code at a certain point. (where the ... is)
double value, valMax;
int n;
n = scan.nextInt();
for(int j = 0; j < n; j++)
{
value = scan.nextDouble();
...
}
Where the first value read in is an int and that is the amount of doubles to be entered.
It is difficult because I have to find a way to initialize valMax inside the loop without messing up anything else.
This is what I have been working with, but with nothing working for me.
for(int j = 0; j < n; j++)
{
value = scan.nextDouble();
if(j == 0)
{
valMax = scan.nextDouble();
j++;
}
else
{
continue;
}
if(value >= valMax)
{
valMax = value;
}
}
Example input:
5 -4.7 -9.2 -3.1 -8.6 -5.0
Where -3.1 is the max and 5 is the count of following numbers.

Your code seems like a good start.
To help solve your problem, consider:
Why did you put in the extra j++? Do you really need it? (Hint: no ;-) )
What will the loop do for j>0 (i.e. after the first iteration)?
That should quickly give you a working solution.

Are you allowed to set the valMax before the loop? Because in that case you can just do
valMax = Double.MIN_VALUE
and just forget about strange things by doing a normal comparison value > valMax.
If you are not your approach is how you should do but two things:
you shouldn't care about incrementing with j++ since the for loop will care about it by itself..
having a else { continue; } will make the body of the for jump to next iteration without caring about code that is after the continue. Are you sure that is what you want to do?
I think that you can initialize to Double.MIN_VALUE at first iteration (j == 0) and just behave normally afterwards: the only thing you need is that valMax is initialized before the first comparison with value, not before the scan from stdin..

Related

Flexible number of for-loops - Java

I'm looking for a way to use a flexible amount of for-loops or some solution that will do the same. Basically I want a variable to go from 0 to 100 in each loop and go through all combinations. The for-loops are nested so if I am looking for a solution for two agents I have:
for(int i = 0; i<=100; i++){
for(int j = 0; j<=100, j++){
//do some stuff with i and j
}
}
but I do not ex ante know how many agents will be needed so I'm looking for a flexible way to get the same result. This might be quite an easy question but I was not able to find a threat which gave me a working solution.
EDIT: It was pointed out to me that the question is not clear enough, I will try to demonstrate what I am trying to achieve:
Let's say I have n agents, if n == 1 then I would need this:
for(int j = 0; j<=100, j++){
//do some stuff with j
}
for n == 2 I would want:
for(int i = 0; i<=100; i++){
for(int j = 0; j<=100, j++){
//do some stuff with i and j
}
}
for n == 3 another for look around these existing ones and so on, but it need to be flexible as the user is asked for n and can type in any integer.
//EndEDIT I hope this made it clearer
Thank you in advance!
I think the easiest way to achieve this is recursively.
Assuming you want the same limits on each range (i.e. that i,j,k etc go from 0..100), you can do it like so:
void recursive(List<Integer> values, int depth) {
if (values.size() == depth) {
// Do the thing you want to do with the values, i.e. the "innermost loop".
} else {
// This is intentionally Integer, so that remove removes that value, not the element at that index.
for (Integer a = 0; a <= 100; ++a) {
values.add(a);
recursive(values, depth);
values.remove(a);
}
}
}
While there are fewer than depth values in the list, this adds each value in the range into the list in turn, and recurses.
Once there are enough values in the list, then it does the "thing" you want to do. The list will contain depth values, and you can access an individual value using values.get(i).

Printing Simple Patterns in Java

Could someone explain the basics behind printing simple patterns in Java?
I'll give one specific example.
I'd just like for someone to clarify what each line is doing so I get a better understanding of how this works. Any other explained examples (line by line) would also be appreciated!
public static void drawPyramidPattern() {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5 - i; j++) {
System.out.print(" ");
}
for (int k = 0; k <= i; k++) {
System.out.print("* ");
}
System.out.println();
}
}
Printing anything or everything via a loop is just about understanding the flow of execution. In your code also, if you'll start watching the flow line by line you'll come to know that how it is working exactly.
If you understand how it works, you would be able to print any pattern, but basics should be clear. Try printing variable i, j and k values after each iteration. See the values that how that gets changed after each cycle of execution and then see the logic you've applied.
Your question is somewhat very broad in scope and can not be answered exactly unless narrowed it down. I would suggest to run this line by line and watch the output, try more changes even if it doesn't make any sense, you'll be having a good understanding over looping even for all of your future tasks. And if after trying yourself, you come to any problem, share here, people are ready to solve them. :)
Hope this helps.
First you must a have complete understanding of loops, nested loops then you come up to patterns designing.
1) First run the loops in hard form like on Register/on Page for understanding the loops.
2) Use debugger to identify the loop progress.
If you think about it in terms of mathematics, loops are just functions.
A single for loop would just be x.
Example
for (int i = 0; i < 5; i++) {
System.out.println("This is function x.");
}
However when you start nesting loops it because a greater function. A for loop inside another for loop would be a function x^2
For example:
for (int i = 0; i < 5; i++) {
for (int j = 0; J < 5; j++){
System.out.println("This is the j loop");
}
System.out.println("This is the i loop");
}
The reason behind this is because in order to finish the first iteration of i, everything inside the loop must be completed. But, the i loop has another loop inside of it, so that must be finished first. So the loop with j must execute until it is finished. (In this case 5 times), Great, now we can increment i. But now we have to step through j again! This process continues until i reaches its threshold of being < 5. So the output would look something like this
Output:
This is the j loop
This is the j loop
This is the j loop
This is the j loop
This is the j loop
This is the i loop
This is the j loop
This is the j loop
....
This would continue until the i has reached 5, in which case it no longer satisfies the necessary i < 5, and the loop would end. Hopefully this helps
First, since i = 0 & 0<5 is true you enter the first(outer) for-loop.
Remember i = 0.
Then j = 0; but 0 < i = 0 is false so you don't enter the second loop.
For the third loop, k = 0 & 0<=0 is true. So you enter the loop and execute the print statement, i.e print a star.
k++, this will increment k by 1 and check the boolean; You ask yourself is 1 <= 0; clearly no ; so you exit the for-loop and then reach the println statement which will take you to the next line.
And then you go back to the outer loop.
//this code print Diagonal Pattern if matrix is
1 2 3
4 5 6
7 8 9
output is :
1
4 2
7 5 3
8 6
9
import java.util.*;
class DiagonalPattern
{
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
int x[][];
int i,j,row,col,p,temp=1,last=0;
System.out.println("how many array wants to create and size of array");
row=sc.nextInt();
col=sc.nextInt();
x=new int[row][col];
System.out.println("Enter " +row*col+ " elements of array of array");
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
x[i][j]=sc.nextInt();
last=j;
}
}
for(i=0;i<row;i++)
{
System.out.println("");
int k=i;
for(j=0;j<=i;j++,k--)
{
if(j==col)
{
break;
}
else
{
System.out.print(x[k][j]);
System.out.print(" ");
}
}
}
for(p=x.length;p>0;p--,temp++)
{
System.out.println("");
i=x.length-1;
int k=i;
for(j=temp;j<=last;j++,k--)
{
System.out.print(x[k][j]);
System.out.print(" ");
}
}
}
}

Code faster with unnecessary conditional?

I have the following java function, to count common elements in two sorted arrays. Note the line with the question mark.
public static int overlap(int[] a, int[] b)
{
int i = 0, j = 0;
int res = 0;
while(i < a.length && j < b.length)
{
if(a[i] > b[j])
j ++;
else if(a[i] < b[j])
i ++;
else if(a[i] == b[j]) // ?
{
res ++;
i ++;
j ++;
}
}
return res;
}
Clearly, that last if-statement doesn't need to be there: at that point we know that the two values are equal. However, when I test the speed (I was checking whether the order of the checks made any difference), the method with the superfluous check is invariably faster than the one without (sometimes by a factor of two).
What is going on here? Some mysterious optimization? Am I overlooking something obvious? I'm using the stand compiler, version 1.8. I can't read bytecode, so I don't know what's going on under the hood.
Here is a full test class: https://gist.github.com/pbloem/1523283211454ec58ce9c5b45204eebd
Bytecode:
https://gist.github.com/pbloem/ce4f6758f0bb1424c155c26e83ca88a1
Possibly JIT swapping order of "if"s to get best performance but cannot swap order of just "else"(without an "if") with another "if" at the beginning, so when you added "if" after "else", it tried it as a first check, and if array overlapping is like %90, then it could keep that last "if" at the first place.
if(a[i] == b[j]) // say %70 probability after N iterations
{ // or less randomized branching
res ++;
i ++;
j ++;
}
else if(a[i] > b[j]) // %20 probability, medium branching
j ++;
else if(a[i] < b[j]) // %10, totally random branching, not predictable
i ++;
is possible when arrays ordering
a > b or b < a
are more randomized than arrays overlapping.
When there is if+if+else, JIT may not predict what you mean in that. By adding an equalty, you are elliminating many cases except the equation.
Could you please try with an ordered array and totally randomized array?
Or it is just helping cpu's branch predictor as #noahnu said in comments.
By using System.currentTimeMillis() you cant get exact elapsed time of program as sometimes it can be wrong due to JIT optimization. Try to use System.nanoTime().
Also make the variables used in time calculation as global variable for proper micro benchmark.
double sumWith = 0.0;
double sumWithout = 0.0;

The code after my for loop doesn't execute

I have a short program that creates an array of integers and removes non-primes:
public class Main {
public static void main(String[] args){
int[] nums = new int[100];
for (int i = 0; i < nums.length; ++i){
nums[i] = i + 1;
}
int j = 0;
while(j < nums.length){
System.out.print(nums[j]);
System.out.print(" ");
j++;
}
for (int n = 1; n < nums.length / 10; n++){
for (int p = n; p < nums.length; p += nums[n]){
if(p > n){
nums[p] = 0;
System.out.println("p"+nums[p]);
}
}
}
//this code doesn't execute
System.out.println("x");
}
}
The statement which is supposed to simply print "x" doesn't execute, nor does any other statement I put after the for loop. The program does not enter an infinite loop, so what's going on? I feel like this is something obvious that I'm just missing.
Edit: it was an infinite loop, I just didn't realize it.
In your p loop, on the second iteration, p > n is true and you set nums[p] to 0. From that point forward, p will never increase, because your incrementer is p += nums[n] and nums[n] is 0, and so your loop never terminates.
This sort of problem is best solved by using a debugger. Using a debugger is a fundamental skill for a programmer. With a debugger, you can step through statements, inspect variables, and see exactly what your code is doing. It's not an advanced technique, it's essential from Day 1 so you can correctly diagnose issues with your code. If you don't currently know how to use a debugger, stop what you're doing and learn to use one, it will be incredibly valuable and time-saving to you. There's almost certainly one built into your IDE.
Are you falling into a infinite loop? In the console press cmd+c or ctrl+c and see what that does. If the program stops it is a sign of a infinite loop.

Algorithm to check to output largest value in array or display if empty

I am trying to practice algorithms before i start my undergrad in computer science and i am struggling really bad to write algorithms. I understand them once i've been taught them and break them down but when I am trying to do my own, it fails miserable. I am trying a exercise question in a programming textbook, where i have an array and i have to output the largest value or if the array is empty, i have to display -1.
This was the best i can come up with but it still falls way short. Any pointers on what exactly I'm doing wrong.
for(i = 0;i < array.length-1;i++)
if(array[i] == 0){
empty = true;
n = -1;
System.out.println(n);
}else{
largest = array[0];
if(array[i] > largest){
largest = array[i];
System.out.println(array[i]);
}
}
I see that -1 displayed 10 times but i have found no solution for this and if the array is full, it provides me one then one value.
If you're struggling with algorithms, it helps sometimes not to look at them as algorithms but real-world problems.
Say you are in a shop buying cheese and your task is to pick a pack of cheese which has the latest expiration date. Now imagine the situation: standing at the cheese section looking for the best yummy cheese...
First, you look if there is any. If not, return empty handed.
If there are some packs, go through them looking for the best. You've got probably only one hand free, holding the basket in the other one, so...
Initially, pick the first cheese
Then go through the packs one by one. If you find cheese better than you have in your hand, put the one you're holding down and take the better one.
Now, let's put this to a programing language:
int[] cheeseExpirations = new int[] { ... };
if (cheeseExpirations.length == 0) {
System.out.println(-1); // no cheese :(
} else {
int myCheese = cheeseExpirations[0]; // take the first pack; better a sparrow in the hand than a pigeon on the roof...
for (int i = 0; i < cheeseExpirations.length; i++) { // idiomatic array iteration
int currentCheese = cheeseExpirations[i];
if (currentCheese > myCheese ) { // found a better one
myCheese = currentCheese; // just take it
}
}
System.out.println(bestCheese);
}
Is it clearer now? Like Richard Feynman said, using your imagination and examples is important:
I had a scheme, which I still use today when somebody is explaining something that I'm trying to understand: I keep making up examples.
For instance, the mathematicians would come in with a terrific theorem, and they're all excited. As they're telling me the conditions of the theorem, I construct something which fits all the conditions. You know, you have a set (one ball)-- disjoint (two balls). Then the balls turn colors, grow hairs, or whatever, in my head as they put more conditions on.
Finally they state the theorem, which is some dumb thing about the ball which isn't true for my hairy green ball thing, so I say "False!" [and] point out my counterexample.
You are checking the length of the array in each loop. This means it won't be checked unless the array has some object, which is just what we don't want.
But, in fact, you are not checking the array length:
if(array[i] == 0) tests if the item of array at index i is 0. To test the length of the array, you have to do if (array.length > 0). Remember you have to do this before the for loop, so it would be something like this:
if(array[i] == 0){
empty = true;
n = -1;
System.out.println(n);
}
for(i = 0;i < array.length-1;i++)
largest = array[0];
if(array[i] > largest){
largest = array[i];
System.out.println(array[i]);
}
}
But, in each loop you are reassigning largest to the first array element, which breaks the algorithm. So you must move that line before the for loop.
if(array[i] == 0){
empty = true;
n = -1;
System.out.println(n);
}
largest = array[0];
for(i = 0;i < array.length-1;i++)
if(array[i] > largest){
largest = array[i];
System.out.println(array[i]);
}
}
A few things:
if(array[i] == 0)
does not check if the array is empty, it checks if the value stored at index i of the array is equal to zero. You probably want something like:
if(array != null && array.length == 0) {
return -1;
}
before the for loop executes.
The rest of your code looks close. The print statement inside of the else clause is unnecessary. You just need to return the value of largest after the for loop executes.
This code is rather strange in general. Why do you consider an array empty as soon as you reach an element that is 0? And why do you continue search, if the array is empty? Last but not least: why do you ignore the last element in the array?
There are plenty of solutions for this that are a lot simpler:
Without any java-api:
if(array.length == 0)
return -1;
int max = Integer.MIN_VALUE;
for(int i = 0 ; i < array.length ; i++)
if(max < array[i])
max = array[i];
return max;
A lazy solution using Arrays.sort() (not exactly elegant, but short)
Arrays.sort(array);
return array[array.length - 1];
Using java8:
return Arrays.stream(array).min((a , b) -> new Integer(a).compareTo(b)).orElse(-1);
Lets take a look at your code
for(i = 0;i < array.length-1;i++)//You will never reach the last number
if(array[i] == 0){//Here you check if the first item equals zero. Gives error if there is no first item.
empty = true;//why do you need this, you never use it.
n = -1;
System.out.println(n);
}else{
largest = array[0];//Why setting largest, do dont know if it is actually bigger
if(array[i] > largest){
largest = array[i];
System.out.println(array[i]);
}
}
Improved version:
largest = -1;//set it by default
for(i = 0;i < array.length;i++)//if length is 10 iMax = 9, which is the tenth item.
if(array[i]>largest){//if larger set the new value
largest = array[i];
}
}
System.out.println(largest);//print the largest number.
if(array.length == 0){
empty = true;
n = -1;
System.out.println(n);
}else{
largest = array[0];
for(i = 1; i < array.length; i++)
if(array[i] > largest){
largest = array[i];
}
System.out.println(largest);
}
First what i did is check if the array is empty. If it is then skip the else and output the -1. If the array is not empty set the largest to the first element and then loop through all other elements. Noticed I changed i = 1 because element 0 is already the largest. Also I removed the -1 to the array length because i will stop 1 before the length (which will be the last index of final element). Finally I moved the print of the largest value outside of the if statement and for loop so that it only gets printed once at the very end.
First check if the array is empty
if(array != null && array.length == 0) {
If it is print -1
System.out.println(-1 + "");
}
Now you are ready to go through the array. But before you do create a variable that will keep track of the largest value. I set it to the first element in the array (since we know that it has at least one element since we already determined that it isn't empty)
else {
int largest = array[0];
Then, loop through the array
for(i = 0;i < array.length-1;i++) {
Get every element one at a time using i to access the ith element
int current = array[i];
Then compare it to the largest. If it's greater than the largest so far, save it as the largest.
if (current>largest) {
current = largest;
}
Keep doing that until finished looping through the array
}
Then print out the largest
System.out.println(largest + "");
}

Categories