I want to program the iteration of the number e - java

I'm still a beginner in Java programming, and I'm using Eclipse Neon. How can I make it like that without writing the code again and again? And at the end, I want to print the final number on the screen.
Here's what I did so far:
public class othermethod {
public static void main(String[] args) {
int position = 1;
int pos = 0;
int[] zahlenlaenge = new int[100];
for (int i = 0; i < zahlenlaenge.length; i++) {
zahlenlaenge[pos] = position;
position++;
pos++;
System.out.println(pos);
}
}
}
How it should actually work:

OK, after evaluating what you're asking, I think your confusion lies in what you're doing with tracking your values.
I've taken most of your code and redone it with doubles, and renamed your array to foo for my typing purposes. I'm not sure what you're tracking, but this provides the discerning of what is sum, what is denominator, and if needed, any other values you can pretty quickly figure out where they come from.
double[] foo = new double[100]; //store the sum at any point in array
double sum = 1d; //first value
double denominator = 1d; //first denominator
for (int i = 0; i < foo.length; i++) {
foo[i] = sum; //set the sum to i (1, 2, 2.5, ...)
System.out.println(i + ":" foo[i]);
denominator *= (i + 1); //calculate the next factorial, (1, 2, 3)
sum += 1d / denominator; //calculate the sum (2, 2.5, ...)
}
You'll notice that this quickly normalizes as the 1d / denominator becomes super-tiny and is basically ignored for calculations.

Related

How to add multiple numbers using nested loops?

I am doing an assignment where I must use nested loops in order to add up the squares and cubes of integers from 1 to N (N being whatever the user inputs). For example, if the user input the number 5, the program is supposed to do "1²+2²+3²+4²+5²" and output the sum of those numbers, as well "1³+2³+3³+4³+5³" and output the sum of those numbers.
However, I am having trouble figuring out how to code it in a way that I receive the proper output? This is what I wrote. Scanners were already added.
int limitNum = input.nextInt();
double squareNums:
double sumofSq = 0;
double cubedNums;
double sumofCubes = 0;
for(int s = 1; s <= limitNum; s++)
{
for(int c = 1; c <= limitNum; c++)
{
cubedNums = Math.pow(c, 3);
sumofCubes = sumofCubes + cubedNums;
}
squareNums= Math.pow(s, 2);
sumofSq = sumofSq + squareNums;
}
But currently, when I run this program, the sum of the squares output correctly, but the sum of the cubes is always some big number. For example if 5 is used, sumofSq would output 55.0, but sumofCubes would output 1125.0.
There is no point using a nested loop as this would result in complexity of O(n²). A single loop would be sufficient and be in complexity class O(n).
public class Application {
public static void main(String[] args) {
var squareSum = 0d;
var cubeSum = 0d;
var upperBound = 5;
for(var i = 1; i <= upperBound; i++){
squareSum += Math.pow(i, 2);
cubeSum += Math.pow(i, 3);
}
System.out.printf("""
Sum of first n squares: %s
Sum of first n cubes: %s
""", (int)squareSum, (int)cubeSum);
}
}
In fact there is no need to loop at all => constant computation time no matter the size of the input O(1). There is a well known formula which tells you the sum of the first n squares.
n(n+1)(2n+1)
------------
6
Please see this for a proof.
The same holds true for the first n cubes.
n²(n+1)²
--------
4
Please see this for a proof.
The following program will therefore return the same result.
public class Application {
public static void main(String[] args) {
var upperBound = 5;
System.out.printf("""
Sum of first n squares: %s
Sum of first n cubes: %s
""", sumOfFirstNSquares(upperBound), sumOfFirstNCubes(upperBound));
}
public static int sumOfFirstNSquares(int n){
return (n * (n+1) * (2 * n + 1)) / 6;
}
public static int sumOfFirstNCubes(int n){
return ((n * n) * (n+1) * (n+1)) / 4;
}
}
In fact there is no need to loop at all => constant computation time no matter the size of the input O(1). There is a well known formula which tells you the sum of the first n squares.
java

My code doesn't calculate min and max numbers

I'm trying to write a code which will show the highest, lowest, the difference of them and the average of inputted 30 numbers.
But its not working and is showing the same result for both min and max numbers. Here is the code.
public class aa {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] daystemp = new int[30];
int i = 0;
int dayHot = 0;
int dayCold = 0;
while(i < daystemp.length){
daystemp[i] = input.nextInt();
i++;
}
int maxTemp = daystemp[0];
while (i < daystemp.length) {
if (daystemp[i] > maxTemp) {
maxTemp = daystemp[i];
dayHot = i + 1;
i++;
}
}
System.out.println(maxTemp);
int minTemp = daystemp[0];
while (i < daystemp.length) {
if (daystemp[i] < minTemp) {
minTemp = daystemp[i];
dayCold = i + 1;
i++;
}
}
System.out.println(minTemp);
int diff = maxTemp - minTemp;
System.out.println("The difference between them is"+diff);
double sum = 0;
while(i < daystemp.length) {
sum += daystemp[i];
i++;
}
double average = sum / daystemp.length;
System.out.println("Average was"+average);
}
}
After the first loop (the input loop), i value is daystemp.length (i.e. 30).
It's never reset to 0. So each while loop condition is false.
Add i=0 before the loops and do i++outside the ifblocks or your code will never end.
example:
i=0;
int maxTemp = daystemp[0];
while (i < daystemp.length) {
if (daystemp[i] > maxTemp) {
maxTemp = daystemp[i];
dayHot = i + 1;
}
i++;
}
A few notes about this solution:
By declaring the cumulative total double, no casting is required.
Because Java knows you want to convert int to double automatically if you assign an int to a declared double. Similary the fact that you want to express a result as double is implied when dividing a double by an int, such as when the average is taken. That avoids a cast also. If you had two ints and you wanted to produce a double you'd need to cast one or more of them, or in cases like a print statement where the compiler can't deduce the optimal type for the parameter, you'd need to explicitly cast to covert an int value to a double.
Not sure what OS you're running this on. The ideal situation would be to make it work on all platforms without requiring people type a magic word to end input (because how tacky). The easiest way to end input is to use the OS-specific end of input (end of file) key combination, and for Linux it's CTRL/D, which is how I explained it in the prompt. On another OS with a different end of input sequence you could just change the prompt. The trickiest would be if it is supposed to be truly portable Java. In that case I'd personally investigate how I could figure out the OS and/or End of File character or key combination on the current OS and modify the prompt to indicate to end input with whatever that is. That would be a bit of and advanced assignment but a very cool result.
Example illustrates use of a named constant to determine the array and is used limit the amount of input (and could be used to limit loop count of for loops accessing the array).
By setting the min and max to very high and low values respectively (notice the LOW value assigned to max and HIGH value assigned to min, those ensure the first legit temp entered will set the min and max and things will go from there).
Temperature Maximum, Minimum, Average and Difference Calculator
import java.util.Scanner;
public class TemperatureStats {
final static int MAX_DAYS = 31;
public static void main(String[] args) {
int[] dayTemps = new int[MAX_DAYS];
double cumulativeTemp = 0.0;
int minTemp = 1000, maxTemp = -1000;
Scanner input = new Scanner(System.in);
System.out.println("Enter temps for up to 1 month of days (end with CTRL/D):");
int entryCount = 0;
while (input.hasNextInt() && entryCount < MAX_DAYS)
dayTemps[entryCount++] = input.nextInt();
/* Find min, max, cumulative total */
for (int i = 0; i < entryCount; i++) {
int temp = dayTemps[i];
if (temp < minTemp)
minTemp = temp;
if (temp > maxTemp)
maxTemp = temp;
cumulativeTemp += temp;
}
System.out.println("High temp. = " + maxTemp);
System.out.println("Low temp. = " + minTemp);
System.out.println("Difference = " + (maxTemp - minTemp));
System.out.println("Avg temp. = " + cumulativeTemp / entryCount);
}
}

Statistical method

So in my code, it seems that in the fillRandomArray method, instead of getting an array of 100 random numbers, I just get straight zeros and I don't know how to fix it. It seems to me that the problem has to do with the first for loop, or potentially the declaration of the double array in the public class statistical model.
import javax.swing.*;
import java.util.*;
import java.util.Arrays;
public class statisticalModel {
//Initates a place for the normal curve to be placed.
static double Ho;
//Real proportion of data statistic.
static double Ha;
//Estimated real proportion of data statistic.
static int Pop;
//Population size.
static int Zscore;
//Z score, or the amount of standard deviations away from the mean.
//Z score = sqrt(P(1-p)/N)
static double stdDev;
//Standard Deviation, follows the 65, 95, 99 model. 65 percent of all scores
//fall in one standard deviation of the mean. 95 percent of all scores fall
//within two standard deviations of the mean. 99 percent of all scores fall
//within three standard deviations of the mean.
static double mean;
//The average of all the scores of the array.
static double variance;
//The average difference between sets of values within the array.
static double[] meanScores = new double[100];
//Array meant to generate a set of random values within the normal curve of
//the model, following the 65, 95, 99 rule.
static String desiredValue = "";
//This is a string set to the user's command. Tells whether or not the value should
//be lower than, higher than, or not equal to Ho.
static Scanner sc = new Scanner(System.in);
//Scanner to take in values listed above.
static int size = 100;
//Variable that measures the size of the array.
static int temporary;
//Value Holder for For Loops, While Loops, If Statements, etc.
static double pValue;
//P Value which represents how far a statistic deviates from the expected mean of a population.
public static void main(String args[])
{
runStatisticalMethod();
}
public static void runStatisticalMethod()
{
takeInData();
calculateStats();
System.out.println(Arrays.toString(meanScores));
explainSolution();
}
public static void takeInData()
{
System.out.println("Please enter your desired Ho");
Ho = sc.nextDouble();
System.out.println("Please enter your desired Ha");
Ha = sc.nextDouble();
System.out.println("Please enter your desired population size");
Pop = sc.nextInt();
System.out.println("Thanks for entering your data. Your data will be compiled below");
}
//Fills the array meanScores with random integers.
public static void fillRandomArray()
{
for (int z = 0; z < 100; z++) {
meanScores[z] = (Math.random() * 100) + (stdDev * 3);
}
assignStdDev();
for (int x = 0; x < 99; x++) {
for (int y = 0; y < 99; y++) {
if (meanScores[y] >= meanScores[y + 1]) {
double valueHolder1 = meanScores[y];
double valueHolder2 = meanScores[y + 1];
meanScores[y + 1] = valueHolder1;
meanScores[y] = valueHolder2;
}
}
}
}
public static void assignStdDev()
{
for (int x = 5; x >= 5 && x <= 95; x++) {
meanScores[x] -= (stdDev * Math.random());
}
for (int x = 31; x >= 31 && x < 66; x++) {
meanScores[x] -= (stdDev * Math.random());
}
}
//Calculates a set of statistics including standard deviation, z-score, mean,
//interquartile range, probability, and variance.
public static void calculateStats()
{
//Calculates the Mean of the inputted variables and normal curve.
int sum = 0;
for (int a = 0; a < 100; a++) {
sum += a;
}
mean = sum / size;
//Calculate the Variance of the inputted variables and normal curve.
for (int b = 0; b < 100; b++) {
temporary += (b - mean) * (b - mean);
}
variance = temporary / size;
//Calculate the Standard Deviation of the inputted variables and normal curve.
stdDev = Math.sqrt(variance);
//Calculate the P-Value and use the p value to determine whether or not the hypothesis is valid.
pValue = (Ha - Ho) / (stdDev / Math.sqrt(Pop));
}
//This method explains the numbers generated in terms of statistics and analyzes
//if the hypothesis is probably. If not, a possible solution is proposed with
//regards to what should be changed. Also explains the curve of the graph.
public static void explainSolution()
{
if (Math.abs(pValue) < .05) {
System.out.println(
"Based on the information you have given me, the hypothesis test seems to show information that your Ha is possibly correct, thus failing to reject your hypothesis");
} else if (Math.abs(pValue) > .05) {
System.out.println(
"Based on the information you have given me, the hypothesis test seems to lack information to show that your Ha is possibly correct, thus rejecting your hypothesis");
}
}
}

Dividing a number into smaller random ints

So what i need is basically described in the subject.
Like if i would put in number 12 and amount of parts it should devide into, i would like it to return something like (with 4 parts) 8, 2, 1, 1. But not doubles because i need the values as int.
I had found one answer earlier but it only worked using doubles. not ints.
(this is the one i found)
public double[] divideUniformlyRandomly(double number, int part) {
double uniformRandoms[] = new double[part];
Random random = new Random();
double mean = number / part;
double sum = 0.0;
for (int i=0; i<part / 2; i++) {
uniformRandoms[i] = random.nextDouble() * mean;
uniformRandoms[part - i - 1] = mean + random.nextDouble() * mean;
sum += uniformRandoms[i] + uniformRandoms[part - i -1];
}
uniformRandoms[(int)Math.ceil(part/2)] = uniformRandoms[(int)Math.ceil(part/2)] + number - sum;
return uniformRandoms;
I had tried changing this code to work using Ints by doing this:
public int[] divide(int number) {
int part = getDivider(number);
int uniformRandoms[] = new int[part];
Random random = new Random();
int mean = number / part;
int sum = 0;
for (int i=0; i<part / 2; i++) {
uniformRandoms[i] = random.nextInt() * mean;
uniformRandoms[part - i - 1] = mean + random.nextInt() * mean;
sum += uniformRandoms[i] + uniformRandoms[part - i -1];
}
uniformRandoms[(int)Math.round(part/2)] = uniformRandoms[(int)Math.round(part/2)] + number - sum;
for(int i : uniformRandoms)
System.out.println(i);
return uniformRandoms;
}
But when running that using number: 512 and using 10 parts (getDivider() will return 10) itll output this:
-1058809647, -2102647561, 469849949, 1627965716, -290084223, -33347991
And alot more of this kind of numbers.
Thanks.
Assuming every term should at least be 1.
public int[] divide(int number, int parts) {
int[] randoms = new int[parts];
Arrays.fill(randoms, 1); // At least one
int remainder = number - parts;
Random random = new Random();
for (int i = 0; i < parts - 1 && remainder > 0; ++i) {
int diff = random.nextInt(remainder);
randoms[i] += diff;
remainder -= diff;
}
randoms[parts - 1] += remainder;
Arrays.sort(randowms);
// Reverse (for getting a descending array):
for (int i = 0, j = parts - 1; i < j; ++i, --j) {h
int temp = randoms[i];
randoms[i] = randoms[j];
randoms[j] = temp;
}
return randoms;
}
This is not uniformly distributed. For that one could iterate till remainder becomes 0, everytime randomly picking an index to increase. Or so. Have fun.
Was this homework?
Use Random#nextInt(int)
public int[] divideUniformlyRandomly(int number, int parts) {
Random random = new Random();
int[] randoms = new int[];
for(int i = 0; i < parts; i++) {
randoms[randoms.length] = random.nextInt(number);
}
return randoms;
}
Here's an algorithm which will do the job:
Create an array of length parts+1.
Add the values 0 and number to the array, then fill the remainder of
it with unique random values using random.nextInt(number-1) + 1
to get values between 0 and number exclusive of the range limits.
Sort the array.
Iterate through the sorted array starting at index 1. The successive
differences array[i] - array[i-1] will be a set of positive integers that
sum to number.
If zeros are allowed, then you don't need the uniqueness criterion in filling the array.
If you need uniqueness, you might consider adding random values to a HashSet (which only .add()'s unique entries) until the size meets your requirement, then convert it with .toArray().
Here's an actual implementation:
import java.util.Arrays;
import java.util.HashSet;
import java.util.Random;
public class SumToTotal {
public static Random r = new Random();
public static int[] divide(int number, int number_of_parts) {
HashSet<Integer> uniqueInts = new HashSet<Integer>();
uniqueInts.add(0);
uniqueInts.add(number);
int array_size = number_of_parts + 1;
while (uniqueInts.size() < array_size) {
uniqueInts.add(1 + r.nextInt(number - 1));
}
Integer[] dividers = uniqueInts.toArray(new Integer[array_size]);
Arrays.sort(dividers);
int[] results = new int[number_of_parts];
for(int i = 1, j = 0; i < dividers.length; ++i, ++j) {
results[j] = dividers[i] - dividers[j];
}
return results;
}
public static void main(String[] args) {
System.out.println(Arrays.toString(divide(12, 5)));
}
}
This produces results such as [3, 2, 1, 2, 4] or [1, 5, 2, 3, 1].
A inefficient but very easy way would be to loop n times and increment one of the indices by one.
void divider(int number, int divisions)
{
Random rand = new Random();
int[] container = new int[divisions];
System.out.print(number + "->");
while (number > 0)
{
container[rand.nextInt(divisions)]++;
number--;
}
for (int i : container)
{
System.out.print("[" + i + "]");
}
}
divider(1000, 20) could output:
1000->[57][43][60][35][39][47][45][59][51][71][52][54][58][48][33][49][49][46][49][55]
1000->[60][50][49][53][42][52][52][45][40][51][52][51][53][47][51][46][53][56][45][52]
1000->[52][43][49][53][57][45][42][43][61][61][58][44][46][49][52][39][63][45][54][44]
On my way to old PC it takes only 11ms to divide 100.000 in 20 different "containers". So if you are not using this very often and/or on very big numbers this is a perfectly valid way to do it.

Translating equivalent formulas in to code isn't giving correct results

I'm trying to calculate the Mean Difference average of a set of data. I have two (supposedly equivalent) formulas which calculate this, with one being more efficient (O^n) than the other (O^n2).
The problem is that while the inefficient formula gives correct output, the efficient one does not. Just by looking at both formulas I had a hunch that they weren't equivalent, but wrote it off because the derivation was made by a statician in a scientific journal. So i'm assuming the problem is my translation. Can anyone help me translate the efficient function properly?
Inefficient formula:
Inefficient formula translation (Java):
public static double calculateMeanDifference(ArrayList<Integer> valuesArrayList)
{
int valuesArrayListSize = valuesArrayList.size();
int sum = 0;
for(int i = 0; i < valuesArrayListSize; i++)
{
for(int j = 0; j < valuesArrayListSize; j++)
sum += (i != j ? Math.abs(valuesArrayList.get(i) - valuesArrayList.get(j)) : 0);
}
return new Double( (sum * 1.0)/ (valuesArrayListSize * (valuesArrayListSize - 1)));
}
Efficient derived formula:
where (sorry, don't know how to use MathML on here):
x(subscript i) = the ith order statistic of the data set
x(bar) = the mean of the data set
Efficient derived formula translation (Java):
public static double calculateMean(ArrayList<Integer> valuesArrayList)
{
double sum = 0;
int valuesArrayListSize = valuesArrayList.size();
for(int i = 0; i < valuesArrayListSize; i++)
sum += valuesArrayList.get(i);
return sum / (valuesArrayListSize * 1.0);
}
public static double calculateMeanDifference(ArrayList<Integer> valuesArrayList)
{
double sum = 0;
double mean = calculateMean(valuesArrayList);
int size = valuesArrayList.size();
double rightHandTerm = mean * size * (size + 1);
double denominator = (size * (size - 1)) / 2.0;
Collections.sort(valuesArrayList);
for(int i = 0; i < size; i++)
sum += (i * valuesArrayList.get(i) - rightHandTerm);
double meanDifference = (2 * sum) / denominator;
return meanDifference;
}
My data set consists of a collection of integers each having a value bounded by the set [0,5].
Randomly generating such sets and using the two functions on them gives different results. The inefficient one seems to be the one producing results in line with what is being measured: the absolute average difference between any two values in the set.
Can anyone tell me what's wrong with my translation?
EDIT: I created a simpler implementation that is O(N) provided the all your data has values limited to a relatively small set.The formula sticks to the methodology of the first method and thus, gives identical results to it (unlike the derived formula). If it fits your use case, I suggest people use this instead of the derived efficient formula, especially since the latter seems to give negative values when N is small).
Efficient, non-derived translation (Java):
public static double calculateMeanDifference3(ArrayList<Integer> valuesArrayList)
{
HashMap<Integer, Double> valueCountsHashMap = new HashMap<Integer, Double>();
double size = valuesArrayList.size();
for(int i = 0; i < size; i++)
{
int currentValue = valuesArrayList.get(i);
if(!valueCountsHashMap.containsKey(currentValue))
valueCountsHashMap.put(currentValue, new Double(1));
else
valueCountsHashMap.put(currentValue, valueCountsHashMap.get(currentValue)+ 1);
}
double sum = 0;
for(Map.Entry<Integer, Double> valueCountKeyValuePair : valueCountsHashMap.entrySet())
{
int currentValue = valueCountKeyValuePair.getKey();
Double currentCount = valueCountKeyValuePair.getValue();
for(Map.Entry<Integer, Double> valueCountKeyValuePair1 : valueCountsHashMap.entrySet())
{
int loopValue = valueCountKeyValuePair1.getKey();
Double loopCount = valueCountKeyValuePair1.getValue();
sum += (currentValue != loopValue ? Math.abs(currentValue - loopValue) * loopCount * currentCount : 0);
}
}
return new Double( sum/ (size * (size - 1)));
}
Your interpretation of sum += (i * valuesArrayList.get(i) - rightHandTerm); is wrong, it should be sum += i * valuesArrayList.get(i);, then after your for, double meanDifference = ((2 * sum) - rightHandTerm) / denominator;
Both equations yields about the same value, but they are not equal. Still, this should help you a little.
You subtract rightHandTerm on each iteration, so it gets [over]multiplied to N.
The big Sigma in the nominator touches only (i x_i), not the right hand term.
One more note: mean * size == sum. You don't have to divide sum by N and then remultiply it back.

Categories

Resources