嘿伙计我确实有以下代码用于在大约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");
}
}
答案 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
相比,此代码与链接列表相比将花费更多时间。