0

假设我有字符串“foo1bar2”,我想替换以与预期的“bar1foo2”输出并行执行以下替换。

foo => bar
bar => foo

字符串不能被标记,因为子字符串可能出现在任何地方,任何次数。

一种天真的方法是像这样替换,但是它会失败,因为第二次替换会撤消第一次。

String output = input.replace("foo", "bar").replace("bar", "foo");
=> foo1foo2

或者

String output = input.replace("bar", "foo").replace("foo", "bar");
=> bar1bar2

我不确定正则表达式也可以在这里帮助我吗?顺便说一句,这不是功课,只是极客的兴趣。我试过用谷歌搜索,但不确定如何描述这个问题。

4

2 回答 2

2

我实际上更喜欢 Code-Guru 的回答,但既然你说这只是一种好奇心,这里有一个递归解决方案。这个想法是只隔离您要替换的字符串的一部分并在其余部分上递归,这样我们就不会意外替换我们已经做过的东西。现在,如果您的两个规则有一个共同的前缀,您可能需要对规则进行一些排序才能获得所需的结果,但这里是:

public class ParallelReplace
{
    public String replace(String s, Rule... rules)
    {
        return runRule(s, 0, rules);
    }

    private String runRule(String s, int curRule, Rule... rules)
    {
        if (curRule == rules.length)
        {
            return s;
        }
        else
        {
            Rule r = rules[curRule];
            int index = s.indexOf(r.lhs);

            if (index != -1)
            {
                return runRule(s.substring(0, index), curRule + 1, rules) + r.rhs
                        + runRule(s.substring(index + r.rhs.length()), curRule + 1, rules);
            }
            else
            {
                return runRule(s, curRule + 1, rules);
            }
        }
    }

    public static class Rule
    {
        public String lhs;
        public String rhs;

        public Rule(String lhs, String rhs)
        {
            this.lhs = lhs;
            this.rhs = rhs;
        }
    }

    public static void main(String[] args)
    {
        String s = "foo1bar2";
        ParallelReplace pr = new ParallelReplace();

        System.out.println(pr.replace(s, new Rule("foo", "bar"), new Rule("bar", "foo")));
    }
}
于 2012-11-20T03:52:59.270 回答
2

首先尝试将“foo”替换为字符串中其他任何地方都不会出现的其他内容。然后用“foo”替换“bar”,然后用“bar”替换第 1 步中的临时替换。

于 2012-11-20T03:20:20.750 回答