【问题标题】:search sub words in word from array of words?从单词数组中搜索单词中的子单词?
【发布时间】:2015-03-20 20:57:59
【问题描述】:

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

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

示例: 文件词:"call","me","later","hey","how","callmelater","now","iam","busy","noway","nowiambusy"

o/p: callmelater : subwords->call,me,later

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

主类作业:

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)。

如果有人可以帮助我解决这个问题,或者至少建议我应该朝哪个方向前进。另外请建议我哪种编程语言可以快速实现此类文本处理任务?

提前致谢

【问题讨论】:

  • 谷歌radix tree。一个好的数据结构非常重要。
  • C++ may actually be slower。当然,他不太可能切换,因为这是一项任务。
  • 这可以通过动态规划来解决。按长度对单词进行排序。取第一个字。获取第一个字符 1,然后检查其余字母 n-1 是否可以从单词列表中构造出来。再次从 n-1 个字母中取出 1 个字符,然后检查是否可以从单词列表中形成 n-2 个字母。
  • @Sandeep 对单词进行排序是开销。没有必要排序。跟踪最长的单词更简单。
  • @KonsolLabapen OP 说他想找到最长的单词。

标签: java algorithm sorting


【解决方案1】:

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

除了getWordList 之外,您可能几乎可以将 Geek Viewpoint 中的特里树保持原样。

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

【讨论】:

  • 这个问题真的没那么难。但如果你真的没有看到,关键是findWord 方法:geekviewpoint.com/java/trie/is_word。因此,您采用了longestWord 的子字符串s,并且s 的所有前缀都是单词在您的最终结果集中是可以接受的。
【解决方案2】:

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

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

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

您对您将收到的输入有任何了解吗?如果您有关于输入词分布的更多详细信息,那么您可以针对您期望的数据定制您的解决方案。

如果您可以选择您的语言,并且时间效率很重要,您可能希望切换到 C++,因为对于许多应用程序来说它比 Java 快几倍。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-17
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    • 2017-08-07
    • 2017-12-03
    • 2019-11-16
    相关资源
    最近更新 更多