php需要所有可能的更改值

时间:2013-11-22 15:28:23

标签: php arrays replace

我需要更改字符串中的每个字符,但此更改包括所有可能的结果。数组变量的键和值可以互相替换

例如所有字母的列表类似于下面的

$changeList=array(
"ş"=>"s",
"ç"=>"c",
"i"=>"ı",
"ğ"=>"ğ",
"ü"=>"u",
"ö"=>"o",
"Ş"=>"S",
"Ç"=>"C",
"İ"=>"I",
"Ğ"=>"G",
"Ü"=>"U",
"Ö"=>"O"
);

$word="ağaç";

如果我计算正确,这是可能的2 ^ 2 = 4结果。 (对于ğ和ç字母) 在替换所有字母后,我需要这个结果。

  1. AGAC
  2. AGAC
  3. AGAC
  4. AGAC
  5. 和其他单词example =pişir 这个词包括多变的三个字母。 2 ^ 3 = 8个结果。 (对于s,ı,ç3个字母)

    1. pişir
    2. pışir
    3. pisir
    4. pişır
    5. pişır
    6. pisır
    7. pısır
    8. pışır
    9. 我需要一个包含所有结果的数组变量。如何以最佳表现完成此任务。

1 个答案:

答案 0 :(得分:1)

好吧,我对此有点痴迷,决定去吧(嘿,这是星期五晚上)。

正如我在上面的评论中所指出的,您希望为每个单独的字母更改生成一个新的单词变体 - 包括多次出现的字母。另一个棘手的考虑因素是多字节字符。

接下来的尝试是一个可能非常不理想的答案,但希望完成工作......我确信有很多方法可以改进这个但是这是一个你可能能够迭代的开始:

<?php

// this solution assumes UTF-8 config settings in php.ini
// setting them with ini_set() seems to work also but ymmv
ini_set('default_charset', 'UTF-8');
ini_set('mbstring.internal_encoding', 'UTF-8');

function getWordReplacements($word, $replacements) {

    // $results... add the original
    $results = array($word);

    // multibyte split of $word
    // credit: http://stackoverflow.com/a/2556753/312962
    $chars = preg_split('//u', $word, -1, PREG_SPLIT_NO_EMPTY); 

    // we will iterate over the chars and create replacements twice,
    // first pass is a forward pass, second is a reverse pass
    // we need a copy of the $chars array for each pass
    $forwardPass = $chars;
    $reversePass = $chars;

    // how many chars in the word?
    $length = count($chars);
    // we'll store the index of the first character 
    // that has a copy in the $replacements list for later
    $first  = null;

    // first pass... iterate!
    for ($i = 0; $i < $length; $i++) {
        // is the current character in the $replacements list?
        if (array_key_exists($chars[$i], $replacements)) {
            // save the index of the first match
            if (is_null($first)) {
                $first = $i;
            }
            // replace the found char with the translation
            $forwardPass[$i] = $replacements[$forwardPass[$i]];
            // flatten the result and save it as a variation
            $results[] = implode($forwardPass);
        }
    }

    // second pass... same as the first pass except:
    // * we go backwards through the array
    // * we stop before we reach the $first index, to avoid a duplicate
    //   entry of the first variation saved in the first pass...
    for ($j = ($length - 1); $j > $first; $j--) {
        if (array_key_exists($chars[$j], $replacements)) {
            $reversePass[$j] = $replacements[$reversePass[$j]];
            $results[] = implode($reversePass);
        }
    }

    // return the results
    return $results;
}

// test with a subset replacement list
$list = [
    'ç' => 'c',
    'ğ' => 'g',
    'ş' => 's',
    'i' => 'ı',
];

// a couple of examples
$r1 = getWordReplacements('pişir', $list);
$r2 = getWordReplacements('ağaç', $list);

var_dump($r1, $r2);

收率:

array (size=6)
  0 => string 'pişir' (length=6)
  1 => string 'pışir' (length=7)
  2 => string 'pısir' (length=6)
  3 => string 'pısır' (length=7)
  4 => string 'pişır' (length=7)
  5 => string 'pisır' (length=6)
array (size=4)
  0 => string 'ağaç' (length=6)
  1 => string 'agaç' (length=5)
  2 => string 'agac' (length=4)
  3 => string 'ağac' (length=5)

希望这会有所帮助:)