I am trying to figure out how to find the percent difference between the original (no space) string of text and the disemvoweled (no space) string of text. I am attempting to do this by using the equation ((newAmount-reducedAmount)/reducedAmount) but I am having no luck and am ending up with a value of zero, as shown below.
Thank you!
My Code:
import java.util.Scanner;
public class Prog5 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner console = new Scanner(System.in);
System.out.println("Welcome to the disemvoweling utility!"); // Initially typed "disemboweling" xD
System.out.print("Enter text to be disemvoweled: ");
String inLine = console.nextLine();
String vowels= inLine.replaceAll("[AEIOUaeiou]", ""); // RegEx for vowel control
System.out.println("Your disemvoweled text is: " + vowels); // Prints disemvoweled text
// Used to count all characters without counting white space(s)
int reducedAmount = 0;
for (int i = 0, length = inLine.length(); i < length; i++) {
if (inLine.charAt(i) != ' ') {
reducedAmount++;
}
}
// newAmount is the number of characters on the disemvoweled text without counting white space(s)
int newAmount = 0;
for (int i = 0, length = vowels.length(); i < length; i++) {
if (vowels.charAt(i) != ' ') {
newAmount++;
}
}
int reductionRate = ((newAmount - reducedAmount) / reducedAmount); // Percentage of character reduction
System.out.print("Reduced from " + reducedAmount + " to " + newAmount + ". Reduction rate is " + reductionRate + "%");
}
}
My output: (Test string is without quotes: "Testing please")
Welcome to the disemvoweling utility!
Enter text to be disemvoweled: Testing please
Your disemvoweled text is: Tstng pls
Reduced from 13 to 8. Reduction rate is 0%
You used an integer data type while calculating percentage difference while performing integer division. You need to type cast one of the variables on the right hand side of the equation to perform double division and then store them in double. The reason for doing this is java integer type can't hold the real numbers.
Also, multiple it by 100 to get the percentage.
double reductionRate = 100 * ((newAmount - reducedAmount) / (double)reducedAmount);
If you want a fraction between 0 and 1, then
double reductionRate = ((newAmount - reducedAmount) / (double)reducedAmount);
Your formula gives you a value between zero and one.
An integer cannot hold fractions so it always shows zero.
Multiply by 100 to get a regular percentage value.
int reductionRate = 100*(newAmount - reducedAmount) / reducedAmount; // Percentage of character reduction
Related
In my code I have a variable, points, that increments based on the consanants and vowels in strings inputted. The method parseSentence is supposed to increase points per word but also ignore spaces.
I've tried running a debugger to see where the problem is but the debugger dies when it reaches the for loop in parseSentence. The method makes the point variable's value the word's point value instead of adding it to the variable. What could be causing this?
import java.util.*;
public class WordGolf1 {
public static int points = 1;
public static void main(String[] args) {
String Input;
System.out.println("Enter word: ");
Scanner sc = new Scanner(System.in);
Input = sc.nextLine();
System.out.println("Not enough points. " + (100 - points) + " needed.");
while (points < 100) {
System.out.println("Enter word: ");
Input = sc.nextLine();
parseSentence(Input);
System.out.println(points + ": points");
System.out.println("Not enough points. " + (100 - points) + " needed.");
}
boolean overshot = true;
Loop:
while (overshot = true) {
if (points == 100) {
overshot = false;
break Loop;
}
points = 100 - (points - 100);
System.out.println("Overshot by " + (points - 100) + " points.");
Input = sc.nextLine();
parseSentence(Input);
}
System.out.println("Congratulations you win!");
sc.close();
}
public static int parseSentence(String input) {
String[] pieces = input.split("\\s+");
for (int y = 0; y < pieces.length; y++) {
if (pieces.length > 1) {
if (y == 0) {
parseWord(input);
} else {
parseWord(input, y);
}
} else {
parseWord(input);
}
}
return points;
}
public static int parseWord(String input) {
String[] pieces = input.split("\\s+");
String charList = "aeiouyAEIOUY";
String consanantList
= "bcdfghjklmnpqrstvwxzBCDFGHJKLMNPQRSTVWXZ";
int pointsTemp = 1;
for (int x = 0; x < pieces[0].length(); x++) {
if (charList.indexOf(pieces[0].charAt(x)) != -1) {
pointsTemp *= 2;
} else if (consanantList.indexOf(pieces[0].charAt(x))
!= -1) {
pointsTemp++;
}
}
points = pointsTemp;
return points;
}
public static int parseWord(String input, int number) {
String[] pieces = input.split("\\s+");
String charList = "aeiouyAEIOUY";
String consanantList
= "bcdfghjklmnpqrstvwxzBCDFGHJKLMNPQRSTVWXZ";
int pointsTemp = 1;
for (int x = 0; x < pieces[number].length(); x++) {
if (charList.indexOf(pieces[number].charAt(x)) != -1) {
pointsTemp *= 2;
} else if (consanantList.indexOf(pieces[number].charAt(x)) != -1) {
pointsTemp++;
}
}
points += pointsTemp;
return points;
}
}
You are not using the value returned by the parseSentence method.
Edit: I tried to rewrite this to be as close your original code with making the changes I feel where necessary.
Now Obviously your teacher has requirements and we can't go against that, but some points of interest you should keep in mind.
Multi Splitting
In your example you split the text to get the amount of words. Then instead of looping the already split text. You are sending the original input and then splitting it again. The "Double" splitting is why you needed "three" methods. If you don't double split you can simply loop the length from the single split and just use a single ParseWord method.
Deducting Values
In your example you take away 100 if the player overshot. The problem with this is let's say the person received a score like 200. Then it would loop twice to lower the value submitting the "You overshot message" twice. However let's say by some magical way a score of 100,000,000 was received. Then as you can see we would loop 1 million times to deduct this value essentially creating an not infinite but might as well be infinite loop.
To resolve this problem we simply do the below.
Value = Value % 100.
This will give us the remainder of our Value between 0 and 99. I.e. 167 will equal 67 and 12384 will be equal 84.
Using String (IndexOf)
What this does is takes the Character you provided and loop iterates over the String you provided. The worst case is 12 loops. There's also a lot of other stuff String and IndexOf do that is extra work and I recommend staying away from it if you can.
The alternative solution which I did is take the character and use " | 32" on it. I'm not going to go deep into how bits work, but basically these characters are 8 bit values but we only use 7 of it's bits ranging from 32 to 127. The amount of bits is like the power of 2. so 2^7 = 128 and 2^8 = 256. When we perform the "|" we are turning a bit on so if it's already on it won't change the value.
So in our example let's say we have the value 64.
This is bit 6 turned on. Now we want to turn on bit 5 "32" so the value becomes 96, but if we already had the value 96 and we turn bit 32 on it will still be 32.
Full List of ASCII Characters..
https://www.ascii-code.com/
The Game Loop
In your example you created "TWO" game loops the first one is when you start off, but once you overshot your score you enter the second loop and forget the first one. The problem is now your "Enter Words" and "You Undershot" code are never used anymore. So all someone will see is the line to enter text with no information on what to do or what occurred unless they overshot then they get the overshot message.
To fix this I made a single Game Loop which processes until the code ends via the SCORE == 100. You can see in the code that we begin every game loop with "Enter Words: " and parse the sentence. Then we add up our score and compare. If we undershot we simply restart the loop and try again. If we overshot we reduce the score and try again. If we succeeded we prompt the user if they would like to play again or end the game. Playing again will set the SCORE to 0 and start over the loop. Ending the game will "BREAK" the loop and cause it to end.
The Full Working Code With Recommended Changes
Feel free to comment if you need additional assistance.
import java.util.*;
public class WordGolf1
{
private static int SCORE = 0;
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
while (true)
{
System.out.print("\n\nEnter word: ");
ParseSentence(sc.nextLine());
if (SCORE == 100)
{
System.out.print("\nYou Won! Would you like to play again: Y/N?");
if ((sc.nextLine().charAt(0) | 32) == 'y')
{
SCORE = 0;
System.out.print("\nResetting Game...");
} else {
break;
}
}
else
{
if (SCORE > 100)
{
int overshot = SCORE - 100;
SCORE = SCORE % 100;
System.out.print("\nYou Overshot By " + overshot + " Points. You now have " + SCORE + " points.");
} else {
System.out.print("\nYou currently have " + SCORE + " points you need " + (100 - SCORE) + " more.");
}
}
}
}
private static int ParseSentence(String input)
{
String[] split = input.split(" ");
for (Strng s : input)
SCORE += ParseWord(s);
}
private static int ParseWord(String word)
{
int value = 1;
for (int i = 0; i < word.length(); ++i)
{
int c = (int)word.charAt(i) | 32;
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
{
value *= 2;
} else {
value += 1;
}
}
return value;
}
}
In this situation I cannot use a for loop or a do while loop. I am in a intro programming class and cannot seem to get anything to work for me, I am in need of some help. What we are having to do is to take a text file make java read it and find out how many left parenthesis, right parenthesis, commas, periods, exclamation points, question mark, asterisk, and how many vowels are in the text file. The problem that I am facing with this is that I cannot seem to get it to update the counters correcting and I also cannot get the input.hasNext() as a variable. Anything helps, thanks in advance.
Code here:
import java.util.Scanner;
import java.io.*;
public class PP5_15
{
public static void main(String[]args) throws IOException
{
Scanner input = new Scanner(new File("Chp5.txt"));
input.useDelimiter("");
int R_ParCount = 0;
int L_ParCount = 0;
int ComCount = 0;
int PerCount = 0;
int ExCount = 0;
int QuCount = 0;
int AstCount = 0;
int VowCount = 0;
int NumCount = 0;
while(input.hasNext() == true)
{
if(input.next().contains("("))
R_ParCount++;
else if (input.next().contains(")"))
L_ParCount++;
}
while(input.hasNext())
{
if(input.next().contains("'"))
ComCount++;
else if(input.next().contains("%"))
PerCount++;
}
System.out.println("Amount of Right Parenthese: "+R_ParCount);
System.out.println("Amount of Left Parenthese: "+L_ParCount);
System.out.println("Amount of Commas: "+ComCount);
System.out.println("Amount of Percent Signs: "+PerCount);
System.out.println("Amount of Exclamation Points: "+ExCount);
System.out.println("Amount of Question Marks: "+QuCount);
System.out.println("Amount of Astric Count: "+AstCount);
System.out.println("Amount of Vowels: "+VowCount);
System.out.println("Amount of Numeric Places are: "+NumCount);
}
}
You just need to store the value returned by next() and then do the comparisons:
input.useDelimiter("");
while(input.hasNext())
{
// Get the next letter and convert to char
char c = input.next().charAt(0);
if (c == '(') {
R_ParCount++;
}
else if (c == ')') {
L_ParCount++;
}
else if (c == ',') {
ComCount++;
}
else if (c == '%') {
PerCount++;
}
// etc...
}
import java.util.Scanner;
import java.io.*;
public class CountChars
{
public static void main(String[]args) throws IOException
{
// fine so far
Scanner input = new Scanner (new File("meanVarianceRange.sh"));
input.useDelimiter("");
// counting everything is more easy, than counting 10 different things
int[] charcount = new int [256];
// except for the vowels, which is aeiou=5 + 5 (uppercase)
int vowels = 0;
// not to mention 10 ciphers, if I understood correctly
int numerics = 0;
while (input.hasNext ())
{
char c = input.next ().charAt (0);
// we use the char as index into our array and just increment
++charcount [c];
// but for the vowels, we count them as group, too
if ("aeiouAEIOU".contains ("" + c))
++vowels;
// in contrast, digits are ordered in the ascii table,
// so we can express them as >= '0' and <= '9'
if (c >= '0' && c <= '9')
++numerics;
}
// see, how the char itself makes the code self commenting:
System.out.println ("Amount of Right Parenthese: " + charcount[')']);
System.out.println ("Amount of Left Parenthese: " + charcount['(']);
System.out.println ("Amount of Commas: " + charcount[',']);
System.out.println ("Amount of Percent Signs: " + charcount['%']);
System.out.println ("Amount of Exclamation Points: " + charcount['!']);
System.out.println ("Amount of Question Marks: " + charcount['?']);
System.out.println ("Amount of Astric Count: " + charcount['*']);
System.out.println ("Amount of Vowels: " + vowels);
// (charcount['a'] + charcount['a'] + charcount['e'] + charcount['i'] + charcount['o'] + charcount['u']));
System.out.println ("Amount of Numeric Places are: " + numerics);
}
}
Since the method 'contains' in String expects a String, we have to use this special transformation from char to String (of length 1), to find our char: .contains ("" + c). Well - there are alternatives, like indexOf and testing for >= 0.
Characters can flawlessly be converted into ints (but not the other way round). That's why we can use the char itself as index into our int-array, which contains as value of charcount['x'] the number of increments, we performed at that index.
Note, that I changed the input file name, to match something on my drive.
Test:
Amount of Right Parenthese: 11
Amount of Left Parenthese: 11
Amount of Commas: 0
Amount of Percent Signs: 1
Amount of Exclamation Points: 1
Amount of Question Marks: 1
Amount of Astric Count: 7
Amount of Vowels: 43
Amount of Numeric Places are: 19
My app lets users search a location and one of the queries I got was
"78°14'09"N 15°29'29"E"
Obviously the user wants to go to this location.
First how do I check if this string fits the decimal format correctly. Then how do I convert it to double format?
double latitude = convertToDouble("78°14'09"N")
I searched here on stackoverflow but they are all looking for the opposite: double to decimal.
78°14'09"N 15°29'29"E
First how do I check if this string fits the decimal format correctly. Then how do I convert it to double format?
The string is not in decimal (degrees) format. It is in degrees, minutes, and seconds, which is more or less the opposite of decimal degrees format. I therefore interpret you to mean that you want to test whether the string is in valid D/M/S format, and if so, to convert it to decimal degrees, represented as a pair of doubles.
This is mostly a parsing problem, and regular expressions are often useful for simple parsing problems such as this one. A suitable regular expression can both check the format and capture the numeric parts that you need to extract. Here is one way to create such a pattern:
private final static Pattern DMS_PATTERN = Pattern.compile(
"(-?)([0-9]{1,2})°([0-5]?[0-9])'([0-5]?[0-9])\"([NS])\\s*" +
"(-?)([0-1]?[0-9]{1,2})°([0-5]?[0-9])'([0-5]?[0-9])\"([EW])");
That's a bit dense, I acknowledge. If you are not familiar with regular expressions then this is no place for a complete explanation; the API docs for Pattern provide an overview, and you can find tutorials in many places. If you find that your input matches this pattern, then not only have you verified the format, but you have also parsed out the correct pieces for the conversion to decimal degrees.
The basic formula is decimal = degrees + minutes / 60 + seconds / 3600. You have the additional complication that coordinates' direction from the equator / prime meridian might be expressed either via N/S, E/W or by signed N, E, or by a combination of both. The above pattern accommodates all of those alternatives.
Putting it all together, you might do something like this:
private double toDouble(Matcher m, int offset) {
int sign = "".equals(m.group(1 + offset)) ? 1 : -1;
double degrees = Double.parseDouble(m.group(2 + offset));
double minutes = Double.parseDouble(m.group(3 + offset));
double seconds = Double.parseDouble(m.group(4 + offset));
int direction = "NE".contains(m.group(5 + offset)) ? 1 : -1;
return sign * direction * (degrees + minutes / 60 + seconds / 3600);
}
public double[] convert(String dms) {
Matcher m = DMS_PATTERN.matcher(dms.trim());
if (m.matches()) {
double latitude = toDouble(m, 0);
double longitude = toDouble(m, 5);
if ((Math.abs(latitude) > 90) || (Math.abs(longitude) > 180)) {
throw new NumberFormatException("Invalid latitude or longitude");
}
return new double[] { latitude, longitude };
} else {
throw new NumberFormatException(
"Malformed degrees/minutes/seconds/direction coordinates");
}
}
The convert() method is the main one; it returns the coordinates as an array of two doubles, representing the coordinates in decimal degrees north and east of the intersection of the equator with the prime meridian. Latitudes south of the equator are represented as negative, as are longitudes west of the prime meridian. A NumberFormatException is thrown if the input does not match the pattern, or if the latitude or longitude apparently represented is invalid (the magnitude of the longitude cannot exceed 180°; that of the latitude cannot exceed 90°).
You won't be able to parse that into a double without removing the non number chars but,
String string = "78°14'09"N";
Double number = 0;
try{
number = Double.parseDouble(string);
//do something..
}catch (NumberFormatException e){
//do something.. can't be parsed
}
If you first remove any characters from the string that are not alphanumeric, then something along these lines will work. This code compiles.
public class HelloWorld{
public static void main(String []args){
String input = "78 14'09 N 15 29'29 E".replaceAll("[^A-Za-z0-9]", " ");
String[] array = input.split(" ");
int nDegree = Integer.parseInt(array[0]);
int nMinute = Integer.parseInt(array[1]);
int nSecond = Integer.parseInt(array[2]);
int eDegree = Integer.parseInt(array[4]);
int eMinute = Integer.parseInt(array[5]);
int eSecond = Integer.parseInt(array[6]);
double nDegrees = nDegree + (double) nMinute/60 + (double) nSecond/3600;
double eDegrees = eDegree + (double) eMinute/60 + (double) eSecond/3600;
String nResult = "Decimal = N " + Double.toString(nDegrees).substring(0,10);
String eResult = "Decimal = E " + Double.toString(eDegrees).substring(0,10);
System.out.println(nResult);
System.out.println(eResult);
}
}
Output:
Decimal = N 78.2358333
Decimal = E 15.4913888
The problem is that Java can't store the degrees ° character as part of a String, or internal quotes (the minute character). If you can find a way to remove them from the string before inputting the data, then this will work.
I don't have a solution for handling the degrees symbol, but you could use an escape symbol \" to allow the use of a quotation mark within a string.
So I've used a regex with capturing groups to grab each of the numbers and the N/S/E/W. After capturing each individually it's just a matter of doing a bit of dividing to get the numbers and then formatting them however you'd like. For example I went with 5 digits of precision here.
public static void main(String[] args) {
String coords = "78°14'09N 15°29'29E";
String[] decimalCoords = degreesToDecimal(coords);
System.out.println(decimalCoords[0]);
System.out.println(decimalCoords[1]);
}
public static String[] degreesToDecimal(String degMinSec) {
String[] result = new String[2];
Pattern p = Pattern.compile("(\\d+).*?(\\d+).*?(\\d+).*?([N|S|E|W]).*?(\\d+).*?(\\d+).*?(\\d+).*?([N|S|E|W]).*?");
Matcher m = p.matcher(degMinSec);
if (m.find()) {
int degLat = Integer.parseInt(m.group(1));
int minLat = Integer.parseInt(m.group(2));
int secLat = Integer.parseInt(m.group(3));
String dirLat = m.group(4);
int degLon = Integer.parseInt(m.group(5));
int minLon = Integer.parseInt(m.group(6));
int secLon = Integer.parseInt(m.group(7));
String dirLon = m.group(8);
DecimalFormat formatter = new DecimalFormat("#.#####", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
formatter.setRoundingMode(RoundingMode.DOWN);
result[0] = formatter.format(degLat + minLat / 60.0 + secLat / 3600.0) + " " + dirLat;
result[1] = formatter.format(degLon + minLon / 60.0 + secLon / 3600.0) + " " + dirLon;
}
return result;
}
There is no error handling here, it's just a basic example of how you could make this work with your input.
I got this code that fetches floats from a database.
for (int i = 0; i < ingredient.size() ; i++) {
Ingredient ing = (Ingredient) ingredient.get(i);
ingredients += String.valueOf(ing.getAmount()) + " " +
ing.getUnit() + " " + ing.getIngredient() + "\n";
}
The database is written in REAL values as some of them is 1.5, 2.5, 1.4 etc. But we also have these whole numbers without the need of a decimal, such as 1, 4, 10 etc.
The problem is that the database table needs to be in REAL value, which gives us no choice but to give all the values one decimal, no matter if it's needed or not.
So we'll end up with values like:
1.0
1.5
2.3
20.0
5.0
My question is: How do we remove the unnecessary decimals, but keep the ones that need it?
One very simple way to remove these would be to strip the characters using StringUtils.
String displayValue = String.valueOf(ing.getAmount());
displayValue = StringUtils.stripEnd(displayValue, ".0");
For an input of "1.0", "1" will be returned.
A more technical approach would be to use the modulus operator %
For example:
if(value%1 == 0){ //1 divides into number perfectly, there is no decimal
//cast value to integer or another non decimal variable
} else {
//use existing value as it contains a decimal
}
How about this (does't require any fancy things like StringUtils)?
String s = String.valueOf(1.0);
System.out.println(s);
/* Make this block as a function and return an int */
String ss = " ";
if (s.charAt(s.length()-2) == '.' && s.charAt(s.length()-1) == '0'){
ss = s.substring(0,s.length()-2);
System.out.println(ss);
}
/**************************************************/
int converted = Integer.parseInt(ss);
System.out.println(converted);
}
If you want to make it a function block, you can.
You can check it working on IDEONE - http://ideone.com/udJv8M
Check the float values with modulo. If 0 is returned it is an Integer. Here is an example with the numbers you have mentioned:
List<Float> values = new ArrayList<Float>();
values.add(new Float(1.0f));
values.add(new Float(1.5f));
values.add(new Float(2.3f));
values.add(new Float(20.0f));
values.add(new Float(5.0f));
List<String> strValues = new ArrayList<String>();
for(Float value : values)
{
String strValue = "";
if(value % 1 == 0)
{
Integer intValue = value.intValue();
strValue = intValue.toString();
strValues.add(strValue);
}
else
{
strValue = value.toString();
strValues.add(strValue);
}
System.out.println(strValue);
}
You can use a custom DecimalFormat pattern:
public static String customFormat(String pattern, double value) {
DecimalFormat myFormatter = new DecimalFormat(pattern);
return myFormatter.format(value);
}
Then a pattern of # defines places holders for optional digits, so #.### will give up to 3 digits where necessary only.
for (int i = 0; i < ingredient.size() ; i++) {
Ingredient ing = (Ingredient) ingredient.get(i);
ingredients += customFormat("#.###", ing.getAmount()) +
" " + ing.getUnit() + " " + ing.getIngredient() + "\n";
}
So don't convert your data to a String except for display only. Real numbers can represent both integers and floating point numbers using the same data type. Plus if you ever needed to do any math on your numbers you can't use Strings to do that. If you convert your numbers from the database directly to String before storing them into Ingredient then you've screwed yourself later on if you want to do calculations on those numbers. (Say you wanted to add a feature to double a recipe and have all of the quantities change for the user). Under your current plan you're preventing yourself from doing something like that because you're overly focused on the display of that number.
Instead just create a method on Ingredient to convert your numbers using String.format(). Like so:
public class Ingredient {
private double amount;
private String name;
public String asDecimal() {
return String.format("%.1f", amount);
}
public String asInteger() {
return String.format("%.0f", amount);
}
public String asFraction() {
// exercise left to the reader
}
}
You could even add a function that converts decimals to fractional amounts to make it easier to display things chiefs might understand vs decimals which are harder. Bear in mind String.format() will round floating point amounts (0.5 -> 1 using as Integer).
Convert your String returned from ing.getAmount() to a Float object, then use the modulo function to determine whether your value is an exact multiple of 1 (ie no decimal places). If so, convert your Float object to an int, which will concatenate the decimals.
Float f = Float.valueOf(ing.getAmount());
if(f%1 == 0) {
// Use f.intValue() to concatenate your decimals.
ingredients +=String.valueOf(f.intValue() + " " + ing.getUnit() + " " + ing.getIngredient() + "\n";
}
else {
ingredients +=String.valueOf(ing.getAmount()) + " " + ing.getUnit() + " " + ing.getIngredient() + "\n";
}
I hope this helps.
//In the following lines of code the user is asked to enter a length to determine the volume of a regular icosahedron, however, when entered the programm always outputs 0.0 as the answer for the volume???
import java.io.*; //allows I/o statements
class VolumeIcosahedron //creating the 'volumeIcosahedron' class
{
//allows strings with exceptions to IO = input/output
public static void main (String[] args) throws IOException
{
BufferedReader myInput = new BufferedReader(
new InputStreamReader (System.in)); //system input/ output
String stringNum; // the number string
double V; // integer with decimals volume
int L; // integer required length
//System output
System.out.println("Hello, what is the required length");
stringNum = myInput.readLine();
L = Integer.parseInt(stringNum);
V = 5/12 *(3 + Math.sqrt(5))*(L*L*L);
System.out.println("The volume of the regular Icosahedron is " + V);
}
}
Because 5/12 in integer equals 0 so it always results in 0.
Try with 5.0 to force the division without involving integer division.
V = 5.0/12 *(3.0 + Math.sqrt(5))*(L*L*L);
I think this is the offending line:
V = 5/12 *(3 + Math.sqrt(5))*(L*L*L);
5/12 returns an int (whole number), which is always truncated down to 0, hence 0 * anything will return 0.
Change it to this, using the letter d to signify that these numbers are of type double:
V = 5d/12d *(3 + Math.sqrt(5))*(L*L*L);
The reason is that you are using integer inside the calculation.
With integer, you should see the division as an euclidean operation, ie a = bq + r.
So in your program, 5/12 will always return 0 (5 = 0 * 12 + 5).
If you change the line to be like this (replacing every integer by double):
V = 5.D/12.D *(3.D + Math.sqrt(5.D))*(L*L*L);
Then the result will be different.