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

问题描述 投票:0回答:3

我有一个从用户接收(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有点新,并且没有太多解析字符串的经验。任何指针将不胜感激。

java string parsing format coordinates
3个回答
0
投票

首先考虑一种主格式。我们想要将所有这些转换为的格式,以便最终将它们转换为两个整数。让这个格式用空格分隔两个数字。这是IMO最容易解析的问题。

然后,让我们考虑这些模式共享的模式。例如,第一个输入是仅保留括号,因此我们可以轻松识别。第三个是保证包含逗号,但没有括号。因此,我们可以使用规则对这些进行分组,如果它有逗号,则删除括号(如果有)并用空格替换逗号。

那是三个下来,两个去。

现在,这两个人最常见的是什么?他们分享了一封信。我们可以很容易地用正则表达式来捕捉这封信,但让我们稍后再担心。所以,让我们制定一个合乎逻辑的规则。

如果,短语没有逗号,我们检查它是否有一个字母。如果是这样,我们检查它是否有空格。如果是这样,我们按空格分割,并用整数equilavent替换字符,正确偏移以表示其在字母表中的位置。否则,我们使用正则表达式将字母拆分,然后执行上述操作。

现在我们在脑海中清楚地了解了我们想要实现的目标,让我们自己尝试一下。

这是我在代码中做的方式。

  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]

1
投票

您可以按以下步骤执行此操作:

  • 删除所有不是数字或字母的字符,你将以2个字符结束
  • 看看两者中的每一个: if digit:解析为int 如果不删除char代码'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]);
    }
}

0
投票

这是如何实施解决方案的示例。验证输入并且程序抛出适当的异常。我认为此代码的某些或大多数方面可用于实现解决方案。

该程序从命令提示符运行,如下所示:

> java CoordinateParser "d 7"

示例代码:

import java.util.*;

public class CoordinateParser {

    private static final Map<Character, Integer> charIntMap = new HashMap<>();
    static {
        charIntMap.put('a', 0);
        charIntMap.put('b', 1);
        charIntMap.put('c', 2);
        charIntMap.put('d', 3);
        charIntMap.put('e', 4);
        charIntMap.put('f', 5);
        charIntMap.put('g', 6);
        charIntMap.put('h', 7);
        charIntMap.put('i', 8);
    }

    public static void main (String [] args) {

        if (args.length != 1) {
            System.out.println("Program needs input string argument, for example:");
            System.out.println("java CoordinateParser \"d7\"");
            System.out.println("Exiting the program.");
            System.exit(0);
        }

        System.out.println("Input: " + args[0]);

        XYCoordinates xy = new CoordinateParser().getCoordinates(args[0]);
        System.out.println("Co-ordinates: " + xy);
    }

    private XYCoordinates getCoordinates(String input)
            throws NumberFormatException {

        input = input.trim();

        if (input.length() < 2 || input.length() > 5) {
            throw new IllegalArgumentException("Invalid input string length: " + input);
        }

        if (input.length() == 5 && input.startsWith("(") && input.endsWith(")")) {
            return new XYCoordinates(input.substring(1, 2), input.substring(3, 4));
        }

        if (input.length() == 3 && input.contains(",")) {
            return new XYCoordinates(input.substring(0, 1), input.substring(2, 3));
        }       

        if (input.length() == 3 && input.contains(" ")) {
            String x = input.substring(0, 1);
            Integer i = charIntMap.get(x.charAt(0));
            if (i != null) {
                return new XYCoordinates(Integer.toString(i), input.substring(2, 3));
            }
        }           

        if (input.length() == 2) {
            String x = input.substring(0, 1);
            Integer i = charIntMap.get(x.charAt(0));
            if (i != null) {
                return new XYCoordinates(Integer.toString(i), input.substring(1, 2));
            }
        }

        throw new IllegalArgumentException("Invalid input format: " + input);
    }

    /*
     * Inner class represents x and y co-ordinates.
     */
    private class XYCoordinates {

        private int x;
        private int y;

        XYCoordinates(String xStr, String yStr) 
                throws NumberFormatException {

            try {
                x = Integer.parseInt(xStr);
                y = Integer.parseInt(yStr);
            }
            catch (NumberFormatException ex) {
                throw new NumberFormatException("Invalid co-ordinates: " +
                    new StringJoiner(", ", "(", ")")
                        .add(xStr).add(yStr).toString());
            }

            if (isNotValidValue(x) || isNotValidValue(y)) {
                throw new IllegalArgumentException("Co-ordinates out of range: " + toString());
            }
        }

        private boolean isNotValidValue(int i) {
            return (i < 0 || i > 8);
        }

        int getX() {
            return x;
        }

        int getY() {
            return y;
        }

        @Override
        public String toString() {
            return new StringJoiner(", ", "(", ")")
                .add(Integer.toString(x))
                .add(Integer.toString(y))
                .toString();
        }
    }
}

XYCoordintes类:

POJO(Plain Old Java Object)表示一个对象,在这种情况下,由类XYCoordinates定义(具有一组坐标xy)。拥有POJO的优点是:

  • 人们可以轻松找回各个坐标;例如,getX()getY()
  • 获取坐标的字符串表示 - 通过覆盖从toString继承的java.lang.Object方法。
  • 通过重写Object类的equals方法来比较两个坐标是相同的(或相等)(两组具有相同xy值的坐标可能被认为是相等的)。
  • 将一些坐标存储在一个集合中并有效地检索它们(覆盖Object类的hashcode方法可以提供帮助)。

这些是一些优点。此外,可以根据需要为POJO类定义其他属性或行为;比较两个坐标并排列一组坐标(请记住ComparableComparator功能接口)。

© www.soinside.com 2019 - 2024. All rights reserved.