【问题标题】:How can I read all of the paragraphs of a text into a list?如何将文本的所有段落读入列表?
【发布时间】:2014-06-18 11:09:05
【问题描述】:

我正在尝试将文本分成不同的段落。我确实找到了this 问题和this 问题。但是,我已经想出了如何检测段落。我无法保存它们。

One morning, when Gregor Samsa woke from troubled dreams, he found
himself transformed in his bed into a horrible vermin.  He lay on
his armour-like back, and if he lifted his head a little he could
see his brown belly, slightly domed and divided by arches into stiff
sections.  The bedding was hardly able to cover it and seemed ready
to slide off any moment.  His many legs, pitifully thin compared
with the size of the rest of him, waved about helplessly as he
looked.

"What's happened to me?" he thought.  It wasn't a dream.  His room,
a proper human room although a little too small, lay peacefully
between its four familiar walls.  A collection of textile samples

以上文字将被计为两段。下面是我用于段落检测的函数。

public List<Paragraph> findParagraph(List<String> originalBook)
{
    List<Paragraph> paragraphs = new LinkedList<Paragraph>();
    List<String> sentences = new LinkedList<String>();


    for(int i=0;i<originalBook.size();i++)
    {
        //if it isn't a blank line
        //don't count I,II symbols
        if(!originalBook.get(i).equalsIgnoreCase("") & originalBook.get(i).length()>2)
        {
            sentences.add(originalBook.remove(i));

            //if the line ahead of where you are is a blank line you've reach the end of the paragraph
            if(i < originalBook.size()-1)
            {
                if(originalBook.get(i+1).equalsIgnoreCase("") )
                {
                    Paragraph paragraph = new Paragraph();
                    List<String> strings = sentences;
                    paragraph.setSentences(strings);
                    paragraphs.add(paragraph);
                    sentences.clear();
                }
            }
        }

    }

    return paragraphs;
}

这是定义我的段落的类

public class Paragraph
{

    private List<String> sentences;

    public Paragraph()
    {
        super();
    }


    public List<String> getSentences() {
        return sentences;
    }

    public void setSentences(List<String> sentences) {
        this.sentences = sentences;
    }

}

我能够很好地检测到段落,但我正在清除所有句子并且得到一个仅包含最后一段的列表。我一直在想一个解决方案,但我一直无法想出一个解决方案。谁能给点建议?

我的解释尽可能详尽。如果需要,我可以添加更多详细信息。

【问题讨论】:

    标签: java text-processing text-parsing


    【解决方案1】:

    问题出在这个区块中:

    Paragraph paragraph = new Paragraph();
    List<String> strings = sentences; // <-- !!!!!
    paragraph.setSentences(strings);
    paragraphs.add(paragraph);
    sentences.clear();
    

    您使用sentences 指向的所有段落的相同 对象,因此最终所有Paragraph 对象将指向相同 @987654324 @。因此,您对 sentences 所做的任何更改都将更改该单个 List&lt;String&gt;,并且这些更改将在您的所有 Paragraph 对象中看到,因为它们都引用同一个实例。

    这有点像sentences 是一个气球,你正在做的是给你所有的Paragraph 对象一个通向那个气球的字符串(加上另一个返回到sentences 的字符串)。如果其中一个对象(或sentences 引用)决定跟随字符串并弹出气球,每个人都会看到变化。

    解决方案很简单。跳过sentences.clear() 并简单地使用List&lt;String&gt; strings = new LinkedList&lt;&gt;() 而不是List&lt;String&gt; strings = sentences。这样一来,您所有的Paragraph 对象都将有不同 List&lt;String&gt; 对象来保存它们的句子,并且您对其中任何一个对象所做的更改都将独立于另一个。如果这样做,您也可以跳过在方法开头声明sentences

    【讨论】:

    • 我不知道为什么我没有想到这一点。有时你只需要一双新鲜的眼睛。谢谢。
    【解决方案2】:

    您可以将代码更改为更高效、更简洁,而不是计算其索引并创建多个 if 语句。

    样本:

    Scanner scan = new Scanner(new File("text.txt"));
    String parag = "";
    
    while(scan.hasNextLine())
    {
        String s = scan.nextLine();
        if(s.trim().length() != 0)
            parag += s + "\n"; //new sentence
        else
        {
            System.out.println(parag); //new paragraph
            parag = "";
        }
    }
    
    System.out.println(parag); //last paraggraph
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-02
      • 1970-01-01
      • 1970-01-01
      • 2016-05-15
      • 2021-02-08
      • 1970-01-01
      • 2016-04-28
      • 2020-01-16
      相关资源
      最近更新 更多