将所有A替换为B并将所有B替换为A.

时间:2015-08-19 02:47:41

标签: algorithm replace language-agnostic

假设我要切换某些单词对。比方说,我想用老鼠小鼠切换,以便

  

这是我对狗和猫的看法:我喜欢狗,但我不喜欢猫。这是我对老鼠和老鼠的看法:我害怕老鼠,但我不怕老鼠。

变为

  

这是我对猫狗的看法:我喜欢猫,但我不喜欢狗。这是我对老鼠和老鼠的看法:我害怕老鼠,但我不怕老鼠。

naїve方法

text = text.replace("dogs", "cats")
           .replace("cats", "dogs")
           .replace("mice", "rats")
           .replace("rats", "mice")

是有问题的,因为它可以多次对相同的单词执行替换。上述任何一个句子都将成为

  

这是我对狗和狗的看法:我喜欢狗,但我不喜欢狗。这是我对老鼠和老鼠的看法:我害怕老鼠,但我不怕老鼠。

什么是最简单的替换字符串对的算法,同时防止多次更换某些内容?

3 个答案:

答案 0 :(得分:3)

使用您认为合适的字符串搜索算法,只要它能够搜索正则表达式。搜索与您要交换的所有字词匹配的正则表达式,例如dogs|cats|mice|rats。维护一个单独的字符串(在许多语言中,这需要某种StringBuilder以便重复追加快速)结果,最初为空。对于每个匹配,您在前一个匹配的结尾(或字符串的开头)和当前匹配之间追加字符,然后将相应的替换(可能从散列映射获得)附加到结果。

大多数标准库应该允许您使用内置方法轻松完成此操作。有关Java示例,请参阅Matcher.appendReplacement(StringBuffer, String)的文档。我记得在C#中也这样做,使用一个功能,您可以指定一个lambda函数来决定用每个匹配替换的内容。

答案 1 :(得分:3)

避免任何意外结果的天真解决方案是用临时字符串替换每个字符串,然后用最终字符串替换临时字符串。但是,假设您可以在文本中形成一个已知的字符串,例如

copy_*

答案 2 :(得分:1)

我确实不熟悉正则表达式,所以我的想法是创建一个数组然后遍历元素以查看是否应该替换它。首先将split()句子变成一个单词数组:

String text = "This is my opinion about dogs and cats: I like dogs but I don't like cats.";
String[] sentence = text.split("[^a-zA-Z]"); //can't avoid regex here

然后使用for循环,其中包含一系列if语句来替换单词:

for(int i = 0; i < sentence.length; i++) {
    if(sentence[i].equals("cats") {
        sentence[i] = "dogs";
    }
    //more similar if statements
}

现在sentence[]包含带有单词的新句子。一些正则表达式魔法应该允许你也保持标点符号。我希望这会有所帮助,如果有任何改进,请告诉我。