I'm running into an issue where both my standard dev. and my median are taking too long to get printed but everything else prints quickly. This only occurs when I have a larger list, I am not understanding the problem, as the numbers are not too large it should fit into both double or integer form, its just not getting displayed at a buttons click like the other values.
Current Code
package Labs;
import java.util.*;
import java.text.DecimalFormat;
/**
*
* #author nick a
*/
public class Practice {
/**
* #param args the command line arguments
*/
private static final DecimalFormat df = new DecimalFormat("0.00");
public static void main(String args[]) {
Double[] dataArray = {16500.0, 304000.0, 384500.0, 431500.0, 681500.0, 348500.0, 282500.0, 327000.0, 182500.0};
List<Double> data = new ArrayList<>(Arrays.asList(dataArray));
System.out.println("StDev Value from list: " + df.format(stdev(data)));
System.out.println("Median Value from list: " + df.format(median(data)));
}
public static double stdev(List<Double>values){
double sumOfDiff = 0;
for(int i = 0; i < values.size(); i++){
sumOfDiff += Math.pow(Math.abs(values.get(i)) - mean(values), 2);
}
double resultant = sumOfDiff/values.size();
return Math.sqrt(resultant);
}
public static double median(List<Double>values){
List<Double>sorted = new ArrayList<>(values);
Collections.sort(sorted);
if(sorted.size() % 2 == 0){
int evenMid = sorted.size()/2;
double sumEven = sorted.get(evenMid-1) + sorted.get(evenMid);
return sumEven/2;
}
int oddMid = (sorted.size()+1)/2;
return sorted.get(oddMid-1);
}
}
The problem happens when the list becomes super large (400,000) entries... I have other things printed out like mean, range, min, max etc. but as soon as its time for standard deviation and median to be printed out it takes its sweet time unlike the rest. How might I fix this?
Related
This question already has answers here:
Error in System.out.println
(5 answers)
Closed 4 years ago.
My Task:
Create a class called Icosahedron which will be used to represent a regular icosahedron, that is a convex polyhedron with 20 equilateral triangles as faces. The class should have the following features:
A private instance variable, edge, of type double, that holds the
edge
length.
A private static variable, count, of type int, that holds the
number of Icosahedron objects that have been created.
A constructor that takes one double argument which specifies the edge length.
An
instance method surface() which returns the surface area of the
icosahedron. This can be calculated using the formula 5*√3 edge².
An
instance method volume() which returns the volume of the icosahedron.
This can be calculated using the formula 5*(3+√5)/12*edge³.
An
instance method toString() which returns a string with the edge
length, surface area and volume as in the example below:
Icosahedron[edge= 3.000, surface= 77.942, volume= 58.906]
The numbers in this string should be in floating point format with a field
that is (at least) 7 characters wide and showing 3 decimal places.
Please use the static method String.format with a suitable formatting
string to achieve this. A static method getCount() which returns the
value of the static variable count.
Finally, add the following main method to your Icosahedron class so that it can be run and tested:
public static void main(String[] args) {
System.out.println("Number of Icosahedron objects created: " + getCount());
Icosahedron[] icos = new Icosahedron[4];
for (int i = 0; i < icos.length; i++)
icos[i] = new Icosahedron(i+1);
for (int i = 0; i < icos.length; i++)
System.out.println(icos[i]);
System.out.println("Number of Icosahedron objects created: " + getCount());
}
Okay. so heres what i have started on:
import java.util.Scanner;
public class Icosahedron {
private double edge = 0;
private int count = 0;
Scanner input = new Scanner(System.in);
double useredge = input.nextDouble();
System.out.println("Enter Edge Length: ");
}
i receive an error on the last line. i cant use println() what am i doing wrong? or maybe im understanding the question wrong? any guidance would be appreciated.
thanks.
Your Icosahedron class should look like the following:
public class Icosahedron {
private double edge;
private int count;
public Icosahedron(int count) {
this.count = count;
}
public double getEdge() {
return edge;
}
public void setEdge(double edge) {
this.edge = edge;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
#Override
public String toString() {
return "Icosahedron{edge=" + edge + ", count=" + count + '}';
}
}
And your class containing the main method (I called it MoreProblem):
import java.util.Scanner;
public class MoreProblem {
public static void main(String[] args) {
Icosahedron[] icos = new Icosahedron[4];
for (int i = 0; i < icos.length; i++) {
icos[i] = new Icosahedron(i+1);
Scanner input = new Scanner(System.in);
System.out.println("Enter Edge Length: ");
double userEdge = input.nextDouble();
icos[i].setEdge(userEdge);
}
for (Icosahedron icosahedron : icos) {
System.out.println(icosahedron);
}
System.out.println("Number of Icosahedron objects created: " + icos.length);
}
}
Write a class with a constructor that accepts a file name as its argument. Assume the file contains a series of numbers, each written on a separate line. The class should read the contents of the file into an array, and then displays the following data.
The lowest number in the array
The highest number in the array
The total of the numbers in the array
The average of the numbers in the array.
The file, Numbers.txt used for the above program contains these twelve numbers:
8.71
7.94
3.01
29.27
9.23
82.76
12.6
47.99
63.89
1.09
22.23
79.17
This is the main program: NumberAnalyzerDemo.java
import java.io.*; // Needed for IOException
/**
This program demonstrates a solution to the
Number Analysis Class programming challenge.
*/
public class NumberAnalyzerDemo
{
public static void main(String[] args) throws IOException
{
// Create a NumberAnalyzer object.
NumberAnalyzer na = new NumberAnalyzer("Numbers.txt");
// Display data about the numbers in the file.
System.out.println("The lowest number in the file is " +
na.getLowest());
System.out.println("The highest number in the file is " +
na.getHighest());
System.out.println("The total of the numbers in the file is " +
na.getTotal());
System.out.println("The average of the numbers in the file is " +
na.getAverage());
}
}
This is the class: NumberAnalyzer.java
import java.io.*;
import java.util.Arrays;
import java.util.Scanner;
import java.io.File;
/**
The NumberAnalyzer class is to searching the numbers in a file.
*/
public class NumberAnalyzer
{
private double[] numbers;
private int count;
File file;
Scanner scan;
/**
Constructer that accepts the file name as its argument.
*/
public NumberAnalyzer(String filename) throws IOException
{
count = 0;
file = new File("Numbers.txt");
scan = new Scanner(file);
numbers = new double[11];
}
/**
The getLowest() method to search the file and pull out the lowest
number in the file.
#return Return the lowest number.
*/
public double getLowest()
{
double low = numbers[0];
for (int i = 0; i < numbers.length; i++)
{
if (low > numbers[i])
{
low = numbers[i];
}
}
return low;
}
/**
The getHighest() method to search the file and pull out the highest
number in the file.
#return Return the highest number.
*/
public double getHighest()
{
double high = numbers[0];
for (int i = 0; i < numbers.length; i++)
{
if (high < numbers[i])
{
high = numbers[i];
}
}
return high;
}
/**
This method calculate the total of all the number in the file.
#return Adding all number in the file.
*/
public double getTotal()
{
double total = 0;
for (int i = 0; i < numbers.length; i++)
{
total += numbers[i];
}
return total;
}
/**
This method used to calculate the average of the numbers in the file.
#return Using the getTotal() divided to the length of the numbers.
*/
public double getAverage()
{
return getTotal() / numbers.length;
}
/**
This method to read all the file txt and get the right number.
*/
private void getNumbers(String filename)
{
while(scan.hasNext())
{
numbers[count] = scan.nextDouble();
count++;
}
scan.close();
}
/**
This method
*/
private int getNumberOfValues(String filename)
{
return count ;
}
}
I'm getting 0.0 for all the output. Please give me some suggestions. Thanks!
solution
change you method
private void getNumbers(String filename)
to
public void getNumbers()
and then do
NumberAnalyzer na = new NumberAnalyzer("Numbers.txt");
na.getNumbers();
You're not calling your getNumbers() method, and so haven't populated your numbers[] array.
Just make the call in your constructor, like this:
public NumberAnalyzer(String filename) throws IOException
{
count = 0;
file = new File("Numbers.txt");
scan = new Scanner(file);
numbers = new double[11];
getNumbers();
}
It looks like it doesn't need to have the String argument, so you could remove that, unless you're still planing to implement something with it.
I am a beginner in java development field and still i am a learner of Java Programming. I wanted to see the output for the Support Vector Machine classifier on netbeans IDE. So i copied this attached piece of code and tried to run by using all the other required class and main method as well but i am getting Number format exception when i give a file containing input like 23,25,26,27 during the call of the method loadBinaryProblem() in main method and if i remove all the commas and replaced them with space ex: 23 25 26 27 then i am getting ArrayIndexOutOfBound exception instead of it. So anybody can help to get the output properly without any error.
package svmlearn;
import java.io.*;
import java.util.*;
/**
* Class representing an optimization problem (a data setting);
* taken from liblinear; "bias" excluded
* #author miafranc
*
*/
public class Problem {
/** The number of training data */
public int l;
/** The number of features (including the bias feature if bias >= 0) */
public int n;
/** Array containing the target values */
public int[] y;
/** Map of categories to allow various ID's to identify classes with. */
public CategoryMap<Integer> catmap;
/** Array of sparse feature nodes */
public FeatureNode[][] x;
public Problem() {
l = 0;
n = 0;
catmap = new CategoryMap<Integer>();
}
/**
* Loads a binary problem from file, i.e. having 2 classes.
* #param filename The filename containing the problem in LibSVM format.
*/
public void loadBinaryProblem(String filename) {
String row;
ArrayList<Integer> classes = new ArrayList<Integer>();
ArrayList<FeatureNode []> examples = new ArrayList<FeatureNode []>();
try {
BufferedReader r = new BufferedReader(new FileReader(filename));
while ((row = r.readLine()) != null) {
String [] elems = row.split(" ");
//Category:
Integer cat = Integer.parseInt(elems[0]);
catmap.addCategory(cat);
if (catmap.size() > 2) {
throw new IllegalArgumentException("only 2 classes allowed!");
}
classes.add(catmap.getNewCategoryOf(cat));
//Index/value pairs:
examples.add(parseRow(elems));
}
x = new FeatureNode[examples.size()][];
y = new int[examples.size()];
for (int i=0; i<examples.size(); i++) {
x[i] = examples.get(i);
y[i] = 2*classes.get(i)-1; //0,1 => -1,1
}
l = examples.size();
} catch (Exception e) {
System.out.println(e);
}
}
/**
* Parses a row from a LibSVM format file.
* #param row The already split row on spaces.
* #return The corresponding FeatureNode.
*/
public FeatureNode [] parseRow(String [] row) {
FeatureNode [] example = new FeatureNode[row.length-1];
int maxindex = 0;
for (int i=1; i<row.length; i++) {
String [] iv = row[i].split(":");
int index = Integer.parseInt(iv[0]);
if (index <= maxindex) {
throw new IllegalArgumentException("indices must be in increasing order!");
}
maxindex = index;
double value = Double.parseDouble(iv[1]);
example[i-1] = new FeatureNode(index, value);
}
if (n < maxindex)
n = maxindex;
return example;
}
}
i guess NumberformatExceptions comes from:
String [] elems = row.split(" "); //nothing done by "23,25,26,27"
//Category:
Integer cat = Integer.parseInt(elems[0]); //you are trying to parse "23,25,26,27"
ArrayIndexOutOfBound comes from:
String [] iv = row[i].split(":");//nothing done
...
double value = Double.parseDouble(iv[1]);//1 is out of bound
I am confused with passing ARRAYLIST values from one class to another.
I used the ARRAY in these classes before. I am changed those with ARRAYLISTS.
I have 2 classes. this class has an ARRAYLIST called "locationcells". This programs get 3 random digits from another class and get uses inputs and check if their inputs match the 3 digits. it's more like a guessing game.
import java.util.ArrayList;
class SimpleDotCom {
private ArrayList<String> locationcells;
public void setLocationcells(ArrayList<String> Locs)
{
locationcells = Locs;
}
public String CheckYourself(String StringGuess)
{
String result = " Miss";
int index = locationcells.indexOf(StringGuess);
if (index >= 0)
{
locationcells.remove(index);
if (locationcells.isEmpty())
{
result = "Kill";
}
else
{
result = "Hit";
}
}
return result;
}
}
this looks right.
Now the class with the main method:
import java.util.ArrayList;
class SimpleDotComGame {
public static void main(String[] args)
{
int numOfGuesses = 0;
GameHelper helper = new GameHelper();
SimpleDotCom theDotCom = new SimpleDotCom();
/*
this is the part I don't understand. I used to have the int array and generated random numbers and it worked well.
int randomNum = (int) (Math.random() * 5);
ArrayList<String> locations = new ArrayList<String>();
*/
theDotCom.setLocationcells(locations);
boolean isAlive = true;
while (isAlive == true)
{
String guess = helper.getUserInput("Enter a number");
String result = theDotCom.CheckYourself(guess);
numOfGuesses++;
if (result.equals("Kill"))
{
isAlive = false;
System.out.println("You took " + numOfGuesses + "guesses");
}
}
}
}
If you see the comments section above. That's the part I am getting confused. I used to have an array there. INT array. So I was able to pass the INT random numbers to the "simpledotcom" class. Now it is an arraylist with string type, I am not sure how to move forward.
Thank you all in advance,
int numericGuess = Integer.parseInt(helper.getUserInput("Enter a number"));
Also you can use a list of Integers too:
ArrayList<Integer> locations = new ArrayList<Integer>();
while(//condition){
int randomNum = (int) (Math.random() * 5);
locations.add(randomNum)
}
this way you can perform
locations.indexOf(numericGuess) or locations.contains(numericGuess)
OR
Conversely you can do,
String guess = helper.getUserInput("Enter a number");
ArrayList<String> locations = new ArrayList<String>();
while(//condition){
int randomNum = (int) (Math.random() * 5);
locations.add(String.valueOf(randomNum))
}
and check by
locations.indexOf(guess) or locations.contains(guess)
You can always transform the random int to a string by using Integer.toString() before inserting into your array list.
You can convert the String back to int using Integer.parseInt()
E.g.
for (int i = 0 ; i < 3 ; i++)
{
locations.add(Integer.toString((int)(Math.random() * 5));
}
If I understand well: add 3 Strings to the ArrayList:
ArrayList<String> locations = new ArrayList<String>();
for (i=0; i<3; i++)
{ locations.add(String.valueOf((int) (Math.random() * 5))); }
Anyway, you might refactor a little as well, starting with the extracting the above lines from the main method.
Another way might be to store your integer in a list, and convert the guesses to integers. Looks more logic to me anyway. In that case, you'll have an ArrayList. To convert a string to an integer:
int guessNumber = Integer.parseInt(guess);
or
Integer guessNumber = Integer.valueOf(guess);
Both will throw a NumberFormatException if 'guess' does not contain a parseble integer (see javadoc )
Why are you not using arrays like (apparently) you did before, by the way?
I'm trying to solve Project Euler problem #16, where I need to sum all the digits of 2^1000. I've gotten stuck dealing with such a big number. My program worked for any number below 10^16, but failed afterwards. This told me that my logic was correct. I went ahead and converted all variables and methods to BigDecimal, but now the program does not run properly. It compiles as it is and there is no error; it just does not terminate. Does anyone have an idea on where I went wrong here?
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Powerdigitsum {
private static final BigDecimal one = new BigDecimal("1");
private static final BigDecimal ten = new BigDecimal("10");
private static BigDecimal sumofDigits(BigDecimal n){
BigDecimal sum = new BigDecimal("0");
while(n.compareTo(one) == 1 || n.compareTo(one) == 0){
sum.add(n.remainder(ten));
n.divide(ten);
n = n.setScale(0, RoundingMode.FLOOR);
}
return sum;
}
public static void main(String[] args) {
final double the_number = Math.pow(2,1000);
final double test = 15;
final BigDecimal two_to_the_thousandth_power = new BigDecimal(test);
System.out.println(sumofDigits(two_to_the_thousandth_power));
}
}
Just use BigInteger properly:
BigInteger a = new BigInteger("2").pow(1000);
The whole method is kinda wrong. See this:
private static BigInteger sumOfDigits(BigInteger n) {
BigInteger sum = BigInteger.ZERO;
while (n.compareTo(BigInteger.ZERO) == 1) {
sum = sum.add(n.remainder(ten));
n = n.divide(ten);
}
return sum;
}
You needed to compare to zero, not one. And you need to assign the values for BigIntegers and BigDecimals, their methods do nothing on their own, the instances of those classes are immutable.
For integers, it's generally better to use BigInteger. The decimal part (that gets there from dividing) is just thrown away.
final double the_number = Math.pow(2,1000);
This won't work because the_number is not large enought to take the result. You need to convert the pow call to BigInteger:
BigInteger result = new BigInteger("2").pow(1000);
But be aware.. this can take some time..
Don't use the BigDecimal(double) constructor: it is limited by the double primitive type, which cannot represent 2^1000.
You can use a BigInteger. Something along these lines should work (probably suboptimal, but...):
public static void main(final String... args)
{
// 2^1000
final BigInteger oneTo2000 = BigInteger.ONE.shiftLeft(1000);
BigInteger digitSum = BigInteger.ZERO;
// We don't want to split against the empty string, the first element would be ""
for (final String digit: oneTo2000.toString().split("(?<=.)"))
digitSum = digitSum.add(new BigInteger(digit));
System.out.println(digitSum);
}
public class SumofDigitsPow {
public static void main(String[] args) {
//2(2^1000)
String temp = BigInteger.ONE.shiftLeft(1000).toString();
int sum = 0;
for(int i=0;i<temp.length();i++){
sum+= temp.charAt(i) - '0';
}
System.out.println(Integer.toString(sum));
}
}
java.math.BigInteger.shiftLeft(int n) method returns a BigInteger whose value is (this << n),So you can get the answer by using BigInteger and LeftShift Method
import java.math.BigInteger;
public class Problem16 {
public static void main(String[] args) {
BigInteger number2 = new BigInteger("2");
BigInteger number3 = new BigInteger("0");
number3 =number2.pow(1000);
String str = number3.toString();
BigInteger sum = new BigInteger("0");
for(int i=0; i<str.length(); i++)
{
char c= str.charAt(i);
int value = Character.getNumericValue(c);
BigInteger value2 = new BigInteger(Integer.toString(value));
sum =sum.add(value2) ;
}
System.out.println(sum);
}
}
IF YOU THINK BIGINTEGER IS CHEATING AND/OR don't feel like using it/learning how to use it, this algorithm is the way to go.
Think about how you would calculate 2^1000 by hand. You'd start with 2^1 and multiply by two repeatedly. Now notice that the number of digits of powers of two increase by 1 for AT LEAST every 3 powers (could be after 4 powers like with 1024 to 8192). So make a jagged 2D array like this
int a[][]= new int[1000][];
for(int i=0;i<1000;i++)
{
a[i]= new int[1+(i/3)];
}
Then initialize a[0][0] to 2. After this, you want to write a for loop such that each row is filled from the rightmost spot. So make two variables "digit" and "carry". Digit is the number that you will input into the row you're working on, and the carry is the one you're going to take to the next calculation and add to the product of 2 and whatever digit you're multiplying it with. Be careful with the order you update digit and carry and reinitialize them to zero after every calculation. I think the hardest part is coming up with the limits for the for loop, so that it fits with the every 3 powers thing. You can make this simpler by just making a triangular jagged array that increments by one every row. I did it like this though. Here's my whole code.
import java.util.*;
public class ProjectEuler16
{
public static void main(String[] args)
{
long t1=System.currentTimeMillis();
ProjectEuler16 obj = new ProjectEuler16();
System.out.println(obj.bigNumHandler());
long t2= System.currentTimeMillis();
System.out.println(t2-t1);
}
int bigNumHandler()
{
int a[][] = new int[1000][];
for(int i=0;i<1000;i++)
{
a[i]= new int[1+(i/3)];
}
a[0][0]=2;
for(int i=1;i<1000;i++)
{
int carry=0;
int digit=0;
int f=0;
if(i%3==0)
{
f=1;
}
for(int j=a[i-1].length-1+f;j>=0;j--)
{
if(j==0&f==1)
{
a[i][0]=carry;
}
else
{
digit=((2*a[i-1][j-f])+carry)%10;
carry=((2*a[i-1][j-f])+carry)/10;
a[i][j]=digit;
}
}
}
int sum=0;
for(int k=0;k<a[999].length;k++)
{
sum=sum+a[999][k];
}
return sum;
}
}
Note that the last row lists the digits for 2^1000.I think you can figure out how to sum the digits. The program took about 5 seconds to come up with the answer.
solution::::
import java.math.BigInteger;
public class PR9 {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
BigInteger zero=BigInteger.valueOf(0);
BigInteger ten=BigInteger.valueOf(10);
BigInteger sum=zero;
BigInteger a = new BigInteger("2").pow(1000);
while(a.compareTo(zero)>0){
sum=sum.add(a.mod(ten));
a=a.divide(ten);
}
System.out.println(sum);
}
}
output:::::
1366
import java.math.BigInteger;
public class P16 {
public static BigInteger digitSum(int n) {
BigInteger sum = BigInteger.ZERO;
BigInteger number = new BigInteger("2").pow(n);
while (number.compareTo(BigInteger.ZERO) == 1) {
BigInteger remainder = number.remainder(BigInteger.TEN);
sum = sum.add(remainder);
number = number.divide(BigInteger.TEN);
}
return sum;
}
public static void main(String[] args) {
final double START = System.nanoTime();
System.out.println(digitSum(Integer.parseInt(args[0])));
final double DURATION = System.nanoTime() - START;
System.out.println("Duration: " + DURATION / 1000000 + "ms.");
}
}
While there maybe a way of solving this problem without the use of BigIntegers, it is clear that they make the code run way faster.
Mine only took about 4ms to find an answer.