在文档

时间:2017-01-06 13:46:20

标签: java android string algorithm

使用Java(在Android上)我试图找到一种方法(快速...)来解决这个问题:

我有一个单词列表(大约10到30个)和一个文档。文档的长度也可以变化,可能大约2500到10000字。本文档是一本书的一部分。

我想要的是在本文档中找到包含列表中较高数量单词的字符串(句子...)。文档中的单词必须与我的单词列表顺序相同。通常情况下,文档中的单词不应该是另一个,也可能是我列表中每个单词之间最多2或3个单词。

为了更清楚,让我们以小数据为例。

我的单词列表是:

  

伤害工作日

我的文件:

  

就是这样,非常小心。你必须确保你拉起来   定期所有的猴面包树,在他们可以的第一时刻   区别于他们非常接近的玫瑰丛   他们最早的年轻人。这是一项非常繁琐的工作,“小王子   补充说,“但很容易。”有一天他对我说:“你应该   做一个漂亮的画,让你住的孩子都可以看到   究竟是怎么回事。如果他们这对他们非常有用   有一天会去旅行。有时,“他补充说,”没有伤害   推迟工作 直到另一个。但   当它是猴面包树的问题时,这总是意味着灾难。一世   我知道一个懒惰的人居住的星球。他忽略了三个   小灌木......“所以,正如小王子向我描述的那样,我   画了那个星球。我不太喜欢拿   道德主义者的语气。但猴面包树的危险性很小   理解,任何人都会冒这样的风险   可能会迷失在一颗小行星上,一旦我突破了我的星球   保留。 “孩子们,”我坦率地说,“小心猴面包树!”

目标是在文档中找到字符串“在推迟工作之前没有任何损害”。

目前,我想到的唯一方法是:

1 - 在文档的列表中找到第一个出现的第一个单词。

2 - 将列表中的单词数乘以2或3,得到我必须在文档中检查的字符串长度(关于文档中列表单词之间的最大单词数)。

3 - 通过拆分和循环搜索此文档字符串(具有在步骤2中获得的字符串长度)的列表中其他单词的出现。

如果我认为我在这个字符串中出现的单词不够(可能大约50%),那么继续搜索文档,从下一次出现的列表中的第一个单词开始。

但是我担心这可能会很长很长,特别是因为我正在使用移动设备...所以我来这里是为了抓住一些我可能没想过的想法,或者一些可以帮助我完成这项任务的libs。我也考虑过正则表达式,但我不确定它是不是更好的方式。

  

@gukoff命题

最后,我的单词列表与我的文本的顺序不同,它简化了算法。 @gukoff答案的开头就足够了。无需实施LIS算法或反转列表。

//Section = input text
//wordsToFind = words to find in text separated by space
private ArrayList<ArrayList<Integer>> test1(String wordsToFind, Section section) {
    //1. Create the index of your words array.
    String[] wordsArray = wordsToFind.split(" ");

    ArrayList<Integer> indexesSentences = new ArrayList<>();
    ArrayList<ArrayList<Integer>> sentenceArrayIndexes = new ArrayList<>();
    ArrayList<Integer> wordsToFindIndexes = new ArrayList<>();

    for(Sentence sentence:section.getSentences()) {
        indexesSentences.clear();
        for(String sentenceWord:sentence.getWords()) {
            wordsToFindIndexes.clear();
            int j = 0;
            for(String word:wordsArray) {
                if(word.equals(sentenceWord)) {
                    wordsToFindIndexes.add(j+1);
                }
                j++;
            }
            //Collections.reverse(wordsToFindIndexes);
            for(int idx:wordsToFindIndexes) {
                indexesSentences.add(idx);
            }
        }
        sentenceArrayIndexes.add((ArrayList<Integer>)indexesSentences.clone());
    }
    return sentenceArrayIndexes;
}

public class Section {
    private ArrayList<Sentence> sentences;

    public Section (String text) {
        sentences = new ArrayList<>();

        if(text == null || text.trim() == "") {
            throw new IllegalArgumentException("Text not valid");
        }
        String formattedText = text.trim().replaceAll("[^a-zA-Z. ]", "").toLowerCase();
        String[] sentencesArray = formattedText.split("\\.");
        for(String sentenceStr:sentencesArray) {
            if(sentenceStr.trim() != "") {
                sentences.add(new Sentence(sentenceStr));
            }
        }
    }

    public ArrayList<Sentence> getSentences() {
        return sentences;
    }

    public void addSentence(Sentence sentence) {
        sentences.add(sentence);
    }
}

2 个答案:

答案 0 :(得分:1)

这是一个简单的方法,根据您的文档大小应该足够好:

  1. 制作一个array(称之为words),其大小为n,其中n是您document中的字数。
  2. 现在填充此数组,以便
     words[i] = 0如果list中没有任何字词与此字词匹配  words[i] = k如果kth中的list字符与此字词匹配(1为基础的索引),则there is no harm in putting off a piece of work until another day.

    示例:如果您的文档为work day harm piece且字词列表为words(按此顺序),那么您的[0,0,0,3,0,0,0,0,4,0,1,0,0,2]数组将如下所示2000~3000

    < / LI>

    2.现在您将拥有一个整数 //AS Rev var elementsasrev = $(this).parent().find('tr').filter('.'+trclass); var asrev = parseInt(elementsasrev.eq(1).find("td:nth-child(6)").html()); if(typeof asrev !== "undefined") { $('.'+trclass).not(this).find(".asrev").html(asrev); } //FBspend var fbspend = parseInt($(this).find("td:nth-child(7)").html() ); $(this).find(".fbspend").html(fbspend); //Profit var profit= asrev - fbspend; $(this).find(".profit").html(profit).css('color','#479e3a'); 的数组。您可以使用Longest common subsequence problem的变体或稍微修改您的算法以找到最佳匹配。

答案 1 :(得分:1)

因此,您可以找到要找到的单词和一个由要检查的句子组成的文本。

  1. 创建单词数组的索引。
  2. 例如,如果words = a dog is not a human

    {
        "a": [1, 5],
        "dog": [2],
        "is": [3],
        "not": [4],
        "human": [6]
    }
    
    1. 在每个句子中,按照降序顺序将索引值替换为每个单词。也就是说,"a"[5, 1]取代,"human"[6]取代,"tree"[]取代。
    2. 例如,句子"not a cat is a human"应变为[4, 5,1, 3, 5,1, 6]

      1. 在每个数组中找到Longest increasing subsequence(LIS)。从本质上讲,LIS将是句子中单词数组中最长的子匹配。
      2. 例如,[4, 5,1, 3, 5,1, 6]的LIS为[1, 3, 5, 6],其映射到子匹配"a is a human"

        但一般来说,如果这些词语不应该相距很远,我建议使用动态编程找到LIS并进行相应的修改。