Using an if statement with arrays - java

At the comment step 4 I am trying to add the current array element to sum, compare the current array element to max_test and if it is larger, save it in the variable max_test. and compare the current element to min_test, if it is smaller save it in min_test. HOWEVER i keep on getting the errors
Grades5.java:55: error: bad operand types for binary operator '>'
if (grades[r] > grades[max_test])
^
first type: int[]
second type: int[]
Grades5.java:57: error: bad operand types for binary operator '<'
if (grades[r] < grades[min_test])
^
first type: int[]
second type: int[]
Grades5.java:59: error: bad operand types for binary operator '+'
sum += grades[r];
^
first type: int
second type: int[]
3 errors
The code:
import java.util.Scanner;
public class Grades5
{
public static void main(String[] args)
{
int[][] grades = {
{ 87, 96, 100},
{ 68, 75, 72},
{ 99, 100, 95},
{100, 96, 70},
{ 75, 60, 79},
};
int how_many_grades = grades.length * grades[0].length;
// -----------------
// Output the grades
// -----------------
System.out.print(" ");
for (int i = 0; i < grades[0].length; i++)
System.out.print("Test " + (i + 1) + " ");
System.out.println("Average");
for (int r = 0; r < grades.length; r++)
{
int sum = 0; // Sum of one student's tests
// -------------------
// Process one student
// -------------------
System.out.print("Student " + (r + 1) + " ");
for (int c = 0; c < grades[r].length; c++)
{
System.out.printf("%6d ", grades[r]); // Step 1
//sum += grades[c]; // Step 2
}
System.out.printf("%7.2f\n", (double)sum / grades[r].length);
}
// ----------------
// Output a summary
// ----------------
int max_test, // Maximum test score
min_test, // Minimum test score
sum = 0; // Sum of all student tests
max_test = min_test = grades[0][0]; // Step 3
for (int r = 0; r < grades.length; r++)
{
// -------------------
// Process one student
// -------------------
for (int c = 0; c < grades[r].length; c++)
{
// Step 4
if (grades[r] > grades[max_test])
max_test = c;
if (grades[r] < grades[min_test])
min_test = c;
sum += grades[r];
}
}
System.out.println("Highest test score: " + max_test);
System.out.println("Lowest test score: " + min_test);
System.out.printf("Average test score: %.1f\n",
(double)sum / how_many_grades);
}
}

Your problem is that grades[r] is not an integer. It is an array of integers. You'd have to address two indices
sum += grades[i][j];
in order to get rid of the compilation error.
It appears to be the same for the other errors. In general you can imagine it as follows:
grades[1] -> { 87, 96, 100}
grades[2] -> { 68, 75, 72}
and
grades[1][1] -> 87;
grades[1][2] -> 96;
etc ..

If the grades for one test are horizontal in your array, then you only need two loops, not three.
for (int test = 0; test < grades.length; test++) {
System.out.print("Test " + (test + 1) + " ");
System.out.println("Average");
int sum = 0; // Sum all grades on this test
for (int student = 0; student < grades[test].length; student++)
{
System.out.print("Student " + (student + 1) + " ");
sum += grades[student];
}
System.out.println();
System.out.printf("%7.2f\n", (double)sum / grades[test].length);
}

You cannot use operator > to compare int[] types. Java doesn't support operator overloading. Those relational operators (>, <, >=, <=) are applied to numeric primitive data types only.
Do you mean something like grades[r][c] > grades[r][max_test] or grades[r][c] < grades[r][min_test]?

This works because grades needs 2 parts when comparing
if (grades[r][c] > max_test)
max_test = grades[r][c];
if (grades[r][c] < min_test)
min_test = grades[r][c];
sum += grades[r][c];

Related

I want to make arithmetic mean for first half and then for the second half of array

I made the arithmetic mean for whole the sorted array, but now i want to make the arithmetic mean for first sorted half and second sorted half of array.
Ex: My array is: 77, 99, 44, 55, 22, 88, 11, 00, 66, 33.
My code make in first place the sort.
The outcome of program is: 00 11 22 33 44 55 66 77 88 99.
Now i want to make the mean for first half:
00 11 22 33 44 and print it.
Then i want to make the mean for the second half:
55 66 77 88 99 and print it.
public class Array {
private double[] a;
private int NrElmts;
public Array(int max)
{ a = new double[max];
NrElmts = 0;
}
public void elements(double value)
{ a[NrElmts] = value;
NrElmts++;
}
public void print()
{ for(int j=0; j<NrElmts; j++)
System.out.print(a[j] + " ");
System.out.println("");
}
public void selectionSort()
{
int out, in, min;
for(out=0; out< NrElmts -1; out++)
{ min = out;
for(in=out+1; in< NrElmts; in++)
if(a[in] < a[min] )
min = in;
invertPositions(out, min); }
}
private void invertPositions(int one, int two)
{ double temp = a[one];
a[one] = a[two];
a[two] = temp;
}
public void mean()
{
int i;
double sum = 0;
for(i = 0; i < NrElmts; i++) {
sum+=a[i];}
double medie = sum/NrElmts;
System.out.format("Mean is: %.1f", mean);
System.out.println("");
}
}
Try this
public void firstHalfMean(){
int i;
double sum = 0;
int numberOFElements = NrElmts/2;
for (i = 0; i < NrElmts/2; i++) { // take sum only till half.
sum += a[i];
}
double mean = sum / numberOFElements; // sum/half the elements
System.out.format("Mean is: %.1f", mean);
System.out.println("");
}
public void secondHalfMean(){
int i;
double sum = 0;
int numberOFElements = NrElmts % 2 == 0 ? NrElmts/2 : NrElmts/2 + 1; // If odd, this second array will contain one more element.
for (i = NrElmts/2; i < NrElmts; i++) { // take sum for the next half
sum += a[i];
}
double mean = sum / numberOFElements; // sum/half elements (half + 1) in case of odd length.
System.out.format("Mean is: %.1f", mean);
System.out.println("");
}
To calculate the mean for 9, 2 and 7 you have to firstly add them all up, which equals 18 and then divide by how many there are - so 18 / 3 which is 6.
Although, you will have to account for the possibility of an odd list - if there's an odd amount of elements, say for example 1, 2, 3 the middle point of 3 - is 1.5 - and if you're iterating through indexes the iterative variable will count the middle point as 1. So it's a bit tricky, not sure what you'd want to do.Consider the following code though - it does exactly what you want, but with odd list sizes, it will just divide by a decimal value
LinkedList<Integer> numbers = new LinkedList<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);
numbers.add(40);
int size = numbers.size();
int iterativeHalf = size / 2;
float meanHalf = (float) size / 2;
float lowerMean = 0;
float upperMean = 0;
for (int i = 0; i < size; i++) {
int realRef = i + 1;
Integer value = numbers.get(i);
if (realRef > iterativeHalf) { //Should be calculating upper mean
if (upperMean == 0) { //if lowerMean is just a running total, not divided yet to get the mean
System.out.println("the lower mean for numbers is " + lowerMean + " / " + meanHalf);
lowerMean = (lowerMean) / meanHalf; //add last value + divide to set it to the mean
}
System.out.println("upper mean = " + upperMean + " + " + value + " = " + (upperMean + value));
upperMean = upperMean + value; //keep the upper values up total going
} else {
System.out.println("lower mean = " + lowerMean + " + " + value + " = " + (lowerMean + value));
lowerMean = lowerMean + value; //keep adding the lower halfs values up
}
}
//When it breaks, must divide upperMean by size to get mean
System.out.println("the upper mean for numbers is " + upperMean + " / " + meanHalf);
upperMean = (upperMean) / meanHalf;
System.out.println(" ");
System.out.println("FINAL lower mean = " + lowerMean);
System.out.println("FINAL upper mean = " + upperMean);
Output is:
lower mean = 0.0 + 10 = 10.0
lower mean = 10.0 + 20 = 30.0
the lower mean for numbers is 30.0 / 2.0
upper mean = 0.0 + 30 = 30.0
upper mean = 30.0 + 40 = 70.0
the upper mean for numbers is 70.0 / 2.0
FINAL upper mean = 35.0
FINAL lower mean = 15.0
This, for a [10, 20, 30, 40] will yield the output shown above but essentially (10+20)/2 as the lower mean and (30+40)/2 for the upper mean.
For [10, 20, 30, 40, 50] will yield (10 + 20) / 2.5 the lower mean and (30+40+50)/2.5 for the upper mean
Only take sum of half the array. Give one more element to your second or first half in case if your array size is odd.
public void firstHalfMean(){
int i;
double sum = 0;
int numberOFElements = NrElmts/2;
for (i = 0; i < NrElmts/2; i++) { // take sum only till half.
sum += a[i];
}
double mean = sum / numberOFElements; // sum/half the elements
System.out.format("Mean is: %.1f", mean);
System.out.println("");
}
public void secondHalfMean(){
int i;
double sum = 0;
int numberOFElements = NrElmts % 2 == 0 ? NrElmts/2 : NrElmts/2 + 1; // If odd, this second array will contain one more element.
for (i = NrElmts/2; i < NrElmts; i++) { // take sum for the next half
sum += a[i];
}
double mean = sum / numberOFElements; // sum/half elements (half + 1) in case of odd length.
System.out.format("Mean is: %.1f", mean);
System.out.println("");
}
Since you already have way to make mean for entire array, all you need to do is find mid position of array and then run from and to that point.
In your example: NrElmts is 10, so divide your NrElmnts by 2, so you can get mean for 1 to 5, and then 6 to 10 both 5 each.
Think about situation where you have odd number of elements in array, how do u want to do it, whether in first array or second. let me know if this need help as well.
Steps:
1) create a new variable say a1 to NrElmts/2, and go with your mean function from 1 to a1
2) go from a1+1 to NrElmnts
Let me know if you need any help.

Program works with for loops but not with while loops?

EDIT: I have edited in the output of the program.
The program calls for estimating a given value mu. User gives a value of mu, and also provides four different numbers not equal to 1 (call them w, x, y, z). The program then attempts to find an estimate of the mu value by using the de Jaeger formula.
If I enter values of 238,900 for mu, and w=14, x=102329, y=1936, z=13
then the value of estimate should be 239,103, and the error about .08%.
My code with the for loops works perfectly fine:
public static void main(String[] args) {
SimpleReader in = new SimpleReader1L();
SimpleWriter out = new SimpleWriter1L();
double bestEstimate = 0; // used to hold the estimate the computer while return
double bestA = 0, bestB = 0, bestC = 0, bestD = 0; // to hold the values of the exponents for each number
double[] exponents = { -5, -4, -3, -2, -1, -1.0 / 2.0, -1.0 / 3.0,
-1.0 / 4.0, 0, 1.0 / 4.0, 1.0 / 3.0, 1.0 / 2.0, 1, 2, 3, 4, 5 };
double[] userNumbers = new double[4];
double mu = getPositiveDouble(in, out);
for (int i = 0; i < 4; i++) {
userNumbers[i] = getPositiveDoubleNotOne(in, out);
}
for (int a = 0; a < exponents.length; a++) {
double a1 = Math.pow(userNumbers[0], exponents[a]);
for (int b = 0; b < exponents.length; b++) {
double b1 = Math.pow(userNumbers[1], exponents[b]);
for (int c = 0; c < exponents.length; c++) {
double c1 = Math.pow(userNumbers[2], exponents[c]);
for (int d = 0; d < exponents.length; d++) {
double d1 = Math.pow(userNumbers[3], exponents[d]);
double currentEstimate = a1 * b1 * c1 * d1;
if (Math.abs(mu - currentEstimate) < Math
.abs(mu - bestEstimate)) {
bestEstimate = currentEstimate;
bestA = exponents[a];
bestB = exponents[b];
bestC = exponents[c];
bestD = exponents[d];
}
}
}
}
}
out.println("Best estimate: " + bestEstimate);
out.println(userNumbers[0] + "^" + bestA + ", " + userNumbers[1] + "^"
+ bestB + ", " + userNumbers[2] + "^" + bestC + ", "
+ userNumbers[3] + "^" + bestD);
out.println("Error: " + calculateError(mu, bestEstimate) * 100 + "%");
}
Output:
Enter a positive real number: 238900
Enter a positive real number that isn't 1: 14
Enter a positive real number that isn't 1: 102329
Enter a positive real number that isn't 1: 1936
Enter a positive real number that isn't 1: 13
Best estimate: 239102.78648033558
14.0^-5.0, 102329.0^1.0, 1936.0^0.5, 13.0^4.0
Error: 0.08488341579555334%
However, with the while loops, I am unable to replicate this.
while (a < exponents.length) {
double a1 = Math.pow(userNumbers[0], exponents[a]);
while (b < exponents.length) {
double b1 = Math.pow(userNumbers[1], exponents[b]);
while (c < exponents.length) {
double c1 = Math.pow(userNumbers[2], exponents[c]);
while (d < exponents.length) {
double d1 = Math.pow(userNumbers[3], exponents[d]);
double currentEstimate = a1 * b1 * c1 * d1;
if (Math.abs(mu - currentEstimate) < Math
.abs(mu - bestEstimate)) {
bestEstimate = currentEstimate;
bestA = exponents[a];
bestB = exponents[b];
bestC = exponents[c];
bestD = exponents[d];
}
d++;
}
c++;
}
b++;
}
a++;
}
Output:
Enter a positive real number: 238900
Enter a positive real number that isn't 1: 14
Enter a positive real number that isn't 1: 102329
Enter a positive real number that isn't 1: 1936
Enter a positive real number that isn't 1: 13
Best estimate: 0.0
14.0^0.0, 102329.0^0.0, 1936.0^0.0, 13.0^0.0
You haven't initialized the variables for the next few iterations.
You need to reinitialize the variables used for while loop's condition check outside their respective while loops. i.e
b = 0;
while(b < exponents.length){
}
Similarly do it for the while loops which use variables c & d.
Daniel's answer is correct : the
structure of the while loop should be:
int a=0, b=0, c=0, d=0;
while (a < length) {
b=0;
while (b < length) {
c=0;
while (c < length) {
d=0;
while (d < length) {
d++;
}
c++;
}
b++;
}
a++;
}

Magic square code loop

This is the code for a method which creates a magic square. n is the length of the square. It has to look like:
static int[][] magicSquare(int n) {
int[][] square=new int[n][n];
I don't understand this k=(k+1)%n; especially, why is it %n ?? Doesn´t that put k to 1 every loop again?
for (int i=0; i<n; i++){
in k=i;
for (int j=0; j<n; j++){
square[i][j]=k+1;
k=(k+1)%n;
1 2 3 4
2 3 4 1
3 4 1 2
4 1 2 3
The % in Java is used for modular division. Whenever the operator is applied the right-hand operand will be subtracted as many times as it can from the left-hand operand and what's left will be the output. You can easily check it by dividing the left-hand operand by the right-hand operand and take the leftover as an integer. In the case of a%b it will be like
a - (a/b)*b.
here are some examples:
10 % 4 = 2 // 2*4 = 8 + 2 = 10
10 % 5 = 0 // 2*5 = 10 + 0 = 10
0 % 4 = 0 // result here is 0 thus 0*4 = 0 + 0 = 0
// if you try to extract 4 from 0, you will not succeed and what's left will be returned (which was originally 0 and it's still 0)...
In your case:
k = (k + 1) % n;
is assuring that the value of k will never exceed 4, thus if it is dividable by 4 then it will be divided and the leftover will be written there. In the case when k is exactly 4 you will have the value of 0 written down into k but since you are always adding k + 1 it is writing the value of 1.
For beginners I do recommend to print the values you are interested in and observe how do the data migrate. Here I've added some printlns for you just to get the idea. Run the code and test it yourself. I do believe the things are going to be a bit cleaner.
public static void main(String[] args) {
int n = 4;
int[][] square = new int[n][n];
System.out.println("--------------");
for (int i = 0; i < n; i++) {
int k = i;
System.out.println("Filling magic cube line " + (i + 1) + ". The k variable will start from " + i + "."); // i initial value is 0 so we add 1 to it just to get the proper line number.
for (int j = 0; j < n; j++) {
System.out.println("Filling array index [" + i + "][" + j + "] = " + (k + 1)); // array indexes start from 0 aways and end at array.length - 1, so in case of n = 4, last index in array is 3.
square[i][j] = k + 1; // add 1 to k so the value will be normalized (no 0 entry and last entry should be equal to n).
k = (k + 1) % n; // reset k if it exceeds n value.
}
System.out.println("--------------");
}
Arrays.stream(square).forEach(innerArray -> {
Arrays.stream(innerArray).forEach(System.out::print);
System.out.println();
});
}
You could always play around and refactor the code as follows:
public static void main(String[] args) {
int n = 4;
int[][] square = new int[n][n];
System.out.println("--------------");
for (int i = 1; i <= n; i++) {
int k = i;
System.out.println("Filling magic cube line " + i + ". The k variable will start from " + i + ".");
for (int j = 0; j < n; j++) {
System.out.println("Filling array index [" + (i - 1) + "][" + (j - 1) + "] = " + k); // array indexes start from 0 aways and end at array.length - 1, so in case of n = 4, last index in array is 3. Subtract both i and j with 1 to get the proper array indexes.
square[i - 1][j - 1] = k;
k = (k + 1) % n; // reset k if it exceeds n value.
}
System.out.println("--------------");
}
Arrays.stream(square).forEach(innerArray -> {
Arrays.stream(innerArray).forEach(System.out::print);
System.out.println();
});
}
Remember that the array's indexing starts from 0 and ends at length - 1. In the case of 4, the first index is 0 and the last one is 3. Here is the diff of two implementations, try to see how does the indexes and values depends both on the control variables i and j.
https://www.diffchecker.com/x5lIWi4A
In the first case i and j both start from 0 and are growing till they it's values are both less than n, and in the second example they start from 1 and are growing till they are equal to n. I hope it's getting clearer now. Cheers

How can we find the sum for each subset of array

I am trying to finding the sum of each in the below code in java.What changes should i have to made in this code.
import java.io.IOException;
class as {
static void printSubsets(int set[]) {
int n = set.length;
for (int i = 0; i < (1 << n); i++) {
for (int j = 0; j < n; j++) {
if ((i & (1 << j)) > 0) {
System.out.print(set[j] + " ");
}
}
System.out.println();
}
}
public static void main(String[] args) {
int set[] = { 1, 2, 3 };
printSubsets(set);
}
}
Output of above code is:
1
2
1 2
3
1 3
2 3
1 2 3
I want To Multiply each element of subset by its last number for e.g.
1*1=1
2*2=4
1*2+2*2=6
3*3=9
likewise all elements
and lastly generate sum of all these subset 1+4+6+9+.. and so on.
Above code also print null set and subset are in order.How this program can be edited to make changes such that it does'nt print null set and print random substring.
As far as I understand your question, you want to multiply all the elements with each other and print out each step of iteration with the result. Here you are:
static void printSubsets(int set[]) {
int sum = 0;
for (int i=0; i<set.length; i++) {
for (int j=i; j<set.length; j++) {
int var = set[i] * set[j];
sum += var;
System.out.println("( " + set[i] + " * " + set[j] + " = " + var + " ) -> sum=" + sum);
}
}
System.out.println("final sum=" + sum);
}
In case of input [1,2,3], the sum is supposed to grow according my algorithm by:
1, 3, 6, 10, 16 up to 20
Just a note about << shift operator which shifts a bit pattern to the left. Let's say that number 2 is understood as 10 in binary. Shifting this number by 2 << 4 will result 100000 in binary that is understood as 32 in decimal. I am not sure you really need this pattern.

while nested in for loop. How does the decrement operator work?

I couldn't figure out how the decrement operator (e--)
works in code below, so i wrote the other class below it
to get the same result. I want to know how the decrement operator
achieves that result in the Power class. - Newbie.
int result, e;
for(int i=0; i < 10; i++) {
result = 1;
e = i;
while(e > 0) {
result *= 2;
e--;
}
System.out.println("2 to the " + i +
" power is " + result);
}
Code written to achieve same result
int result = 1;
for(int i=0; i < 10; i++) {
if (i > 0) {
result*=2;
}
System.out.println("2 to the " + i +
" power is " + result);
}
So the first example is resetting result for each iteration of the main for loop, so it needs to recalculate from scratch each time, where as the second example is keeping the previous computed value. The if in the second example is not needed is it.
The decrement operator modifies the variable on which it's called. So e-- is effectively e = e - 1 (except the overall result of the expression is different, see below).
This code:
result = 1;
e = i;
while(e > 0) {
result *= 2;
e--;
}
starts with result = 1 and then loops for i iterations doubling the value in result. Equivalent code using for which you seem more comfortable with:
result = 1;
for (e = 0; e < i; e++) {
result *= 2;
}
There are two forms of the decrement (and increment) operator: Prefix and postfix, depending on whether the operator is before (prefix) or after (postfix) its operand. Either could be used in the code you were asking about, because the only difference is the result of the expression.
Prefix: Suppose we have x = 5. The expression --x has the value 4: First we decrement x, then we take its new value as the result of the expression.
Postfix: Suppose we had x = 5 (again). The expression x-- has the value 5, with x ending up containing 4: First we grab the current value of x as the result of the expression, then we decrement it (because the -- is after x).
int x, r;
x = 5;
r = --x; // Prefix
System.out.println("r = " + r + ", x = " + x); // "r = 4, x = 4"
x = 5;
r = x--; // Postfix
System.out.println("r = " + r + ", x = " + x); // "r = 5, x = 4"
i figure out that by placing a System.out.println(e) i could "see" the variable "e" behavior in order to make sense of the decrement.
class Power {
public static void main(String args[]) {
int e;
int result;
for(int i=0; i < 10; i++) {
result =1 ;
e = i;
while(e > 0) {
System.out.println(e); // not part of the original program
result *= 2 ;
e--;
System.out.println(e); // not part of the original program
}
//System.out.println("2 to the " + i +
//" power is " + result);
}
This is the output:
C:\Users\enrique\Desktop\Hello.java>java Power: 1, 0, 2, 1, 1, 0, 3
e = 1(iteration 1), 2^1, e (1) decremented to 0, e = 2 (iteration 2), 2^2, e(2) decremented to 1, e = 1 re-enter The while but is ignored as 2^1 is already registered, e (1) decremented to 0, e = 3 (iteration 3), 2^3…

Categories

Resources