有一个字符映射,如下所示:
$replacements = array(
array('a', 'b'), // a => b
array('a', 'c'), // a => c
array('b', 'n'),
array('c', 'x'),
);
还有一个输入字符串,比如说“cbaa”。如何获得所有组合,其中至少有一个字符被替换为其中一个替换字符?在这个例子中,“a”可以替换为“b”和“c”,因此字符串包括:
xbaa
cnaa
xbba
cbca
cbab
cbac
...
xnaa
xnac
...
答案 0 :(得分:2)
$replacements = array(
array('a', 'b'), // a => b
array('a', 'c'), // a => c
array('b', 'n'),
array('c', 'x'),
);
$str = 'cbaa';
// lets change replacements format
$replacementsSorted = array();
foreach ($replacements as $pair) {
if (isset($replacementsSorted[$pair[0]])) {
$replacementsSorted[$pair[0]][] = $pair[1];
} else {
$replacementsSorted[$pair[0]] = array($pair[1]);
}
}
$replacements = $replacementsSorted;
class Combine {
private static $_result = array();
static function run($str, $replacements, $start) {
self::$_result[] = $str;
$l = strlen($str);
for ($i = $start; $i < $l; $i++) {
if (isset($replacements[$str[$i]])) {
foreach ($replacements[$str[$i]] as $key => $val) {
$str[$i] = $val;
if (in_array($str, self::$_result)) {
continue;
}
// call recursion
self::run($str, $replacements, $i+1);
}
}
}
return self::$_result;
}
}
var_dump( Combine::run($str, $replacements, 0) );
答案 1 :(得分:2)
以下是Dmitry Tarasov代码的修改版本(请给他所有信用),这似乎正常。
class Combine {
private static $_result = array();
public static function run($str, $replacements){
self::_run($str, $replacements, 0);
return array_values(array_unique(self::$_result));
}
private static function _run($str, $replacements, $start){
self::$_result[] = $str;
for($i = $start, $l = strlen($str); $i < $l; $i++){
self::_run($str, $replacements, $i+1);
if(isset($replacements[$str[$i]])){
foreach($replacements[$str[$i]] as $key => $val){
$str[$i] = $val;
// call recursion
self::_run($str, $replacements, $i+1);
}
}
}
}
}
print_r( Combine::run($str, $replacements) );
引入私有函数是为了避免重复执行多次繁重的数组操作,而不是在root调用的任何地方使用它们。
答案 2 :(得分:0)
function combi($str, $replac, &$result, $builtstr="", $pos=0) {
$len = strlen($str);
if ($pos == $len) {
if ($builtstr != $str)
$result[] = $builtstr;
return;
}
$c = $str[$pos];
$poss = array();
$poss[] = $c;
foreach($replac as $v) {
if ($v[0] == $c)
$poss[] = $v[1];
}
foreach($poss as $k=>$c_repl) {
combi($str, $replac, $result, $builtstr . $c_repl, $pos+1);
}
}
$combinations = array();
combi("cbaa", $replacements, $combinations);
答案 3 :(得分:0)
<?php
error_reporting(E_ALL | E_STRICT);
$replacements = array(
array('a', 'b'), // a => b
array('a', 'c'), // a => c
array('b', 'n'),
array('c', 'x'),
);
$inputstr = "cbaa";
$hash = array(); // hash map maps originals characters with an array of the original character and the other replacements
foreach ($replacements as $pair) {
if (!isset($hash[$pair[0]])) { $hash[$pair[0]] = array($pair[0]); }
$hash[$pair[0]][] = $pair[1];
}
echo "hash:\n";
print_r($hash);
$to_flat = array_map(function($c) use ($hash) { // maps original input string characters to an array of candidates
return $hash[$c];
}, str_split($inputstr));
echo "to_flat:\n";
print_r($to_flat);
$perms = array_reduce($to_flat, function($akku, $letter_targets){
$theseperms = array();
foreach ($akku as $work) { // for each permutation made
foreach ($letter_targets as $target) { // for each character candidate
$newakku = $work;
$newakku .= $target;
$theseperms[] = $newakku;
}
}
return $theseperms;
}, array(""));
unset($perms[array_search($inputstr, $perms, true)]); //remove cbaa
$perms = array_values($perms); //reset keys
echo "perms:\n";
print_r($perms);
?>