so i'm a beginner in java and i recently had an assignment to calculate the distance between two integer points using the distance formula. so far I had
import java.util.Scanner;
// user inputs two coordinates (x, y) (x2, y2) and program outputs distance
public class Distance {
public static void main (String[] args) {
try (Scanner scan = new Scanner(System.in) {
System.out.println("Input coordinate 1 with a comma and no space.");
String coord1 = scan.nextLine();
System.out.println("Input coordinate 2");
String coord2 = scan.nextLine();
coord1 = coord1.trim();
coord2 = coord2.trim();
int comma1 = coord1.indexOf(",");
int comma2 = coord2.indexOf(",");
String coordX1 = coord1.substring(0, comma1);
int valueX1 = Integer.parseInt(coordX1);
String coordY1 = coord1.substring(comma1 + 1);
int valueY1 = Integer.parseInt(coordY1);
String coordX2 = coord2.substring(0, comma2);
int valueX2 = Integer.parseInt(coordX2);
String coordY2 = coord2.substring(comma2 + 1);
int valueY2 = Integer.parseInt(coordY2);
double distance = Math.sqrt(Math.pow(valueX2 - valueX1, 2) + Math.pow(valueY2 - valueY1, 2));
System.out.println(distance);
}
}
}
and this program works only because the user doesn't input a space, and when I try adding the .trim to coord1 and coord2 by putting a line beneath it "coord1 = coord1.trim();" and "coord2 = coord2.trim();" I get this error
Exception in thread "main" java.lang.NumberFormatException: For input string: " 0"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Integer.parseInt(Integer.java:654)
at java.base/java.lang.Integer.parseInt(Integer.java:786)
at Avg.main(Avg.java:17)
I want to make it so that the system can accept a space, as in math nobody puts coordinates like (x,y) its always (x, y). apologies if my code isnt minimal as i'm just getting started with learning code.
Note that .trim() only removes the trailing spaces and it won't remove spaces in between the characters in your String.
There are quite a few ways to remove all spaces within your String. One way I usually use is by doing:
coord1 = coord1.replaceAll("\\s","");
coord2 = coord2.replaceAll("\\s","");
After removing the whitespaces, you can use .split() to delimitate the input:
String coordX1 = coord1.split(",")[0];
String coordY1 = coord1.split(",")[1];
int valueX1 = Integer.parseInt(coordX1);
int valueY1 = Integer.parseInt(coordY1);
Same goes for your coordX2 and coordY2
Related
I would like to ask how do I do that when the cycle starts and go over again, the string variable name will increase by 1. This program is supposed to ask you how many patients are you going to write. If you write for ex. 10, then the cycle will go for 10 times and it will ask all those information I want and then add them to the array which I have already created called BMI. This whole program is supposed to print you a table which contains Name, Height in meters, weight in Kg, your calculated BMI and then text in what state of BMI are you ATM. The problem is how do I do it? I just started learning arrays and stuff like that and my teacher gave me this homework. I don't think that this homework is hard but just hard to understand what to do.
Things I already tried is creating a for cycle with String called name something like this: String name(); but that obviously did not work.
import java.util.Scanner;
class Pacient {
public static void main(String args[]){
int pole;
Scanner input = new Scanner(System.in);
String pacient;
System.out.print("Zadej kolik bude pacientu: "); //How many patients do you want? For ex. 10
pacient = input.nextLine();
input.nextLine();
pole = Integer.parseInt(pacient);
String[][] bmi = new String[4][pole]; //This is supposed to make an array with my patients.
double vaha; //weight
double vyska; //height
String jmeno; //name
double telo1, telo2; //body for calc.
String vysledek; //result
int i,x=0,j, pa=0, k=0; //some variables
bmi[0][0] = "Jmeno"; //First line of final table NAME
bmi[0][1] = "Vaha"; // WEIGHT
bmi[0][2] = "Vyska"; //HEIGHT
bmi[0][3] = "BMI"; //BMI based on calc.
bmi[0][4] = "Text"; //Final result
for(int y=1;y<pole;y++){
pa++;
x++;
System.out.print("Zadej svoje krestni jmeno: ");
jmeno = input.nextLine();
System.out.print("Zadej svoji vahu v Kg: ");
vaha = input.nextDouble();
System.out.print("Zadej svoji vysku v m: ");
vyska = input.nextDouble();
System.out.println("Vase informace byly uspesne ulozeny! ");
bmi[1][0] = jmeno; //These values should somehow increase but idk
how atm and be assign with the patient which
will be printed at the end.
bmi[1][1] = vaha2;
bmi[1][2] = vyska2;
bmi[1][3] = telo3;
bmi[1][4] = vysledek;
}
// System.out.println("Tisknu tabulku");
// telo1 = vyska * vyska; //Some calc. of BMI
// telo2 = vaha / telo1;
// if (telo2 < 18.5) { //Adding text to the result variable
// vysledek = "mate podvahu";
// } else if (telo2 < 25) {
// vysledek = "Jste v normach";
// } else if (telo2 < 30) {
// vysledek = "Nadvaha";
// } else {
// vysledek = "Obezita";
// }
// String telo3 = String.valueOf(telo2); //Converting to strings
// String vyska2 = String.valueOf(vyska);
// String vaha2 = String.valueOf(vaha);
System.out.println("--------------------------------------------------");
for(i=0;i<pole;i++) {
for(j = 0; j<5; j++) System.out.print(bmi[i][j] + " ");
System.out.println();
}
System.out.println("--------------------------------------------------");
}
}
Atm the program is just printing most of the time NULL NULL NULL NULL, and it does not match with the patient number. How do add all this code to for cycle and make it automatic convert int and double to strings and then print them correctly and assign them to the BMI Array. If you have any further questing, feel free to ask.
I have corrected the issues in code. Everything is explained step-by-step in comments. I have converted variable name in English for my understanding. If you have questions. Please ask.
import java.util.Scanner;
class Pacient {
private static Scanner input;
public static void main(String args[]) {
int numberOfPatients; // Variables that saves number of patient
// Asking user the number of patients
input = new Scanner(System.in);
System.out.print("How many patients do you want?: ");
// I have change this to nextInt
// From javadoc "Scans the next token of the input as an int"
// It is essentially next() + parseInt()
numberOfPatients = input.nextInt();
// nextInt() does not move cursor to next line
// using nextLine() here would move it to next line and close
// previous line otherwise it creates issue when you will use next/nextLine again
input.nextLine();
// String[][] array = new String[Rows][Columns];
// For each patient there is a row. Since in the code there is header
// as well that's why we need numberOfPatients + 1
String[][] bmi = new String[numberOfPatients + 1][5];
// All corresponding columns
bmi[0][0] = "Name"; // First line of final table NAME
bmi[0][1] = "Weight"; // WEIGHT
bmi[0][2] = "Height"; // HEIGHT
bmi[0][3] = "BMI"; // BMI based on calc.
bmi[0][4] = "Result"; // Final result
// Starting from 1. Skipping header
for (int y = 1; y <= numberOfPatients; y++) {
// Using y instead of an int. This way the loop will
// automatically move to next row
// Instead of saving it to variable and then to array
// I am saving it directly
System.out.print("Enter your first name: ");
bmi[y][0] = input.nextLine();
System.out.print("Enter your weight in Kg: ");
bmi[y][1] = input.nextLine();
System.out.print("Enter your height in m: ");
bmi[y][2] = input.nextLine();
// Using the information from above to calculate BMI
// Basically I am storing and calculating at the same time
// parseDouble converts String into double
// Math.pow(a,b) is powber function. a is base and b is exponent
double weight = Double.parseDouble(bmi[y][1]);
double heightSquare = Math.pow(Double.parseDouble(bmi[y][2]), 2);
double bmiCalculated = weight / heightSquare;
// Based on BMI assigning result in result column
bmi[y][3] = bmiCalculated + "";
if (bmiCalculated < 18.5) {
bmi[y][4] = "You are underweight";
} else if (bmiCalculated > 18.5 && bmiCalculated < 25) {
bmi[y][4] = "You are normal";
} else if (bmiCalculated > 25 && bmiCalculated < 30) {
bmi[y][4] = "You are overweight";
} else {
bmi[y][4] = "You are obese";
}
System.out.println("Your information has been saved successfully!");
}
System.out.println("--------------------------------------------------");
// In java 2D arrays are multiple 1D array stacked on each other
// bmi.length gives the number of rows
// Basically you iterate through each row and print each individual row
// like 1D array
for (int i = 0; i < bmi.length; i++) {
// bmi[i] gives ith row. Which is 1D array. So you can print it like normal array
for (int j = 0; j < bmi[i].length; j++)
System.out.print(bmi[i][j] + " ");
System.out.println();
}
System.out.println("--------------------------------------------------");
}
}
Your declaration of array and implementation is conflicting. You've fixed the first dimension and kept the second, variable. But you're using as if the first one is variable and second is fixed.
You should declare your array like
String[][] bmi = new String[pole+1][4];
pole+1 because you're using first row for table headings
Your first loop should look like this
for(int y = 1; y < pole+1; y++){
for(int z = 0; z < 4; z++){
String data="ask user for data";
bmi[y][z] = data; //similar for all
}
}
Your output for loop will also look like above.
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
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.
in the program below you can see that i've allowed the input of the user to give a direction such as n100 which will draw a line north and move it 100 spaces but How am I able to allow the sketch program to do diagonal lines as well as straight lines, I understand I am able to change the input to (0,2) to allow diagonal lines by using something like ne but then my program doesn't like when I use directions such as n, e, s, w.
What can I do to allow both lines?
this is the code below:
boolean okToProcess = true;
String message = "";
int colourInt;
String input = in.getText();
String direction = input.substring(0, 1);
String distance = input.substring(1);
double distanceAsDouble = 0;
if (direction.equals("n"))
t.heading(0);
else if (direction.equals("ne"))
t.heading(45);
else if (direction.equals("e"))
t.heading(90);
else if (direction.equals("se"))
t.heading(135);
else if (direction.equals("s"))
t.heading(180);
else if (direction.equals("sw"))
t.heading(225);
else if (direction.equals("w"))
t.heading(270);
else if (direction.equals("nw"))
t.heading(315);
else {
okToProcess = false;
message += "bad direction: " + direction + " ";
}
if (isNumeric(distance)) {
distanceAsDouble = Double.parseDouble(distance);
}
else{
okToProcess = false;
message += "bad distance: " + distance;
}
if (okToProcess) {
if (!EtchASketchClipped(t, distanceAsDouble)) {
t.setLineWidth(3);
If you use
String direction = input.substring(0, 1);
String distance = input.substring(1);
you are storing and comparing only the first character of the string and eventually assign an invalid number to distance, as if the direction is diagonally, the second character is prepended to direction. Use String.startsWith() to check for a given direction. Inside the if-statement, decide wether to start the distance at the second or third character. You can also just use input as a value to check.
...
String distance ;
double distanceAsDouble = 0;
if (input.startsWith("n")) {
t.heading(0);
distance = input.substring(1);
} else if (input.startsWith("ne")) {
t.heading(45);
distance = input.substring(2);
} else if ...
String direction = input.replaceFirst("^(\\D*)(.*)$", "$1");
String distance = input.replaceFirst("^(\\D*)(.*)$", "$2").trim();
Where the regular expression means
\\D matches non-digit
\\d matches digit
postfix * for 0 or more
. for any char
^ begin
$ end
() group numbered from 1
$1 group 1
I am in need of assistance with my Java program assignment. The assignment is to calculate the distance between two points using java. I completed part one as followed:
import java.util.Scanner;
public class DistanceCalcEasy
{
public static void main(String[] args)
{
// Creating a new scanner object
System.out.println("Distance Calculator");
Scanner input = new Scanner(System.in);
// Getting all of the coordinates
System.out.print("Enter the X coordinate of the first point: ");
double x1 = input.nextDouble();
System.out.print("Enter the Y coordinate of the first point: ");
double y1 = input.nextDouble();
System.out.print("Enter the X coordinate of the second point: ");
double x2 = input.nextDouble();
System.out.print("Enter the Y coordinate of the second point: ");
double y2 = input.nextDouble();
// Calculating the distance between the points
double distance = Math.sqrt( Math.pow((x2-x1),2) + Math.pow((y2-y1),2) );
// Printing the distance to the User
System.out.println("The distance between the points is " + distance);
}
}
Now the problem is I need to do this same program again but the "hard way" by allowing the user to input a coordinate like 1,2 instead of each x and y on their own line. This is what I have started to come up with after a little bit of research:
import java.util.Scanner;
public class DistanceCalcHard
{
public static void main(String[] args)
{
// Creating a new Scanner Object
System.out.println("Distance Calculator");
Scanner input = new Scanner(System.in);
// Getting the data points
System.out.print("Enter the first point x,y: ");
String firstPoint = input.nextLine();
System.out.print("Enter the second point x,y: ");
String secondPoint = input.nextLine();
Scanner scan = new Scanner(firstPoint).useDelimiter("\\s*,\\s*");
while (scan.hasNextDouble() )
{
}
// Calculating the distance
// Displaying the distance to the user
}
}
Does that seem like a good start? I was thinking I could make two array's, one for each point, and then do my distance calculation that way. Is there a simpler way to do this or can someone point me in a better direction? Thank You
An easier way to go about splitting the string into two values (ie. x,y -> x and y) would be by using the split() operator for a String object.
String[] pointA = firstPoint.split(",");
And the same can be done for the second point. Now you have your two points in arrays where pointA[0] is the x value and pointA[1] is the y value.
More documentation about the method can be found here
How about something like this:
import java.util.Scanner;
public class DistanceCalcEasy
{
public static void main(String[] args)
{
// Creating a new scanner object
System.out.println("Distance Calculator");
Scanner input = new Scanner(System.in);
// Getting all of the coordinates
System.out.print("Enter the X,Y coordinate of the first point: ");
String xy1in = input.nextLine();
System.out.print("Enter the X,Y coordinate of the second point: ");
String xy2in = input.nextLine();
String[] xy1 = xy1in.split(",");
String[] xy2 = xy2in.split(",");
double x1 = Double.parseDouble(xy1[0]);
double y1 = Double.parseDouble(xy1[1]);
double x2 = Double.parseDouble(xy2[0]);
double y2 = Double.parseDouble(xy2[1]);
// Calculating the distance between the points
double distance = Math.sqrt( Math.pow((x2-x1),2) + Math.pow((y2-y1),2) );
// Printing the distance to the User
System.out.println("The distance between the points is " + distance);
}
}