使用外部字母数组在PHP中置换字符串

时间:2014-08-15 09:21:31

标签: php permutation

更新: 让我重新解释一下我的问题:

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

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


旧问题

我正在使用PHP函数来查找字符串的所有可能组合,将某些字符替换为字符列表。

说字符串是" Hello World"我想找到所有可能的组合,用P和K和S代替H和W,结果将是:

  • Hello World
  • Pello World
  • Pello Porld
  • Pello Korld
  • Hello Korld
  • Hello World
  • Kello Porld
  • Sello Porld
  • Sello Sorld
  • Hello Sorld
  • ...

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

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

/**
 * 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
)

我希望它有道理并且有人破解了这个坚果: - )

4 个答案:

答案 0 :(得分:1)

尝试

<?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;
}
?>

答案 1 :(得分:1)

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

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

/**
 * 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);

答案 2 :(得分:0)

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

$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)

不是一个防弹解决方案,而只是一个不同的视角来调查。

答案 3 :(得分:0)

适合我:

<?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
)