我有一个方法可以从用户那里获取(X,Y)坐标字符串。 X和Y坐标的范围都从0到8,并且坐标可以是五种可能的格式之一:
我遇到的麻烦是开发一种可以成功解析所有四种格式的方法。更具体地说,我想将X和Y坐标都成功转换为两个单独的int并将它们存储在某个位置,而不管使用哪种格式。
我对Java有点陌生,并且对解析字符串没有太多经验。任何指针将不胜感激。
答案 0 :(得分:1)
您可以按照以下步骤进行操作:
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]);
}
}
答案 1 :(得分:0)
首先让我们考虑一个主格式。我们想要将所有这些转换为一种格式,以便最终将它们转换为两个整数。让我们将此格式设置为两个数字,并用空格分隔。这是IMO最容易解析的。
然后,让我们考虑一下所有这些共享的模式。例如,保证第一个输入仅包含一个括号,因此我们可以轻松地识别出它。第三个被保证包含逗号,但是没有括号。因此,我们可以使用规则将它们分组,如果有逗号,则删除括号(如果有的话),然后用空格替换逗号。
那是3点下来,还有2点要走。
现在,这后两个有什么共同点?他们分享一封信。我们可以使用regex轻松地找到这封信,但稍后再担心。因此,让我们制定一个逻辑规则。
如果该短语没有逗号, 我们检查它是否有字母。如果是这样,我们检查它是否有空格。 如果是这样,我们将以空格分隔,并用整数整数替换字符,正确偏移以表示其在字母表中的位置。 否则,我们使用正则表达式将字母分开,然后执行上述操作。
现在,我们对想要放大的内容有了清晰的认识,让我们尝试自己做。
这就是我在代码中的处理方式。
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]
答案 2 :(得分: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(普通的旧Java对象)表示由类XYCoordinates
(具有一组坐标x
和y
定义的对象)。拥有POJO的优点是:
getX()
和getY()
。toString
继承的java.lang.Object
方法。Object
类的equals
方法(两组具有相同x
的坐标
和y
的值可能相等)。Object
类的hashcode
方法会有所帮助)。这些是其中的一些优点。另外,可以根据需要为POJO类定义其他属性或行为。比较两个坐标并排序一组坐标就成为我的想法(记住Comparable
和Comparator
功能接口)。