我有一个不同类型的对象列表,我们称之为Clauses
List<Clause> clauses = new ArrayList<Clause>();
在每个条款中,我想要一个名为forwardClauses
的子句子列表我希望每个条款在其forwardClauses中添加一个给定的x个子句,这些子句在它过滤掉了作为WeirdClause实例的子句之后。我也不关心WeirdClauses所具有的前瞻性。
所以
NormalClause extends Clause
和
WeirdClause extends Clause
列表
[
NormalClause(uuid=1),
NormalClause(uuid=2),
NormalClause(uuid=3),
WeirdClause(uuid=4),
NormalClause(uuid=5)
]
如果x = 2(= 2条款向前),应该给我第一个
uuid=1
forwardClauses = [NormalClause(uuid=2), NormalClause(uuid=3)]
uuid=2
forwardClauses = [NormalClause(uuid=3), NormalClause(uuid=5)]
uuid=3
forwardClauses = [NormalClause(uuid=5)]
uuid=4
forwardClauses = []
uuid=5
forwardClauses = []
所以这是我提出问题后的第一个实现(没有检查过):
public static void setForwardClauses(List<Clause> clauses, int forwardClausesNum) {
for (int i = 0; i< clauses.size(); i++){
Clause clause = clauses.get(i);
if(clause instanceof WeirdClause){
continue;
}
int forwardClausesToGo = forwardClausesNum;
for(int j = i+1; j < clauses.size(); j++){
Clause forwardClause = clauses.get(j);
if(forwardClausesToGo > 0 && !(forwardClause instanceof WeirdClause)){
clause.addForwardClause(forwardClause);
forwardClausesToGo--;
}
}
}
}
编辑:改进版本O(N)基于nukie的回答利用O(1)list.get(i)
private void lookForwardClauses(List<Clause clauses, int forwardClausesNum) {
for (int i = 0; i< clauses.size(); i++){
Clause clause = clauses.get(i);
if(clause instanceof InnerText){
continue;
}
int forwardClausesToGo = forwardClausesNum;
int j = 1;
while(i+j < clauses.size() && forwardClausesToGo > 0) {
Clause forwardClause = clauses.get(i+j);
if(!(forwardClause instanceof WeirdClause)){
clause.addForwardClause(forwardClause);
forwardClausesToGo--;
}
j++;
}
}
}
无论发生什么事情都是O(N ^ 2)并且为下一个元素保留指针的方法将是微不足道的但是在这里它们必须等于forwardClausesNum并且除此之外一些元素不计算所以指针我相信不会工作。
如果我能采取更高效的替代方案,我们将不胜感激。谢谢
答案 0 :(得分:1)
我认为这可能是一个很好的方法:
forwardClausesNum
限制尾部来设置第一个元素的forward子句。编辑: 如果您正在使用Java 8,我认为这可能会解决您的问题。但是,它可以更有效地完成,但除非性能是一个非常大的问题,否则这应该足够了。
public static void setForwardClauses(List<Clause> clauses, int num) {
List<Clause> normalClauses =
clauses.stream()
.filter(c -> !(c instanceof WeirdClause))
.collect(Collectors.toList());
recSetForwardClauses(normalClauses);
}
private static void recSetForwardClauses(List<Clause> clauses, int num) {
if(clauses.isEmpty()) return;
List<Clause> tail =
clauses.stream().skip(1).collect(Collectors.toList());
List<Clause> limited =
tail.stream().limit(num).collect(Collectors.toList());
clauses.get(0).setForwardClauses(limited);
recSetForwardClauses(tail);
}
答案 1 :(得分:0)
我想,你可以这样试试:
public static void setForwardClauses(List<Clause> clauses, int forwardClausesNum) {
int counter=0;
Clause current = clauses.get(counter);
//skip leading WeirdClauses
do {
counter++;
} while (current instanceOf WeirdClause);
if (current instanceOf WeirdClause)
return;
int group = 0;
for (counter = counter + 1; counter < clauses.size();counter++){
if (clauses.get(counter) instanceOf WeirdClause)
continue;
if (group == forwardClausesNum) {
current = clauses.get(current);
group = 0;
} else {
current.forwardClauses.add(clauses.get(counter));
group++;
}
}
}
由于您没有为函数设置返回值,因此我将此示例编写为副作用函数。但是当然你可以将结果放在其他一些集合中。