When I run this class I am not getting a the sum/average. I am getting an error listed below. I am not sure why I am getting it. I am a student very new at this.
public class DebugEight2
{
public static void main(String[] args)
{
int[] someNums = {4,17,22,8,35};
int tot;
int x;
int sum = 0;
for(x = 0; x <= someNums.length; ++x)
tot = someNums[x];
sum = sum + someNums[x];
System.out.println("Sum is " + sum);
System.out.println("Average is " + sum * 1.0 / someNums.length);
}
}
Error:
"Exception in thread "main" java.lang.ArrayIndexOutofBoundsException: 4 at DebugEight1.main (DebugEight1.java:17)"
Array index starts from 0 and goes till it's length -1 See that <= in your for loop. So this for(x = 0; x <= someNums.length; ++x) should be for(x = 0; x < someNums.length; ++x)
Problem is your loop condition, remove the equal sign like this
for(x = 0; x < someNums.length; ++x)
You should also wrapp the code which is supposed to be inside the loop into brackets (without them, only the next line after the for loop condition will be executed)
for(x = 0; x < someNums.length; ++x) {
tot = someNums[x];
sum = sum + someNums[x];
}
first you should remove = from <= someNums.length; i will look like this < someNums.length; and then change ++x to x++ if you put ++x when loop starts it will check condition < someNums.length; and then pluse one +1 to x and so on, currently your array length is 5 when loop goes on last increment its size is 6 and there is no item on 6 location thats why it is throwing exception so you have you change it ++x to x++
public class DebugEight2
{
public static void main(String[] args)
{
int[] someNums = {4,17,22,8,35};
int tot;
int x;
int sum = 0;
for(x = 0; x <someNums.length; x++) /// just change here
tot = someNums[x];
sum = sum + someNums[x];
System.out.println("Sum is " + sum);
System.out.println("Average is " + sum * 1.0 / someNums.length);
}
}
Arrays are zero based and their indices go from 0 to someNums.length -1
You not only exceeding the bounds of the array but the variable sum is being assigned outside of scope of the loop. Adjust the upper bounds of the array and add braces:
for (x = 0; x < someNums.length; x++) {
tot = someNums[x];
sum = sum + someNums[x];
}
Hope this helps
You want to iterate while x is lesser than someNums.length; since max index in array is arraysLength - 1, so change x <= someNums.length; to x < someNums.length; in for loop
There is no need for tot (I assume it should store total numbers) variable because you already have someNums.length which represents how many numbers you summed. BTW you already are calculating avg using sum and someNums.length. So you can safely remove
tot = someNums[x];
from your code.
What you did is you looped beyond the scope of the array. Try doing someNums.length, you will get the number 5.
Going to your for loop we now know that it starts at 0 and increments until it gets to 5. And the for loop is traversing over the array and is pointing at the positions in your array.
So let's traverse through your loop.
At x = 0, someNums[x] = 4.
At x = 1, someNums[x] = 17,
At x = 2, someNums[x] = 22,
At x = 3, someNums[x] = 8,
At x = 4, someNums[x] = 35,
As you can see, your array has now ended, you no longer have any more elements to traverse over. But we have previously stated that your for loop increments until it gets to 5.
So at x = 5, someNums[x] will have to give you an error since you are pointing at a position and trying to retrieve information from that position that essentially does not exist.
There are two ways to solve your problem:
You change the loop to for(int x = 0; x < someNums.length; x++)
You change the loop to for(int x = 0; x <= someNums.length - 1; x++)
These will solve your problem because they will stop your loop at 4 and not at 5, therefore you will no longer receive an error.
Related
I'm working on making a program to roll 4 6 sided dice and do some simple math and logic with them. I was running a very rough draft of the program and started to notice that the number of rolls would be inconsistent. In particular I would sometimes wont get the smallest value or get two
If looked around for a solution online to no avail. I even copied the code from other examples on how to find the smallest value
public class test {
private static int dice(int s) {
int num = 0;
Random random = new Random();
num = random.nextInt(s);
num = num + 1;
return num;
}
public static void main(String[] args) {
List<Integer> rolls = new ArrayList<Integer>();
for (int i = 0; i != 4; i++) {
rolls.add(dice(6));
}
for (Integer roll : rolls) {
System.out.println(roll);
}
int min = rolls.get(0);
int index = 0;
for (int x = 0; x < rolls.size(); x++) {
if (rolls.get(x) < min) {
min = rolls.get(x);
index = x;
System.out.println("Smallest: " + min);
}
}
int sum = 0;
for (int x : rolls) {
sum += x;
}
System.out.println("Sum:" + sum);
}
}
This should generate 4 rolls of 6 sided dice. Then it should find the smallest value print that, then calculate the sum and print it
Check out this bit of code:
int min = rolls.get(0);
int index = 0;
for(int x = 0; x<rolls.size(); x++){
if(rolls.get(x) < min){
min=rolls.get(x);
index = x;
System.out.println("Smallest: " + min);
}
}
What happens if rolls.get(0); is your minimum roll? In that case, if(rolls.get(x) < min) will always be false, and you'll never print "Smallest...".
Also note that every time you find a roll that is smaller than the last one you looked at, you print out "Smallest..." again, so if you have multiple dice in descending size, you'll print that line out multiple times.
Set your initial min value to 7, so you're guaranteed to have a min value that is smaller than the initial state. And then, instead of printing inside your loop, save the min and print "Smallest..." once the loop is finished:
// Be aware that this code doesn't work correctly if your List is empty.
int min = 7; // You could also set this to rolls.get(0) and start your loop at 1
for (int x = 0; x < rolls.size(); x++) {
if (rolls.get(x) < min) {
min = rolls.get(x);
}
}
System.out.println("Smallest: " + min);
(I also removed index, because it's not being used anywhere in your code).
If you wanted to be a bit more modern with this (and also more robust), you could also do:
rolls.stream()
.min(Integer::compareTo)
.ifPresent(min -> System.out.println("Smallest: " + min));
That will handle the case of rolls being empty by just not printing anything.
i have to make a program that prints out the elements of an array filled with random numbers backwards but it also prints out a zero after my variables? i think it has something to do with my for-loops but i get a java.lang.ArrayIndexOutOfBoundsExceptionerror any time i try to change them.
edit: i also noticed that the first printed element is always zero. i don't really see it as a problem but what could be causing that?
import java.util.*;
public class EZD_printBackwards
{
static int vars[] = new int[10];
static int backwards()
{
Random rand = new Random();
int bkwds = vars[0];
for (int a = 0; a < 10; a++)
{
vars[a] = rand.nextInt(100)+1;
}
for (int x = 10; x > 0; x--)
{
System.out.println("Element " + x + " is " + vars[x] );
}
return bkwds;
}
public static void main(String Args[])
{
int option;
Scanner kbReader = new Scanner(System.in);
do
{
System.out.println(backwards());
System.out.print("Type 1 to run again. Type 0 to end the program.");
option = kbReader.nextInt();
while(option !=1 && option !=0)
{
if (option != 1 && option != 0)
{
System.out.print("Please enter 1 to run again or 0 to end the program.");
option = kbReader.nextInt();
}
}
}while(option==1);
System.out.println("");
}
}
In your example, vars is size 10. The second for loop starts at index x = 10 which is greater than the last index of vars because array index starts at zero. To fix the issue, you should use this condition in your for loop:
for (int x = vars.length -1; x >= 0; x--)
{
System.out.println("Element " + x + " is " + vars[x] );
}
You have two problems:
FIRST => For loop out of bounds
you want to go through 10 elements, therefore your
for (int x = 10; x > 0; x--)
should be
for (int x = 9; x >= 0; x--)
0..9 is 10 elements and the same things goes for
for (int a = 0; a < 10; a++)
to
for (int a = 0; a < 9; a++)
SECOND ==> 0 at the end
That's because you do
System.out.println(backwards());
instead of
backwards();
you are returning the value of "bkwds", and you are initializing "bkwds" with vars[0] , and i guess in java the compiler initialize all the values of an array with 0 ,
in other words your probleme is in System.out.println(backwards());
remove it with
backwards();
and it should work !
EDIT
your look is out of bound either replace it with this
for (int a = 0; a < 10; a++)
or
do this
for (int a = 9; a > 0; a--)
The range of your Array is from 0 up to and including 9. Your for loop, however, is starting from 10 and coming down to index 1. It should start from 9 and comes down to index zero. This, however, does not explain printing random 0! The reason for these zeros is you have an int bkwds which youb set to vars[0] at the beginning of your function. But, since it is not initialized, it will be set to 0 (the default for int) In your main, you call the function in a print statement, which I suppose keeps printing that falsely, useless initialized variable that you return :)
As arrays are indexed from zero, change to
System.out.println("Element " + x + " is " + vars[x-1] );
output
Element 10 is 31
Element 9 is 63
Element 8 is 82
Element 7 is 46
Element 6 is 67
Element 5 is 24
Element 4 is 3
Element 3 is 27
Element 2 is 37
Element 1 is 13
edit
And change this
System.out.println(backwards());
to
backwards();
As the return value of this method is useless and not used, change this method to return void
I'm new to Java.
I can't seem to understand why these two codes produce different outputs.
Please explain this to me.
What is the difference of y<=x; and y<=5;. As you can see the x is 5 too, I don't understand why I get different outputs.
for (int x = 0; x < 5; x++) {
for (int y = 1; y <=x ; y++) {
System.out.print("x");
}
for (int g = 4; g >= x; g--) {
System.out.print("*");
}
System.out.println();
}
Output:
*****
x****
xx***
xxx**
xxxx*
Code:
for (int x = 0; x < 5; x++) {
for (int y = 1; y <= 5; y++) {
System.out.print("x");
}
for (int g = 4; g >= x; g--) {
System.out.print("*");
}
System.out.println();
}
Output:
xxxxx*****
xxxxx****
xxxxx***
xxxxx**
xxxxx*
Basically the main difference is this line:
for(int y=1; y<=x; y++)
resp.
for(int y=1; y<=5; y++)
The number of times the loop is executed is different. Namely in the first case it is variable (so the number of 'x' increases), in the second case it is fixed (5 'x' printed each time).
(edit: typo)
xstarts at 0 so the first iteration has the condition y<=0, the second will have y<=1 and so on .. till y<=5
While the second one will have y<=5in every iteration, thats why you get xxxxx in every line.
In the first code you print x times the "x" String in each row.
for(int y=1; y<=x; y++) {
System.out.print("x");
}
BTW, it prints the following (which is different than what you claim in the question):
*****
x****
xx***
xxx**
xxxx*
In the second code you print 5 times the "x" String in each row.
for(int y=1; y<=5; y++) {
System.out.print("x");
}
As you can see the x is = 5 too
No, x iterates from 0 to 4, so in each iteration of the outer for loop, it has a different value.
In your first code your for(int y=1; y<=x; y++) for iterations of outer for loop is -
for(int y=1;y<=0;++y) (for first iteration of outer loop)
for(int y=1;y<=1;++y) (for second iteration of outer loop)
for(int y=1;y<=2;++y) (for third iteration of outer loop)
for(int y=1;y<=3;++y) (for fourth iteration of outer loop)
for(int y=1;y<=4;++y) (for fifth iteration of outer loop)
But in your second code its always -
for(int y=1; y<=5; ++y)
for all iterations of outer for loop.
It is very simple the will run for 5 time times and every itreation its value will be increamented by 1 i.e. from 0 to 4.
So in first loop inner loop will have the condition like this:
for (int y = 1; y <= x; y++) {
System.out.print("x");
}
But since in first loop the value of x is 0 hence it literally means:
for (int y = 1; y <= 0; y++) {
System.out.print("x");
}
But in the last iteartion of outer loop the value of x is 4 hence this is equivalent to:
for (int y = 1; y <= 4; y++) {
System.out.print("x");
}
So it iterates 4 times.
In your first example y is first less than x = 1 and during the next iteration it will be less x= 2 ... Because x values changes with your first for loop.
For the second example however you state that y have to be less than 5 which doesn't change at all.
They are different because in the first case your x varies from 0 to 4 based on :
for(int x=0; x<5; x++)
In the case second case x is fixed at 5.
I have replaced your two inner for loops with a new stringRepeat function. It might be easier to understand this way.
public class ForLoopStarsAndCrosses {
public static void main(String[] args) {
/// the total length ot the x's and stars
final int length = 5;
// start with 1 x until one less than the length (in this case 4)
for(int x = 1; x < length; x++) {
// the number of stars equals the total length minus the number of x's
final int nbStars = length - x;
// add the x's and the stars
final String output = stringRepeat("x", x) + stringRepeat("*", nbStars);
System.out.println(output);
}
System.out.println();
}
/** Repeat the string s n times */
private static String stringRepeat(String s, int n) {
String result = "";
for (int i = 0; i < n; i += 1) {
result += s;
}
return result;
}
}
Firstly, you should understand the difference between value and variable. Value is a constant as you write 5 but variable can be changeable.
For your question, first code and first round:
x = 1, y<= 1 and output: x
for(int y=1; y<=x; y++){
System.out.print("x");
}
but for the second code and first round:
y<=5 so output is: xxxxx
for(int y=1; y<=5; y++){
System.out.print("x");
}
it is very simple.
The purpose of loops (can be for, while, do-while) is that, how many number of times the same set of statements to be executed under a specific condition. "for" is a definite loop where there will be an index starting with an integer, keep increment it until the condition is achieved. "while" is a indefinite loop where there is no index and it will be executed until the condition is achieved. "do-while" is a loop similar to "while", which will be executed atleast once and then validates the condition for the next iteration.
Based on the above details,
for(int x=0; x<5; x++){
for(int y=1; y<=x; y++){
for(int x=0; x<5; x++){
for(int y=1; y<=5; y++){
The diff between these two conditions is that,
First condition:
In the first iteration, value of x is 0 and for the second loop y is started with 1.
Here when it compares the value with x which is 0 and 1<=0 which is false, this condition is failed and the statements under Y will not be executed and the control will go back control of x.
Second condition:
In the first iteration, value of x is 0 and for the second loop y is started with 1.
Here when it compares the value with 5, 1<=5 which is true, this condition is valid and the statements under Y will be executed and the control will go back control of x until y becomes 6 and condition checked is 6<=5 which is false, this condition is failed and the statements under Y will not be executed and the control will go back control of x
Note: Due to low reputation, I can't add comments and had to contribute this as an answer. Don't downvote this, instead suggest corrections by comment on the same.
this is the question, and yes it is homework, so I don't necessarily want anyone to "do it" for me; I just need suggestions: Maximum sum: Design a linear algorithm that finds a contiguous subsequence of at most M in a sequence of N long integers that has the highest sum among all such subsequences. Implement your algorithm, and confirm that the order of growth of its running time is linear.
I think that the best way to design this program would be to use nested for loops, but because the algorithm must be linear, I cannot do that. So, I decided to approach the problem by making separate for loops (instead of nested ones).
However, I'm really not sure where to start. The values will range from -99 to 99 (as per the range of my random number generating program).
This is what I have so far (not much):
public class MaxSum {
public static void main(String[] args){
int M = Integer.parseInt(args[0]);
int N = StdIn.readInt();
long[] a = new long[N];
for (int i = 0; i < N; i++) {
a[i] = StdIn.readLong();}}}
if M were a constant, this wouldn't be so difficult. For example, if M==3:
public class MaxSum2 {
public static void main(String[] args){
int N = StdIn.readInt(); //read size for array
long[] a = new long[N]; //create array of size N
for (int i = 0; i < N; i++) { //go through values of array
a[i] = StdIn.readLong();} //read in values and assign them to
//array indices
long p = a[0] + a[1] + a[2]; //start off with first 3 indices
for (int i =0; i<N-4; i++)
{if ((a[i]+a[i+1]+a[1+2])>=p) {p=(a[i]+a[i+1]+a[1+2]);}}
//if sum of values is greater than p, p becomes that sum
for (int i =0; i<N-4; i++) //prints the subsequence that equals p
{if ((a[i]+a[i+1]+a[1+2])==p) {StdOut.println((a[i]+a[i+1]+a[1+2]));}}}}
If I must, I think MaxSum2 will be acceptable for my lab report (sadly, they don't expect much). However, I'd really like to make a general program, one that takes into consideration the possibility that, say, there could be only one positive value for the array, meaning that adding the others to it would only reduce it's value; Or if M were to equal 5, but the highest sum is a subsequence of the length 3, then I would want it to print that smaller subsequence that has the actual maximum sum.
I also think as a novice programmer, this is something I Should learn to do. Oh and although it will probably be acceptable, I don't think I'm supposed to use stacks or queues because we haven't actually covered that in class yet.
Here is my version, adapted from Petar Minchev's code and with an important addition that allows this program to work for an array of numbers with all negative values.
public class MaxSum4 {
public static void main(String[] args)
{Stopwatch banana = new Stopwatch(); //stopwatch object for runtime data.
long sum = 0;
int currentStart = 0;
long bestSum = 0;
int bestStart = 0;
int bestEnd = 0;
int M = Integer.parseInt(args[0]); // read in highest possible length of
//subsequence from command line argument.
int N = StdIn.readInt(); //read in length of array
long[] a = new long[N];
for (int i = 0; i < N; i++) {//read in values from standard input
a[i] = StdIn.readLong();}//and assign those values to array
long negBuff = a[0];
for (int i = 0; i < N; i++) { //go through values of array to find
//largest sum (bestSum)
sum += a[i]; //and updates values. note bestSum, bestStart,
// and bestEnd updated
if (sum > bestSum) { //only when sum>bestSum
bestSum = sum;
bestStart = currentStart;
bestEnd = i; }
if (sum < 0) { //in case sum<0, skip to next iteration, reseting sum=0
sum = 0; //and update currentStart
currentStart = i + 1;
continue; }
if (i - currentStart + 1 == M) { //checks if sequence length becomes equal
//to M.
do { //updates sum and currentStart
sum -= a[currentStart];
currentStart++;
} while ((sum < 0 || a[currentStart] < 0) && (currentStart <= i));
//if sum or a[currentStart]
} //is less than 0 and currentStart<=i,
} //update sum and currentStart again
if(bestSum==0){ //checks to see if bestSum==0, which is the case if
//all values are negative
for (int i=0;i<N;i++){ //goes through values of array
//to find largest value
if (a[i] >= negBuff) {negBuff=a[i];
bestSum=negBuff; bestStart=i; bestEnd=i;}}}
//updates bestSum, bestStart, and bestEnd
StdOut.print("best subsequence is from
a[" + bestStart + "] to a[" + bestEnd + "]: ");
for (int i = bestStart; i<=bestEnd; i++)
{
StdOut.print(a[i]+ " "); //prints sequence
}
StdOut.println();
StdOut.println(banana.elapsedTime());}}//prints elapsed time
also, did this little trace for Petar's code:
trace for a small array
M=2
array: length 5
index value
0 -2
1 2
2 3
3 10
4 1
for the for-loop central to program:
i = 0 sum = 0 + -2 = -2
sum>bestSum? no
sum<0? yes so sum=0, currentStart = 0(i)+1 = 1,
and continue loop with next value of i
i = 1 sum = 0 + 2 = 2
sum>bestSum? yes so bestSum=2 and bestStart=currentStart=1 and bestEnd=1=1
sum<0? no
1(i)-1(currentStart)+1==M? 1-1+1=1 so no
i = 2 sum = 2+3 = 5
sum>bestSum? yes so bestSum=5, bestStart=currentStart=1, and bestEnd=2
sum<0? no
2(i)-1(currentStart)+1=M? 2-1+1=2 so yes:
sum = sum-a[1(curentstart)] =5-2=3. currentStart++=2.
(sum<0 || a[currentStart]<0)? no
i = 3 sum=3+10=13
sum>bestSum? yes so bestSum=13 and bestStart=currentStart=2 and bestEnd=3
sum<0? no
3(i)-2(currentStart)+1=M? 3-2+1=2 so yes:
sum = sum-a[1(curentstart)] =13-3=10. currentStart++=3.
(sum<0 || a[currentStart]<0)? no
i = 4 sum=10+1=11
sum>bestSum? no
sum<0? no
4(i)-3(currentStart)+1==M? yes but changes to sum and currentStart now are
irrelevent as loop terminates
Thanks again! Just wanted to post a final answer and I was slightly proud for catching the all negative thing.
Each element is looked at most twice (one time in the outer loop, and one time in the while loop).
O(2N) = O(N)
Explanation: each element is added to the current sum. When the sum goes below zero, it is reset to zero. When we hit M length sequence, we try to remove elements from the beginning, until the sum is > 0 and there are no negative elements in the beginning of it.
By the way, when all elements are < 0 inside the array, you should take only the largest negative number. This is a special edge case which I haven't written below.
Beware of bugs in the below code - it only illustrates the idea. I haven't run it.
int sum = 0;
int currentStart = 0;
int bestSum = 0;
int bestStart = 0;
int bestEnd = 0;
for (int i = 0; i < N; i++) {
sum += a[i];
if (sum > bestSum) {
bestSum = sum;
bestStart = currentStart;
bestEnd = i;
}
if (sum < 0) {
sum = 0;
currentStart = i + 1;
continue;
}
//Our sequence length has become equal to M
if (i - currentStart + 1 == M) {
do {
sum -= a[currentStart];
currentStart++;
} while ((sum < 0 || a[currentStart] < 0) && (currentStart <= i));
}
}
I think what you are looking for is discussed in detail here
Find the subsequence with largest sum of elements in an array
I have explained 2 different solutions to resolve this problem with O(N) - linear time.
I have a 36x25 grid of nodes that I wish to search through all triangular numbers from the corner opposite of the hypotenuse. Here's psuedocode for what I was considering, but this method only works until it hits the next corner of the grid, and I'm sure there is a much simpler way to do this recursively, I just am having difficulty figuring it out.
for(int iteration; iteration < maxDistance(49); iteration++)
{
int xAdd = iteration;
int yAdd = 0;
while(xAdd != 0)
{
checkStuff(nodeGrid[x+xAdd][y+yAdd]);
xAdd--;
yAdd++;
}
}
What I want program to do:
[0][1][2][3][4][5]
[1][2][3][4][5][6]
[2][3][4][5][6][7]
[3][4][5][6][7][8]
[4][5][6][7][8][9]
check in this order. So first check all tiles with value 0, then 1 and so on.
Note: in this case my function will only work up until the 4th set up tiles. Any further and it will reach out of bounds.
/**
* Only works for rectangular arrays
*/
public void iterateOver(Node[][] a){
int x_dim = a[0].length;
int y_dim = a.length;
for (int i = 0; i < x_dim + y_dim - 1; i++){
int x, y;
if (i < x_dim){
x = i;
y = 0;
}
else{
x = x_dim - 1;
y = i - x_dim + 1;
}
for (;x >=0 && y < y_dim; y++, x--){
doStuff(a[y][x]);
}
}
}
How it works
Picture your rectangular array:
[0][1][2][3][4][5]
[1][2][3][4][5][6]
[2][3][4][5][6][7]
[3][4][5][6][7][8]
[4][5][6][7][8][9]
There are clearly 6 columns and 5 rows (or 6 x values and 5 y values). That means that we need to do 6 + 5 - 1 iterations, or 10. Thus, the for (int i = 0; i < x_dim + y_dim - 1; i++). (i is the current iteration, measured from 0).
We start by columns. When i is less than the x dimension, x = i and y = 0 to start with. x is decremented and y is incremented until x is less than zero or y is equal to the y dimension. Then, we do a similar thing down the right hand side.