0

文字列「foo1bar2」があり、「bar1foo2」の期待される出力と並行して次の置換を実行するために置換したいとします。

foo => bar
bar => foo

サブストリングはどこでも、何度でも発生する可能性があるため、ストリングをトークン化することはできません。

素朴なアプローチは、このように置き換えることですが、2番目の置き換えが最初の置き換えを元に戻すため、失敗します。

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

また

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

正規表現がここでも役立つかどうかわかりませんか?ちなみに、これは宿題ではなく、オタク的な興味です。私はこれをグーグルで調べてみましたが、問題を説明する方法がわかりません。

4

2 に答える 2

2

最初に「foo」を文字列内の他の場所では発生しない他のものに置き換えてみてください。次に、「bar」を「foo」に置き換え、手順1の一時的な置き換えを「bar」に置き換えます。

于 2012-11-20T03:20:20.750 に答える
2

私は実際にはCode-Guruの答えの方が好きですが、それは単なる好奇心だとおっしゃっていたので、ここに再帰的な解決策があります。アイデアは、置き換えようとしている文字列の一部だけを分離し、残りの部分を繰り返して、すでに行ったものを誤って置き換えないようにすることです。ここで、2つのルールに共通のプレフィックスがある場合、目的の結果を得るには、ルールの順序付けを行う必要がある場合がありますが、次のようになります。

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 に答える