首先,不要注意我的方法和宏的名称,我是法国人,我在代码中混合了法语和英语,因为这对我来说更容易
我正在处理存储在文本文件中的图表,如下所示(空格可以忽略):
A: (B, 4.5), (C, 5.8)
B: (A, 3)
C:
通过我的图表实现来获得相同的图表,我会做类似的事情:
StdGraph<String> graph = new StdGraph<String>();
graph.addSommet("A"); //1 -> add the vertex named "A" to the graph
graph.addSommet("B"); //2 -> add the vertex named "B" to the graph
graph.addSommet("C"); //3 -> add the vertex named "C" to the graph
graph.addArete("A", "B", 4.5); //4 -> add an edge between A and B with a weight of 4.5
graph.addArete("A", "C", 5.8); //5 -> add an edge between A and C with a weight of 5.8
graph.addArete("B", "A", 3.); //6 -> add an edge between B and A with a weight of 3.0
//note that 3 and 4 can switch places, and technically 6 could go right after 2
它必须按这个顺序,因为如果其中一个顶点不存在,我就无法添加边。 我的图表实现有效,但我不知道如何从文本中获取数据;另外,我必须确保它遵循正确的模式,因为我需要测试输入文件不是其他文件。
我尝试这样做是为了从文件中获取一个不带空格的字符串,以便以后更容易解析,但我以前从未使用过扫描仪,所以我不确定它是否有效:
private String fileToString(File f) {
StringBuilder str = new StringBuilder("");
Scanner s = null;
try {
s = new Scanner(f);
} catch (FileNotFoundException e) {
System.out.println("ERREUR => FileNotFoundException");
e.printStackTrace();
}
while (s.hasNext()) {
str.append(s.nextLine());
}
String res = str.toString();
res.replaceAll("//s", "");
return res;
}
我的图表正则表达式是这样的(这样写是为了让我和我的大学小组更容易阅读):
//Regex for a Vertex' name:
String SOMMETREGEX = "[a-zA-Z0-9\\-_/]*";
//Regex for an Edge's weight:
String POIDSREGEX = "[\\-+]?\\d+(\\.\\d+)?";
//Regex for one line composed of the vertex and its neighbors with the weight of the edges
String SOMANDSUIV = "("+SOMMETREGEX+":"
+ "(\\("+SOMMETREGEX+","+POIDSREGEX+"\\),)*"
+ "(\\("+SOMMETREGEX+","+POIDSREGEX+"\\))?\\n)";
//Regex for the full graph
String GRAPHREGEX = SOMANDSUIV + "*";
最后,我有这个方法,这是我需要完成的,但我不知道如何:
private StdGraph<String> buildGraphFromFile(File f) {
StdGraph<String> res = new StdGraph<String>();
String stringOfFile = fileToString(f);
if(!Pattern.matches(GRAPHREGEX, stringOfFile)) {
return null;
}
// Stuff goes here but idk what
return res;
}
我已经搜索了几个小时,但我什至不知道从哪里开始,因为我的正则表达式很复杂,而且我对文件、扫描仪和模式匹配完全没有经验......
如果您有任何建议,我很想听听,因为我完全迷失了
我必须使用 java 1.6,所以之后的任何东西都不是一个选择
如果您找不到合适的解析器,您可以使用类似于以下的模式:
"^\\s*([A-Z]{1,})\\s*:|\\s*(?:\\(\\s*([A-Z])\\s*,\\s*([^)\\r\\n]+)\\))"
找到你的节点和权重。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegularExpression {
public static void main(String[] args) {
final String regex = "^\\s*([A-Z]{1,})\\s*:|\\s*(?:\\(\\s*([A-Z])\\s*,\\s*([^)\\r\\n]+)\\))";
final String string = "A: (B, 4.5), (C, 5.8)\n"
+ "B: (A, 3)\n"
+ "C:\n"
+ "E: (B, 4.5), (E, 5.8), (F, 5.8)\n"
+ "F: (A, 3)\n"
+ "G: (A, 3) , (E, 3) , (F, 3), (G, 3)";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
}
}
Full match: A:
Group 1: A
Group 2: null
Group 3: null
Full match: (B, 4.5)
Group 1: null
Group 2: B
Group 3: 4.5
Full match: (C, 5.8)
Group 1: null
Group 2: C
Group 3: 5.8
Full match: B:
Group 1: B
Group 2: null
Group 3: null
Full match: (A, 3)
Group 1: null
Group 2: A
Group 3: 3
Full match: C:
Group 1: C
Group 2: null
Group 3: null
Full match: E:
Group 1: E
Group 2: null
Group 3: null
Full match: (B, 4.5)
Group 1: null
Group 2: B
Group 3: 4.5
Full match: (E, 5.8)
Group 1: null
Group 2: E
Group 3: 5.8
Full match: (F, 5.8)
Group 1: null
Group 2: F
Group 3: 5.8
Full match: F:
Group 1: F
Group 2: null
Group 3: null
Full match: (A, 3)
Group 1: null
Group 2: A
Group 3: 3
Full match: G:
Group 1: G
Group 2: null
Group 3: null
Full match: (A, 3)
Group 1: null
Group 2: A
Group 3: 3
Full match: (E, 3)
Group 1: null
Group 2: E
Group 3: 3
Full match: (F, 3)
Group 1: null
Group 2: F
Group 3: 3
Full match: (G, 3)
Group 1: null
Group 2: G
Group 3: 3