在字符串中搜索子字符串

时间:2015-02-08 21:16:46

标签: java arrays linked-list substring

嘿伙计我确实有以下代码用于在大约70万个字母的文件中搜索子字符串我相信它适用于ArrayList但是对于LinkedList它需要永远完成。任何人都可以看到为什么需要这么长时间? = S

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class CountSubstrings {
    private static int sumAL=0;
    private static int sumLL=0;
    private static List<Character> sAList= new ArrayList<Character>();
    private static List<Character> sLList= new LinkedList<Character>();
    private static List<Character> pattAL= new ArrayList<Character>();
    private static List<Character> pattLL= new LinkedList<Character>();
    private static int index=0;
    private static double timer=0;
    private static double Otimer=0;

    /*
     * Returns the lowest index at which substring pattern begins in text (or
     * else -1).
     */

    private static int findBrute(List<Character> text, List<Character> pattern,  int position) {
        int n = text.size();
        int m = pattern.size();
        for (int i = position; i <= n - m; i++) { // try every starting index 
                                 // within text
            int k = 0; // k is index into pattern
            while (k < m && (text.get(i + k) == pattern.get(k)))
            {   // kth character of pattern matches
                k++;
                if (k == m )
                {   index=i;
                    return i;} // substring text[i..i+m-1] is a match
                }
            }

        return -1; // search failed
    }

    public static void main (String[] args)
    {
        Scanner sc1= new Scanner(System.in);
        Scanner sc2= new Scanner(System.in);

        System.out.print("Please enter the path for the input file: ");
        String fileName= sc1.next();

        System.out.print("Enter the pattern to look for: ");
        String subString= sc2.next();

        for(char c: subString.toCharArray())
        {
            pattAL.add(c);
            pattLL.add(c);
        }

        System.out.println("current time "+System.currentTimeMillis()+" milliseconds");
        try (BufferedReader OpenFile = new BufferedReader(new FileReader(fileName)))
        {
            // file is opened here and we can access everything in there.
            String sSLine;
            String content = new Scanner(new File(fileName)).useDelimiter("\\Z").next();
            //System.out.println(content);

     // find int answer line by line not complete

            while ((sSLine = OpenFile.readLine()) != null) {
                sSLine.replace('\n', ',');// making sure we add every word alone even when we encounter \n
                for(char c: sSLine.toCharArray())
                {
                    sAList.add(c);
                    sLList.add(c);
                }
            }
        } catch (IOException e) 
        {
            e.printStackTrace();
        } 
        //Array List by pointer

        //starting ARRAY LIST
        Otimer=System.currentTimeMillis();
         while(findBrute(sAList,pattAL,index)!=-1)
         {
                index=index+pattAL.size();
                sumAL++;
         }

         timer=System.currentTimeMillis()-Otimer;
         Otimer=System.currentTimeMillis();
         index=0; // resetting the index  OR  we can make 2 other variables indexAL  indexLL  if magic numbers were so bad
         System.out.println("Using ArrayList: "+sumAL+" matches, derived in "+timer+ " milliseconds");
         while(findBrute(sLList,pattLL,index)!=-1)
         {
            System.out.println("index"+index+" char: "+sLList.get(index));

            index=index+pattLL.size();
            //if(sLList.get(index))
            sumLL++;
            System.out.println("index"+index+" char: "+sLList.get(index+1));
         }
         timer=System.currentTimeMillis()-Otimer;
    System.out.println("Using Linked List: matches "+sumLL+" time, derived in "+timer+ " milliseconds");
      }
}

1 个答案:

答案 0 :(得分:1)

我认为您需要了解Linked list的工作原理。链接列表中的每个项目都引用列表中的下一个项目(在Java的情况下,也是前一个项目)。因此,要在“链接”列表中的特定索引处获取项目,必须从列表的任一端遍历所有项目,直到到达正确的索引。 相比之下,ArrayList是基于数组构建的,因此可以非常快速地访问任意索引。

让我们看一下LinkedList的文档:

  

所有操作的执行都与双向链表一样。 索引到列表中的操作将从开头或结尾遍历列表,以较接近指定索引为准。

对于ArrayList

  

size,isEmpty, get ,set,iterator和listIterator操作在恒定时间下运行。

在您的代码中,您在get方法的循环中使用findBrute方法。

...                    ↓                     ↓
while (k < m && (text.get(i + k) == pattern.get(k)))
...

还在while方法的main循环中:

...                                                ↓
System.out.println("index"+index+" char: "+sLList.get(index));
...

因此,由于链接列表的工作方式,与ArrayList相比,此代码与链接列表相比将花费更多时间。

相关问题