查找特定字符串索引(PHP)的给定集合中的所有可能排列

时间:2016-11-18 14:11:56

标签: php string

我这几天一直在绞尽脑汁,我似乎被卡住了。我是PHP的新手,所以请原谅任何邋or或错误。

考虑到一种模式,例如电子邮件地址“ab@?b?.ca”,我需要替换“?”的任何实例来自一组字符'a-e','@'和'。'的所有可能的排列。

这就是我现在所拥有的:

function permute($str, $ch, $i, $n, &$output) {
    if ($i == $n) {
        array_push($output, $str);
    } else {
        for ($x = $i; $x < $n; $x++) {
            for ($y = 0; $y < count($ch); $y++) {
                $str[$x] = $ch[$y];
                permute($str, $ch, $i + 1, $n, $output);
            }
        }
    }
}

# each ? in the pattern to be replaced by all possible permutations of characters in chars array
# a through e as well as @ and .
$output = array();
$chars = range('a', 'e');
array_push($chars, '@');
array_push($chars, '.');

# the pattern to be checked
$pattern = "ab@?b?.ca";
permute($pattern, $chars, 0, strlen($pattern), $output);

......这与我想要的非常接近,但不太正确。该函数对字符串的每个字符进行操作,但它只应该对'?'进行处理。还有什么我可以做的,我错过了吗?如果我弄清楚的话,我会在评论中做出回应并进行编辑!

2 个答案:

答案 0 :(得分:0)

这是我的工作解决方案:

function permute($str, $arr, $i, $n, &$result) {
    $nLen = strlen($n);
    // cycle through every position of needle
    while (($i = strpos($str, $n, $i)) !== false) {
        $i = $i + $nLen;
        // cycle through each replacement value
        foreach ($arr as $value) {
            $modified = substr_replace($str, $value, $i - $nLen, $nLen);
            // if there are no needles left, save it
            if (stristr($modified, $n) === false) {
                $result[] = $modified;
            }
            permute($modified, $arr, $i, $n, $result);
        }
    }
}

# each ? in the pattern to be replaced by all possible permutations of characters in chars array
# a through e as well as @ and .
$chars = range('a', 'e');
array_push($chars, '@');
array_push($chars, '.');

# the pattern to be checked
$pattern = "ab@?b?.ca";
$result = array();
$needle = '?';
$index = 0;

permute($pattern, $chars, $index, $needle, $result);
var_dump($result);

这假设您只想保存没有留针的值。例如,而不是:

array(63) {
  [0]=>
  string(9) "ab@ab?.ca"
  [1]=>
  string(9) "ab@aba.ca"
  [2]=>
  string(9) "ab@abb.ca"
  // etc...

将输出:

array(49) {
  [0]=>
  string(9) "ab@aba.ca"
  [1]=>
  string(9) "ab@abb.ca"
  [2]=>
  string(9) "ab@abc.ca"
  // etc...

如果您确实想要第一个结果,那么只需删除stristr($modified, $n) === false条件。

答案 1 :(得分:0)

这可以做同样的事情,而不必写出算法:

$var = "ab@?b?.co";
$var = str_replace("?","",$var);
print $var;
//ab@b.co

希望这有帮助。