Java ArrayList Iterator next()未按预期工作

时间:2014-04-05 17:36:45

标签: java algorithm arraylist iterator

我正在尝试创建一个算法,确定一个数组列表(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

2 个答案:

答案 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中找到的内容相匹配的内容时,就可以进入外循环中的下一步了。

相关问题