从单词数组中搜索单词中的子单词?

时间:2015-03-20 20:57:59

标签: java algorithm sorting

我一直在做一项任务,因为我必须从文件中读取单词并找到最长的单词并检查最长单词中包含多少个子单词? 这应该适用于文件中的所有单词。

我尝试使用java编写的代码用于文件中的少量数据,但我的任务是处理大量数据。

实施例: 文件词:“call”,“me”,“later”,“hey”,“how”,“callmelater”,“now”,“iam”,“busy”,“noway”,“nowiambusy”

O / P: callmelater:subwords-> call,me,稍后

在这里,我正在阅读存储在链表中的文件单词,然后找到最长的单词&将其从列表中删除然后检查提取的单词包含多少个子词。

主类作业:

import java.util.Scanner;
public class Assignment {
public static void main (String[] args){
    long start = System.currentTimeMillis();;




    Assignment a = new Assignment();
    a.throwInstructions();

    Scanner userInput = new Scanner(System.in);
    String filename = userInput.nextLine();

//  String filename = "ab.txt";
//  String filename = "abc.txt";
    Logic testRun = new Logic(filename);
//  //testRun.result();

    long end = System.currentTimeMillis();;

    System.out.println("Time taken:"+(end - start) + " ms");
}

public void throwInstructions(){
    System.out.println("Keep input file in same directory, where the code is");
    System.out.println("Please specify the fie name : ");
}

用于处理的子类逻辑:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Logic {
private String filename;
private File file;
private List<String> words = new LinkedList<String>();
private Map<String, String> matchedWords = new HashMap();

@Override
public String toString() {
    return "Logic [words=" + words + "]";
}

// constructor
public Logic(String filename) {
    this.filename = filename;
    file = new File(this.filename);
    fetchFile();
    run();
    result();
}

// find the such words and store in map
public void run() {

    while (!words.isEmpty()) {
        String LongestWord = extractLongestWord(words);
        findMatch(LongestWord);
    }
}

// find longest word
private String extractLongestWord(List<String> words) {
    String longWord;
    longWord = words.get(0);
    int maxLength = words.get(0).length();
    for (int i = 0; i < words.size(); i++) {
        if (maxLength < words.get(i).length()) {
            maxLength = words.get(i).length();
            longWord = words.get(i);
        }
    }
    words.remove(words.indexOf(longWord));
    return longWord;
}

// find the match for word in array of sub words
private void findMatch(String LongestWord) {
    boolean chunkFound = false;
    int chunkCount = 0;
    StringBuilder subWords = new StringBuilder();
    for (int i = 0; i < words.size(); i++) {
        if (LongestWord.indexOf(words.get(i)) != -1) {
            subWords.append(words.get(i) + ",");
            chunkFound = true;
            chunkCount++;
        }
    }

    if (chunkFound) {
        matchedWords.put(LongestWord,
                "\t" + (subWords.substring(0, subWords.length() - 1))
                        + "\t:Subword Count:" + chunkCount);
    }
}

// fetch data from file and store in list
public void fetchFile() {
    String word;
    try {
        FileReader fr = new FileReader(file);
        BufferedReader br = new BufferedReader(fr);
        while ((word = br.readLine()) != null) {
            words.add(word);
        }
        fr.close();
        br.close();
    } catch (FileNotFoundException e) {
        // e.printStackTrace();
        System.out
                .println("ERROR: File -> "
                        + file.toString()
                        + " not Exists,Please check filename or location and try again.");
    } catch (IOException e) {
        // e.printStackTrace();
        System.out.println("ERROR: Problem reading -> " + file.toString()
                + " File, Some problem with file format.");
    }

}

// display result
public void result() {
    Set set = matchedWords.entrySet();
    Iterator i = set.iterator();
    System.out.println("WORD:\tWORD-LENGTH:\tSUBWORDS:\tSUBWORDS-COUNT");
    while (i.hasNext()) {
        Map.Entry me = (Map.Entry) i.next();
        System.out.print(me.getKey() + ": ");
        System.out.print("\t" + ((String) me.getKey()).length() + ": ");
        System.out.println(me.getValue());
    }
}
}

这是我的程序缺乏的地方,并进入一些永无止境的循环。 我的计划的复杂性很高。 为了减少处理时间,我需要一种有效的方法,如二进制/合并排序方法,这将花费最少的时间,如O(log n)或O(nlog n)。

如果有人可以帮助我,或者至少建议我应该继续这样做。还请建议我用哪种编程语言快速实现这样的文本处理任务?

提前致谢

2 个答案:

答案 0 :(得分:0)

不确定我理解你的上下文,但从阅读问题描述听起来像链接列表是不合适的数据结构。您不需要检查每个单词到最长的单词。

“trie”可能是此应用程序的完美数据结构。

但是如果你还没有在课堂上学到这一点,那么也许你至少可以用哈希表减少你的搜索空间。在进行计算最长单词的初始列表处理时,您可以根据第一个字母将每个单词同时处理为哈希表。这样,当您准备检查子词的最长单词时,您只能检查最长单词中带有首字母的单词。 (我假设可能有重叠的单词,不像你的例子。)

您对收到的输入有何了解?如果您有关于输入字分布的更多详细信息,则可以根据预期的数据自定义解决方案。

如果您可以选择语言,并且时间效率很重要,那么您可能希望切换到C ++,就像许多应用程序一样,它比Java快几倍。

答案 1 :(得分:0)

此问题需要Trie。但你必须增加你的特里:通用的不会。 Geek Viewpoint has a good Trie written in Java。您的特定工作将在getWordList方法中进行。你的getWordList将输入最长的单词(即longestWord),然后尝试查看每个子字符串是否包含字典中存在的单词。我想我已经给了你足够的东西 - 我不能为你做你的工作。但如果你有进一步的问题,请不要犹豫。

除了在getWordList之外,您可能能够保持Geek Viewpoint中的trie不变。

你也很幸运,因为Geek Viewpoint使用一个Boggle示例来演示trie,你的问题是一个非常非常简单的Boggle版本。