0

辞書のプレースホルダーを置き換えて文字列を拡張したいとします。置換文字列には、プレースホルダーを含めることもできます。

$pattern = "#a# #b#";
$dict = array("a" => "foo", "b" => "bar #c#", "c" => "baz");
while($match_count = preg_match_all('/#([^#])+#/', $pattern, $matches)) {
    for($i=0; $i<$match_count; $i++) {
        $key = $matches[1][$i];
        if(!isset($dict[$key])) { throw new Exception("'$key' not found!"); }
        $pattern = str_replace($matches[0][$i], $dict[$key], $pattern); 
     }   
}
echo $pattern;

たとえば、循環置換パターンがない限り、これは正常に機能します"c" => "#b#"。その後、メモリが使い果たされるまで、プログラムは無限ループにスローされます。

そのようなパターンを検出する簡単な方法はありますか? 置換間の距離が任意に長くなる可能性があるソリューションを探しています。a->b->c->d->f->a
理想的には、別の分析ではなく、ループ内でも解決策が発生することです。

4

2 に答える 2

0

1 文字キー

キーが単一の文字である場合、これは非常に簡単です。値側の文字列にキーである文字が含まれているかどうかを確認するだけです。

foreach ($your_array as $key => $value) {
    foreach(str_split($value) as $ch) {
        if(array_key_exists ($ch,$your_array) {
            #Problem, cycle is possible
        }
    }
}
#We're fine

サイクルがあったとしても、すべての文字列で発生するわけではありません (たとえば、空の文字列では、パターンは発生しないため、サイクルは発生しません)。その場合、それをチェッカーに組み込むことができます。ルールが 2 回目に起動されると、問題が発生します。これが事実である場合、前のパターンがこの機会を生成したという単純な理由で、機会は何度も何度も生成されます。

文字列キー

キーも文字列である場合、これはおそらく決定不能なPost Correspondence Problemです...

于 2014-08-07T15:18:31.913 に答える