在 PHP 中使用外部字母数组在字符串处进行排列


Permutate at string in PHP using external array of letters

更新:让我改写一下我的问题:

取一个字符串: (x(ello (y(orld

我想找到所有可能的组合,我使用 PHP 用字母 w,z 和 c 代替 (x( 和 (y(。我下面的方法显然是错误的...


老问题

我正在研究一个 PHP 函数,以查找字符串的所有可能组合,用字符列表替换某些字符。

假设字符串是"Hello World",我想找到所有可能的组合,其中我用 P 和 K 和 S 替换 H 和 W,因此结果将是:

  • 世界您好
  • 佩洛世界
  • 佩洛·波尔德
  • 佩洛·科尔德
  • 你好库尔德
  • 世界您好
  • 凯洛·波尔德
  • 塞洛·波尔德
  • 塞洛·索尔德
  • 你好索尔德

等等。该列表应包含所有可能的组合。

这是我到目前为止得到的:

/**
 * Get all permuations of a string based on an array of translations
 *
 * @author Kovik :) http://koviko.net/
 * @param string $str
 * @param array $rules
 * @return array
 */
function get_all_permutations($str, array $rules) {
    $rules_power_set = array(array());
    foreach ($rules as $from => $to) {
        foreach ($rules_power_set as $current_set) {
            $rules_power_set[] = array_merge(array($from => $to), $current_set);
        }
    }
    $permutations = array();
    foreach ($rules_power_set as $rules) {
        $permutations[] = strtr($str, $rules);
    }
    return $permutations;
}
$rules = array(
    'H' => 'S',
    'H' => 'K',
    'H' => 'P',
    'W' => 'S',
    'W' => 'K',
    'W' => 'P'
);
$input = "Hello World";
$permutations = get_all_permutations($input, $rules);
print_r($permutations);

结果:

Array
(
[0] => Hello World
[1] => Pello World
[2] => Hello Porld
[3] => Pello Porld
)

我希望这是有道理的,有人已经破解了这个坚果:-(

我不

认为这个问题是重复的,无论如何我无法从链接中获得正确的答案。

这是解决方案(我稍后会解释一下,它是如何工作的(:

/**
 * finds the indexes of characters for replacement letter
 * 
 * @param string $table
 * @param array|string $freeSits array of 
 * letter or string `A|f|p...` can be passed
 * @param bool $caseSensitive
 * @return array
 */
function getSeatNumbers($table, $freeSits, $caseSensitive = false)
{
    if (is_array($freeSits))
    {
        $freeSits= implode('|', $freeSits);
    }
    $flag = $caseSensitive ? '' : 'i' ;

    preg_match_all("/$freeSits/$flag", $table, $match, PREG_OFFSET_CAPTURE);
    $positions = array();
    foreach ($match[0] as $i)
    {
        $positions[] = $i[1];
    }
    return $positions;
}
/**
 * do the sitting
 * @param string $table
 * @param array $seats
 * @param array $guests
 * @param array $variations
 */
function recursiveSitting($table, array $seats, array $guests, &$variations)
{
    $s = $seats;
    while (count($s)) 
    :
        $seat = current($s);
        $s = array_slice($s, 1);
        $t = $table;
        foreach ($guests as $guest) 
        {
            $t[$seat] = $guest;
            if(count($s) > 0)
            {
                recursiveSitting($t,  $s, $guests, $variations);
            }
            $variations[] = $t;
        }
    endwhile;
}

$table = "Hello World";
$freeSits= array('H','W','D');
$guests = array('P','K','S');

$seats = getSeatNumbers($table, $freeSits, true); 
$variations = array($table);
recursiveSitting($table, $seats, $guests, $variations);
echo "<pre>";
//you can sort the array
sort($variations);
print_r($variations);

尝试

<?php
$array  = array("Hello","World");
$rep    = array("H","S","K","P","W");
$c      = array();
foreach($array as $k=>$item):
    foreach($rep as $r):
        $c[$k][] = $r.substr($item,1);
    endforeach;
endforeach;
echo "<pre>";
print_r(myCombine($c));
echo "</pre>";
function myCombine($a)
{
    if(empty($a)) return array();
    $r = array_shift($a);
    foreach($a as $i):
        $s = array();
        foreach($i as $o):
            foreach($r as $j):
                $s[] = $j." ".$o;
            endforeach;
        endforeach;
        $r = $s;
    endforeach;
    return $r;
}
?>

前提是,由于索引重复,您不能有:

$rules = array(
    'H' => 'S',
    'H' => 'K',
    'H' => 'P',
    ...
);

我在玩这个:

$rules = array(
    array(
        "match" => array("H", "W"),
        "replace" => array("Z", "PC")
    ),    
    array(
        "match" => "W",
        "replace" => array("A","CP")
    )
);    
$input = "Hello World";
$results = array();
foreach ($rules as $k => $rule) 
{
    $inputs = array();
    $strings = array_pad($inputs, count($rule["replace"]), $input);
    foreach ($strings as $key => $string) 
    {
        if(is_array($rule["match"]))
        {
            foreach($rule["match"] as $rulematch)
            {
                $results[] = preg_replace("#(".$rulematch.")#", $rule["replace"][$key], $string);
            }
            $results[] = preg_replace("#[(".implode("?)(", $rule["match"])."?)]#", $rule["replace"][$key], $string);
        }
        else 
        {
            $results[] = preg_replace("#(".$rule["match"].")#", $rule["replace"][$key], $string);
        }
    } 
}
var_dump($results);

目前给我:

array (size=8)
    0 => string 'Zello World' (length=11)
    1 => string 'Hello Zorld' (length=11)
    2 => string 'Zello Zorld' (length=11)
    3 => string 'PCello World' (length=12)
    4 => string 'Hello PCorld' (length=12)
    5 => string 'PCello PCorld' (length=13)
    6 => string 'Hello Aorld' (length=11)
    7 => string 'Hello CPorld' (length=12)

不是防弹解决方案,而只是从不同的角度进行调查。

对我有用:

<?php
$leetDict = array(
'a' => array('@', 'q'),
'w' => array('vv', 'v'),
'l' => array('i', '|')
);
function permute($dictWord) {
    global $leetDict;
    if(strlen($dictWord)==0) return;
    $currentLetter = $dictWord{0};
    $restOfWord = substr($dictWord, 1);
    if(array_key_exists($currentLetter, $leetDict)) {
        $substitutions = $leetDict[$currentLetter];
    } else {
        $substitutions = array($currentLetter);
    }
    if(strlen($restOfWord)>0) {
        $perms = array();
        foreach($substitutions as $s) {
            foreach($substitutions as $s) {
                foreach(permute($restOfWord) as $p) {
                    $perms[] = $s . $p;
                }
            }
        }
    } else {
        $perms = $substitutions;
    }
    return $perms;
}
$result = permute("Hola");
print_r($result);

返回:

Array
(
    [0] => Hoi@
    [1] => Hoiq
    [2] => Ho|@
    [3] => Ho|q
    [4] => Hoi@
    [5] => Hoiq
    [6] => Ho|@
    [7] => Ho|q
)