Java 如何从具有特定类约束的列表中获取x个下一项
我有一个不同类型对象的列表,我们称之为子句Java 如何从具有特定类约束的列表中获取x个下一项,java,list,arraylist,Java,List,Arraylist,我有一个不同类型对象的列表,我们称之为子句 List<Clause> clauses = new ArrayList<Clause>(); 如果x=2(=2条向前),第一条应该给我 因此,这是我在提出问题(尚未检查)后的第一个实现: publicstaticvoidsetforward子句(列表子句,int-forwardClausesNum){ for(int i=0;i!(c古怪子句实例)) .collect(Collectors.toList()); RECSET
List<Clause> clauses = new ArrayList<Clause>();
如果x=2(=2条向前),第一条应该给我
因此,这是我在提出问题(尚未检查)后的第一个实现:
publicstaticvoidsetforward子句(列表子句,int-forwardClausesNum){
for(int i=0;i<子句.size();i++){
子句=子句.get(i);
if(古怪子句实例){
继续;
}
int forwardClausesToGo=forwardClausesNum;
对于(int j=i+1;j0&!(forwardClauseInstanceof WeirdClause)){
条款。添加转发条款(转发条款);
前进的路——;
}
}
}
}
编辑:基于nukie的答案O(1)列表的改进版O(N)。获取(i)
private void lookforward子句(列表0){
子句forward子句=子句.get(i+j);
if(!(forwardClause instanceof WeirdClause)){
条款。添加转发条款(转发条款);
前进的路——;
}
j++;
}
}
}
我想到的是O(N^2),为下一个元素保留指针的方法很简单,但这里它们必须等于forwardClausesNum,而且有些元素不被计算,所以我认为指针不起作用
如果有更好的选择,我将不胜感激:)谢谢我认为这可能是一个很好的方法:
forwardClausesNum
限制尾部,设置第一个元素的forward子句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);
}
publicstaticvoidsetforward子句(列表子句,int-num){
列表子句=
子句.stream()
.过滤器(c->!(c古怪子句实例))
.collect(Collectors.toList());
RECSETFORWARD条款(普通条款);
}
私有静态void RecSetForwardClaires(列表子句,int num){
if(子句.isEmpty())返回;
列表尾=
子句.stream().skip(1).collect(collector.toList());
名单有限公司=
tail.stream().limit(num.collect(Collectors.toList());
条款。get(0)。SetForward条款(有限);
RECSETFORWARD条款(尾部);
}
我想,您可以这样尝试:
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++;
}
}
}
publicstaticvoidsetforward子句(列表子句,int-forwardClausesNum){
int计数器=0;
当前子句=子句.get(计数器);
//跳过前导奇怪子句
做{
计数器++;
}while(weird子句的当前实例);
if(WeirdClause的当前实例)
返回;
int组=0;
for(计数器=计数器+1;计数器<子句.size();计数器++){
if(子句.get(counter)instanceOf weird子句)
继续;
如果(组==forwardClausesNum){
当前=子句。获取(当前);
组=0;
}否则{
current.forward子句.add(子句.get(计数器));
组++;
}
}
}
因为您没有将返回值放入函数,所以我编写了这个示例作为副作用函数。当然,你也可以把结果放在其他的收藏中。我没有要求特定的代码——如果需要的话,我可能会得到一笔赏金。但是想到的一切都是O(N^2)复杂的。我曾想过使用指针来跟踪下一个元素,这很简单,但forwardNum是动态的,一些元素必须被过滤掉。我将发送我所拥有的内容soon@marstran我发送了我所做的-它没有被检查是的,当然,将
WeirdClause
s添加到转发子句时,将其删除。另外,当第一个元素是WeirdClause
时,请跳过设置forwardClauses。谢谢!这是一种使用递归的有趣方法——这种方法的空间和时间复杂度是多少?它在任何方面都比迭代方法好吗?如果我没有弄错的话,这种方法在时间和空间复杂性上都是O(n)。您可以使用列表
上的子列表
-方法,以便在获取尾部和限制尾部时不必迭代元素。但是,请注意,此方法会在原始列表上创建一个视图。这意味着,如果您更改原始列表,则所有子列表也将更改。您可能还希望在调用该方法之前过滤掉所有WeirdClause
s,因此您不必一直“重新过滤”列表。不过,我仍然需要初始列表中的WeirdClause:)谢谢!当它发现古怪的子句时,它不会停止计数(count++)吗?我只想跳过它们。这似乎有O(N)的时间复杂度,这将是理想的。请检查我的代码以了解预期的行为。是的,此实现将跳过古怪的子句。continue语句只将循环路由到下一个迭代,而不执行循环块中的提醒代码。我认为我们的解决方案基本相同。哦,是的,列表。get(I)应该是O(1),因为这是一个arraylisthmm。。。。事实上,跳过最初的奇怪条款没有多大意义)我认为这是我思维流动的结果)
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--;
}
}
}
}
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++;
}
}
}
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);
}
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++;
}
}
}