如果包含在特定的结尾列表中,则删除单词结尾

时间:2013-10-14 13:50:27

标签: java performance algorithm

我正在努力提高效率,对我来说很光鲜。

我正在处理的问题是,如果该结尾位于特定列表中,我需要删除结尾一词。

即假设列表是:

{ical, ic,ion,ogy} //the actual list is a handful of elements (almost ~20)

当我遇到这样的句子时,我需要做的是:

Hello world, this sentence is magic. Because we will talk about Biology.

它将缩减为:

Hello world, this sentence is **mag** . Because we will talk about **Biol** .

最简单的方法是迭代句子中的单词,并检查每个结尾是否与列表中的元素匹配......但这非常昂贵。

有没有更简单的方法来实现上述目标?

* ALSO *

您可以使用一个大型REGEX执行此操作:

(?<=([a-zA-Z]))(ic|ical|ics|raphy|raphic|raphical|ion|ions|ional|ive|ivity|ity|ities|ische|ischen|ischer|isches|ogy|ogic|ogical|omy|omic|omics|omical)(?=(\b))

3 个答案:

答案 0 :(得分:4)

简单方法:

构建regular expression输入字符串,并将所有出现的正则表达式替换为空。

正则表达式将采用以下形式:

(a|b|c)\\b

(a|b|c)匹配abc \\b是一个单词边界,表示单词的结尾。

代码:

String[] arr = {"ical", "ic", "ion", "ogy"};
String input = "Hello world, this sentence is magic. Because we will talk about Biology.";
String regex = "(" + arr[0];
for (String s: arr)
   regex += "|" + s; // using Pattern.quote(s) instead of s here would be safer
regex += ")\\b";
input = input.replaceAll(regex, "");
System.out.println(input);

打印:

Hello world, this sentence is mag. Because we will talk about Biol.

更复杂的方法:

构建trie个后缀,但反向

从后面处理字符串。

如果你得到一个单词的开头,请查看trie中的下一个字符,如果你在trie中找到匹配项,请将它们删除。

最后使用StringBuilderStringBuilder.reverse()来有效地执行此操作。

示例:

假设:

ical, ic, ion, ogy

你的特里会看起来像:

          .
         /|\
      y // \\ l
       /n| |c\
      .  . .  .
     g| o| |i |a
      .  . X  .
     o| i|    |c
      X  X    .
              |i
              X

X是终止节点(后缀的结尾),.是非终止节点)

输入:

John Biology.

反向处理......

流程:"."

不是一个字,只需添加到输出。

输出= "."

流程:"Biology"

root有一个y子节点,所以我们移动到那个节点 该节点有一个g孩子,所以我们继续前进 该节点有一个o子节点,所以我们继续前进。 然后我们到达了一个终止节点,因此丢弃已处理的字符并打印出其余的单词。

输出:".loiB"

流程:" "

不是一个字,只需添加到输出。

输出= ".loiB "

流程:"John"

root有一个n子节点,所以我们移动到那个节点 该节点没有h子节点,因此我们停止并输出处理后的字符以及单词的其余部分(即输出整个单词)。

输出= ".loiB nhoJ"

反向,给我们:"John Biol."

答案 1 :(得分:1)

我不知道这是否比循环更有效(我怀疑它是),但为什么不使用带有replaceAll()的正则表达式去除它们结尾的单词。

\ b标签确保只捕获单词结尾。

public class TestRegEx {

public static final String SENTENCE = "Hello world, this sentence is magic. Because we will talk about Biology. Physical. Reunion.";
public static final String PATTERN = "(ic|ogy|ical|ion)\\b";

public static void main(String[] args) {

     System.out.println(SENTENCE.replaceAll(PATTERN, ""));
    }
} 

我得到的输出是:

你好世界,这句话是mag。因为我们会谈论Biol。物理学。 Reun。

希望有所帮助。

答案 2 :(得分:0)

如果您要检查的结尾数量有限,则可以为每个结尾生成正则表达式。这应该允许有效的检查,如果结束发生,你不需要拆分句子,并可以在一行中进行替换。

可悲的是,我的java正则表达式知识不够好,我可以动态构建所需的正则表达式,但你可以看看。但是有很多good tutorials out there