我有一个输入数据存储在arraylist中。
在遍历列表时,输出是
Input ----------- [0 Overcast 1 High 2 Normal 3 Weak ]
Input ----------- [0 Rainy 1 Mild 2 High 3 Strong ]
Input ----------- [0 Rainy 1 Mild 2 Normal 3 Weak ]
并在另一个arraylist中进行统治
Rule -----------[ 0 Overcast Yes, 0 Rainy 3 Strong No, 0 Rainy 3
Weak Yes, 0 Sunny 2 High No, 0 Sunny 2 Normal Yes]
我期望输出为
[0 Overcast 1 High 2 Normal 3 Weak Yes]
[0 Rainy 1 Mild 2 High 3 Strong No]
[0 Rainy 1 Mild 2 Normal 3 Weak Yes]
通过查看规则集,我必须在输入中添加标签。
为此,我试图匹配输入和规则集
for(String ruleSet : addRule){ //ruleset
for(String lineSet : getLine){ //inputline
if (lineSet.matches("(.*)"+ruleSet+"(.*)")) {
System.out.println("got----------------"+lineSet+"***"+ruleSet);
break;
}
else{
System.out.println("Not found----------------"+lineSet+"***"+ruleSet);
}
}
}
但是我的结果是这样的
0 Overcast 1 High 2 Normal 3 Weak Yes与0 Overcast Yes不匹配。 尽管它是一个子集。
我做错什么了吗?
投票者请评论
您将不得不解释您试图以更好的方式实现的目标。 现在还不清楚。
您可以控制规则集吗? 您可以用其他方式编写它们还是将它们作为输入?
我可以控制规则集
如果我理解正确,您有两个String列表:
getLine是代表输入行的字符串列表
addRule是代表规则集的字符串列表。
每个规则包含需要与输入行进行匹配的几部分,以及在匹配的情况下应使用的结果。
(尽管该术语在Java上下文中具有非常特定的含义,但您似乎将其称为"类路径")。
所以这行:
0 Overcast 1 High 2 Normal 3 Weak
会违反规则
0 Overcast
因为它包含子字符串" 0 Overcast",但也违反了规则:
0 Overcast 3 Weak
因为该行包含子字符串" 0 Overcast"和" 3 Weak",即使整个规则未在该行中显示为子字符串。
我猜您正在寻找的是子集搜索,也许看到了这个答案并尝试使用它,但是在字符串之间进行子集匹配很复杂,并且可以使用正则表达式,但是比您尝试的要难一些,因此,我建议尝试使用更简单的解决方案。
具体来说,仅执行.matches("(.*)"+ruleSet+"(.*)")并不会做您想要的。
如果我对您的问题的解释是正确的,请在评论中让我知道,我将尽力帮助您找到解决方案。
继续
因此,假设您可以控制规则集,那么我可能会制作一个如下所示的Rule类:
public class Rule {
public List parts;
public String result;
public Rule(String result, String... parts) {
this.parts = new ArrayList<>();
for(String part : parts) {
this.parts.add(part);
}
this.result = result;
}
public String match(String line) {
for(String part : parts) {
if (!line.contains(part)) return null;
}
return result;
}
}
注意match的实现方式:如果任何部分都不匹配,则匹配失败。
(我将varargs用于构造函数,但如果需要,您可以只传递一个列表)。
然后您可以像这样初始化规则集:
List ruleSet = new ArrayList<>();
ruleSet.add(new Rule("Yes","0 Overcast"));
ruleSet.add(new Rule("No","0 Rainy","3 Strong"));
ruleSet.add(new Rule("Yes","0 Rainy","3 Weak"));
...
当您违反规则时,如果没有匹配项,则调用match以获得null,如果存在匹配项,则调用结果。
for(Rule rule : ruleSet) {
for(String line : getLine) {
String result = rule.match(line);
if (result != null) {
...
另外,您可以将规则编写为正则表达式,如下所示:
String rule =".*0 Rainy.*3 Strong.*";
if(line.matches(rule)) {
...
但是您可能应该避免使用正则表达式,直到您有一些时间来学习它们。它们是强大的工具,但有许多警告。
如果需要将规则集保存在文本文件中,那么您将不得不编写一种方法来将行转换为Rule对象,可能是作为其他构造函数。这是一种实现方法:
public class Rule {
...
public Rule(String line) {
this.parts = new ArrayList<>();
String number = null;
for (String s : line.split()) {
if (s.equals("Yes") || s.equals("No")) {
this.result = s;
return;
}
if (number == null) {
number = s;
} else {
this.parts.add(number +"" + s);
number = null;
}
}
}
但是lineSet.matches("(.. *)" + ruleSet +"(。*)")会匹配子字符串,对吗?我尝试了您所说的方法,因为它在[0 Overcast 1 High 2 Normal 3 Weak]之间匹配,所以也无法正常工作。*** [0 Overcast]我正在尝试匹配子字符串
还是有其他方法可以存储规则集和迭代过程?
@SreeVeni如果您有规则集,无论如何,您可能都必须遍历它。我不明白你的第一句话。
我想说的是..我尝试从规则集中删除类路径并进行匹配,但是它们仍然与输入行不匹配
更改为包含并根据您的建议再次编辑所有不匹配项。我认为我们必须匹配子字符串。例如0阴1热2高3弱应匹配0阴
我完全改变了答案。读一遍,告诉我我是否走在正确的轨道上。
是的,这确实是我的意思:)。这是决策树预测的一部分。
这是我的规则文件。因此,我需要阅读您建议的存储方式,即简单地将它们存储到列表中。