我正在尝试编写一个程序来计算标准输入中两点之间的距离。但必须从同一行读取这两点。 例如(25,2)(26,15)。我被困在一个我无法将这些输入放在一行上的部分。 到目前为止我有这个:
/*
This Distance Program calculates the distance between two points
*/
package distance;
/**
*
* @author
*/
import java.util.Scanner;
public class Distance {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("X1");
try {
double x1 = input.nextDouble();
double y1 = input.nextDouble();
double x2 = input.nextDouble();
double y2 = input.nextDouble();
double dist = Math.sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));
System.out.println("Distance between two points is: " + dist);
} catch (Exception E) {
System.out.println(E);
}
}
}
答案 0 :(得分:3)
如果输入的格式是##.## ##.## ##.## ##.##
(每个##.##
是一个双精度,并且它不需要有小数位,例如它可以是整数,例如5) ,这意味着数字用空格分隔,然后这将起作用:
String line = input.nextLine();
String[] points = line.split("\\s+");
if(points.length() == 4){
double x1 = Double.parseDouble(points[0]);
double y1 = Double.parseDouble(points[1]);
double x2 = Double.parseDouble(points[2]);
double y2 = Double.parseDouble(points[3]);
//and the rest is the same
}
这样做,是从输入中读取String
。然后它通过它们之间的空格分割该字符串(\\s+
将字符串拆分为在它们之间有一个或多个空格的字符串)。字符串数组实际上是双精度数,因此我们将它们转换为双精度数。
注意:如果输入不是双精度,则会出错。
答案 1 :(得分:2)
这里的密钥是:您必须具体关于用户应提供的确切格式。是的,输入单个字符串并解析该内容是个好主意,但是......您在问题中提出了这个示例(25,2) (26,15)
。该字符串将不与Itamars解决方案一起使用。
所以重点是:在你开始思考之前"我如何解析用户输入",你必须澄清你自己你期望/希望用户输入的那些两个坐标给你。
含义:如果您的用户为您提供了" n1 n2 n3 n4" (所以4个数字);你可以使用\ s +进行拆分。如果您的用户给你" n1,n2,n3,n4)"然后你应该分开","例如。
并允许你给定的格式"(x1,y1)(x2,y2)"你可能会首先拆分\ s +(给你两个字符串;然后再使用""再次拆分。或者你学习正则表达式,因为它们使这样解析很多更容易写下来。
长话短说:不要处理不清楚的要求。
最后:还要准确使用类型。您在代码中使用 double ;但这真的是你需要的吗?作为输入示例......仅使用整数。当然,双重将始终有效;但是当你希望你的用户使用整数时,你应该使用int或long!
答案 2 :(得分:1)
正如@GhostCat指出的那样,您可以使用regex来检查用户输入格式。我实施了一个可能的解决方案。
^(( - ?\ d +),( - ?\ d +))\ S(( - ?\ d +),( - ?\ d +))$
正则表达式将字面上匹配括号,逗号和空格,并且它将分组捕获四个数字。即。
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Distance {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Insert two point to calculate the distance. Format: (x1,y1) (x2,y2) : ");
Pattern pattern = Pattern.compile("^\\((-?\\d+),(-?\\d+)\\)\\s\\((-?\\d+),(-?\\d+)\\)$");
Matcher matcher = pattern.matcher( input.nextLine ( ) );
if ( matcher.matches ( ) )
{
System.out.println ( "Good" );
double dist = Math.sqrt( Math.pow ( Long.parseLong ( matcher.group(3) ) - Long.parseLong ( matcher.group(1) ) , 2 ) +
Math.pow ( Long.parseLong ( matcher.group(4) ) - Long.parseLong ( matcher.group(2) ) , 2 ) );
System.out.println ( "Distance: " + dist );
}
else
{
System.out.println ( "Wrong input format" );
}
}
}
注意:由于您使用的是Math类,我建议使用pow代替原始乘法。
注2:在java中,以反斜杠(\)开头的字符是转义序列,对编译器具有特殊含义。这就是为什么在代码中你必须追加一个。
Insert two point to calculate the distance. Format: (x1,y1) (x2,y2) :
2 3 4 5
Wrong input format
Insert two point to calculate the distance. Format: (x1,y1) (x2,y2) :
(-2,-3) (-4,4)
Good
Distance: 7.280109889280518
您还可以验证积分范围。如果你创建一个像这样的静态方法,那就更清楚了。
public static boolean rangeInclusive(int x, int y, int min, int max)
{
return x>=min && x<=max && y>=min && y<=max;
}
如果x和y在最小 - 最大范围内,则返回true。否则就错了。
表示只有当点在范围内时才进行数学运算,如下所示:
if ( matcher.matches ( ) )
{
if( rangeInclusive ( Integer.parseInt ( matcher.group(1) ) , Integer.parseInt ( matcher.group(2) ), -50 , 50 ) &&
rangeInclusive ( Integer.parseInt ( matcher.group(3) ) , Integer.parseInt ( matcher.group(4) ), -50 , 50 ))
{
double dist = Math.sqrt( Math.pow ( Long.parseLong ( matcher.group(3) ) - Long.parseLong ( matcher.group(1) ) , 2 ) +
Math.pow ( Long.parseLong ( matcher.group(4) ) - Long.parseLong ( matcher.group(2) ) , 2 ) );
System.out.println ( "Distance: " + dist );
}
else
{
System.out.println ( "Wrong range" );
}
}