我正在尝试创建一个算法,确定一个数组列表(s1)是否是另一个数组列表(s2)的子序列。第一个列表中的元素都需要位于第二个列表中,并且必须按相同的顺序排列。因此s1是s2的子序列,但s1不是s2的子序列。我需要使用迭代器来遍历每个列表,我只应该遍历每个列表一次(因为它必须以相同的顺序)。我似乎有一个问题,下一个()变得无效?是什么导致这个/我该如何解决这个问题? 除了没有转到第一个数组列表中的下一个元素之外,我现在所拥有的代码似乎正如我希望的那样工作。
import dataStructures.*;
public class Subsequence2
{
public static void main(String[] args)
{
ArrayList<Character> s1 = new ArrayList<Character>();
s1.add('n');
s1.add('p');
s1.add('a');
ArrayList<Character> s2 = new ArrayList<Character>();
s2.add('a');
s2.add('n');
s2.add('b');
s2.add('p');
s2.add('c');
s2.add('a');
Subsequence2 one = new Subsequence2();
System.out.print("S1 is a subsequence of S2 is a ");
System.out.print(one.subSequence(s1, s2));
System.out.print(" statment.");
} //end main
public static <T> boolean subSequence(ArrayList<T> s1, ArrayList<T> s2)
{
//if s1 is empty or if s1 and s2 are empty it is a subsequence
if(s1.isEmpty() || (s1.isEmpty() && s2.isEmpty()))
{
return true;
}
//if s2 is empty and s1 is not is is not a subsequence.
else if(s2.isEmpty())
{
return false;
}
else
{
int s1Count = 0; //count items matched
Iterator<T> itr1 = s1.iterator();
Iterator<T> itr2 = s2.iterator();
while(itr1.hasNext())
//for(Iterator<T> itr1 = s1.iterator(); itr1.hasNext();) //traverse s1
{
T c1 = itr1.getCurrent();
itr1.next(); //go to next element of s1
while(itr2.hasNext()) //traverse s2
{
T c2 = itr2.getCurrent();
//if items are equal check the next item and add 1 to count of items matched
if(c1.equals(c2))
{
itr2.next();
++s1Count;
//used for testing- just want to see what index it is pulling
System.out.print("s1 index " + s1.indexOf(c1) + " s2 index " + s2.indexOf(c2) + " \n" + c1 + " " + c2 + "\n");
}
//if it didn't match, check next element
else
{
itr2.next();
}
if(s1Count == s1.size()) //if match count is == to s1 size, it is a subsequence
{
return true;
}
} // end itr2 while
} //end for itr1
} //end else not empty
return false;
} //end subSequence method
}//end class
答案 0 :(得分:1)
或者您可以使用Collections.indexOfSubList(List<?> source, List<?> target)
查看java docs
答案 1 :(得分:1)
内循环上的条件不应只是itr2.hasNext()
。您希望内循环只要itr2.hasNext()
进行迭代,并且下一个项目与itr1
的当前项目不同。一旦找到(itr2
)当前itr1
项,您就想停止迭代内循环,然后返回itr1
中的下一个项目。
public static <T> boolean subSequence(ArrayList<T> s1, ArrayList<T> s2) {
Iterator<T> itr1 = s1.iterator();
Iterator<T> itr2 = s2.iterator();
while (itr1.hasNext()) {
T itemFrom1 = itr1.next();
T itemFrom2;
do {
if( ! itr2.hasNext()){
return false;
}
itemFrom2 = itr2.next();
} while( ! itemFrom1.equals(itemFrom2));
}
return true;
}
基本上这里发生的事情是,虽然我们仍在迭代itr1
,但如果itr2
中的元素用尽,那么我们仍然会在itr1
中找到匹配的东西来匹配,所以这不是一个后续的。但只要我们继续在itr2
找到东西,我们就会继续前进。每当我们在itr2
中找到与我们在itr1
中找到的内容相匹配的内容时,就可以进入外循环中的下一步了。