猿问

(Java) 如何解析具有多种可能格式的坐标字符串,并将它们转换为整数?

我有一个方法可以从用户那里接收 (X,Y) 坐标字符串。X 和 Y 坐标的范围都从 0 到 8,坐标可以是五种可能的格式之一:

  • (4,3) : 括号中的 X 和 Y 坐标,并以逗号分隔且无空格

  • 4 3 : X 和 Y 坐标仅由空格分隔,无括号

  • 4,3 : X 和 Y 坐标仅由逗号分隔,没有括号

  • d 3:用字母表示的X。0=A, 1=B, ..., 8=H。X 和 Y 由空格分隔

  • d3 : 除了没有空格外,同上。

我遇到的问题是开发一种可以成功解析所有四种格式的方法。更具体地说,我想成功地将 X 和 Y 坐标转换为两个单独的整数并将它们存储在某处,无论使用哪种格式。

我对java有点陌生,并且没有太多解析字符串的经验。任何指针将不胜感激。


胡说叔叔
浏览 153回答 3
3回答

一只斗牛犬

首先让我们考虑一个主格式。我们想要将所有这些转换为的格式,以便最终将它们转换为两个整数。让我们将此格式设置为由空格分隔的两个数字。这是 IMO 最容易解析的。然后,让我们考虑所有这些共享的模式。例如,第一个输入保证只有一个括号,所以我们可以很容易地识别出来。第三个保证包含逗号,但没有括号。因此,我们可以用规则将它们分组,如果它有逗号,则删除括号(如果有)并将逗号替换为空格。这是三个下降,2个去。现在,这最后两个有什么共同点?他们共享一封信。我们可以使用正则表达式轻松捕获这封信,但让我们稍后再考虑。所以,让我们制定一个逻辑规则。如果短语没有逗号,我们检查它是否有字母。如果是,我们检查它是否有空格。如果是这样,我们按空格分割,并用其整数等值替换字符,正确偏移以表示其在字母表中的位置。否则,我们使用正则表达式按字母拆分,并执行上述操作。现在我们对我们想要完成的事情有了一个清晰的印象,让我们自己尝试一下。这就是我在代码中的做法。  public int[] parseXYCoord(String s) {    String master=s;    if(s.contains(",")){        master=master.replace("(","").replace(")","");        master=master.replace(","," ");    }else if(master.matches("^[a-z]((\\s[0-8])|[0-8])$")){        int charValue=master.charAt(0)-'a'+1;        master=charValue+" "+master.charAt(master.contains(" ")?2:1);    }    return parseMaster(master);}private int[] parseMaster(String master) {    if(!master.matches("^[0-8] [0-8]$"))        throw new IllegalArgumentException("Inputted Number is incorrect!");    String[] splitMaster=master.split(" ");    return new int[]{Integer.parseInt(splitMaster[0]),Integer.parseInt(splitMaster[1])};}我不太擅长正则表达式。虽然它很丑陋,但它确实完成了工作。如果您想学习如何使用正则表达式,请查看站点DebugRegex。测试它使用    System.out.println(Arrays.toString(parseXYCoord("4,3")));    System.out.println(Arrays.toString(parseXYCoord("4 3")));    System.out.println(Arrays.toString(parseXYCoord("(4,3)")));    System.out.println(Arrays.toString(parseXYCoord("d3")));    System.out.println(Arrays.toString(parseXYCoord("d 3")));它打印[4, 3][4, 3][4, 3][4, 3][4, 3]

慕尼黑8549860

您可以按照以下步骤执行此操作:删除所有不是数字或字母的字符,您将以粘贴 2 个字符结尾看看这两个:如果数字:解析为 int如果不删除字符代码'a'并添加+1以获得a=1, b=2, ...private static int[] parseToCoord(String s) {    String[] xy = s.replaceAll("[^\\w\\d]", "").toLowerCase().split("");    int[] res = new int[2];    res[0] = xy[0].matches("\\d") ? Integer.parseInt(xy[0]) : xy[0].charAt(0) - 'a' + 1;    res[1] = xy[1].matches("\\d") ? Integer.parseInt(xy[1]) : xy[1].charAt(0) - 'a' + 1;    return res;}该Stream版本是private static int[] parseToCoordStream(String s) {    return Stream.of(s.replaceAll("[^\\w\\d]", "").toLowerCase().split(""))            .mapToInt(val -> val.matches("\\d") ? Integer.parseInt(val) : val.charAt(0) - 'a' + 1)            .toArray();}用public static void main(String args[]) throws Exception {    for (String s : Arrays.asList("(4,3)", "4 3", "4,3", "d 3", "d3", "D3")) {        int[] xy = parseToCoord(s);        System.out.println(xy[0] + " " + xy[1]);    }}

喵喵时光机

这是如何实施解决方案的示例。输入被验证并且程序抛出适当的异常。我认为此代码的某些或大部分方面可用于实现解决方案。该程序从命令提示符运行,如下所示,例如:> java CoordinateParser "d 7"该示例的代码:import java.util.*;public class CoordinateParser {&nbsp; &nbsp; private static final Map<Character, Integer> charIntMap = new HashMap<>();&nbsp; &nbsp; static {&nbsp; &nbsp; &nbsp; &nbsp; charIntMap.put('a', 0);&nbsp; &nbsp; &nbsp; &nbsp; charIntMap.put('b', 1);&nbsp; &nbsp; &nbsp; &nbsp; charIntMap.put('c', 2);&nbsp; &nbsp; &nbsp; &nbsp; charIntMap.put('d', 3);&nbsp; &nbsp; &nbsp; &nbsp; charIntMap.put('e', 4);&nbsp; &nbsp; &nbsp; &nbsp; charIntMap.put('f', 5);&nbsp; &nbsp; &nbsp; &nbsp; charIntMap.put('g', 6);&nbsp; &nbsp; &nbsp; &nbsp; charIntMap.put('h', 7);&nbsp; &nbsp; &nbsp; &nbsp; charIntMap.put('i', 8);&nbsp; &nbsp; }&nbsp; &nbsp; public static void main (String [] args) {&nbsp; &nbsp; &nbsp; &nbsp; if (args.length != 1) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Program needs input string argument, for example:");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("java CoordinateParser \"d7\"");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Exiting the program.");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.exit(0);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Input: " + args[0]);&nbsp; &nbsp; &nbsp; &nbsp; XYCoordinates xy = new CoordinateParser().getCoordinates(args[0]);&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Co-ordinates: " + xy);&nbsp; &nbsp; }&nbsp; &nbsp; private XYCoordinates getCoordinates(String input)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throws NumberFormatException {&nbsp; &nbsp; &nbsp; &nbsp; input = input.trim();&nbsp; &nbsp; &nbsp; &nbsp; if (input.length() < 2 || input.length() > 5) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Invalid input string length: " + input);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if (input.length() == 5 && input.startsWith("(") && input.endsWith(")")) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new XYCoordinates(input.substring(1, 2), input.substring(3, 4));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if (input.length() == 3 && input.contains(",")) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new XYCoordinates(input.substring(0, 1), input.substring(2, 3));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; if (input.length() == 3 && input.contains(" ")) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String x = input.substring(0, 1);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Integer i = charIntMap.get(x.charAt(0));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (i != null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new XYCoordinates(Integer.toString(i), input.substring(2, 3));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; if (input.length() == 2) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String x = input.substring(0, 1);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Integer i = charIntMap.get(x.charAt(0));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (i != null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new XYCoordinates(Integer.toString(i), input.substring(1, 2));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Invalid input format: " + input);&nbsp; &nbsp; }&nbsp; &nbsp; /*&nbsp; &nbsp; &nbsp;* Inner class represents x and y co-ordinates.&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; private class XYCoordinates {&nbsp; &nbsp; &nbsp; &nbsp; private int x;&nbsp; &nbsp; &nbsp; &nbsp; private int y;&nbsp; &nbsp; &nbsp; &nbsp; XYCoordinates(String xStr, String yStr)&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throws NumberFormatException {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x = Integer.parseInt(xStr);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y = Integer.parseInt(yStr);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; catch (NumberFormatException ex) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new NumberFormatException("Invalid co-ordinates: " +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new StringJoiner(", ", "(", ")")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .add(xStr).add(yStr).toString());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (isNotValidValue(x) || isNotValidValue(y)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Co-ordinates out of range: " + toString());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; private boolean isNotValidValue(int i) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return (i < 0 || i > 8);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; int getX() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return x;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; int getY() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return y;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; public String toString() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new StringJoiner(", ", "(", ")")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .add(Integer.toString(x))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .add(Integer.toString(y))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .toString();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}XY坐标类:POJO(Plain Old Java Object)表示一个对象,在这种情况下,由类定义XYCoordinates(具有一组坐标x和y)。拥有 POJO 的优点是:可以很容易地检索单个坐标;例如,&nbsp;getX()和getY()。获取坐标的字符串表示 - 通过覆盖&nbsp;toString从java.lang.Object.通过覆盖Object类的equals方法来比较两个坐标是否相同(或相等)&nbsp;(两组具有相同x&nbsp;和y值的坐标可能被认为是相等的)。将一些坐标存储在一个集合中并有效地检索它们(覆盖Object类的hashcode方法会有所帮助)。这些是一些优点。此外,还可以根据需要为 POJO 类定义其他属性或行为;我想到了比较两个坐标和对一组坐标进行排序(记住Comparable和Comparator功能接口)。
随时随地看视频慕课网APP

相关分类

Java
我要回答