带有重复字符的PHP中的数字排列

时间:2016-02-24 08:07:10

标签: php

我在一个字符串中存储一个数字。我的代码将数字混洗成不同的排列。

输入为:

的示例
'123'

然后输出排列将是:

123,132,213,231,321,312

如果输入字符串有重复的数字,我的代码不起作用,并进入无限循环。

不起作用的示例输入:

11,22,33,44,55,455,998,855,111,555,888,222 etc.

我的代码:

<?php
function factorial($n){
    if($n==1) return $n;

    return $n*factorial($n-1);
}

$a   = '1234';
$_a  = str_split($a);
$num = count($_a);
$ele_amnt = factorial($num);
$output = array();
while(count($output) < $ele_amnt){
    shuffle($_a);
    $justnumber = implode('', $_a);
    if(!in_array($justnumber , $output))
        $output[] = $justnumber;

}
sort($output);
print_r($output);

任何人都可以解释为什么以及如何解决它?

2 个答案:

答案 0 :(得分:2)

简短版本:while循环的终止条件&#34;是&#34;在$a=11;测试&#34;是&#34; gradle documentation permutational

我们假设为$ele_amnt:然后2<firstelement><seconelement>,当数组$ output包含多个元素时,您的while循环将停止。
您的shuffle / implode代码可以生成字符串<secondelement><firstelement>11,两者都是if(!in_array( $justnumber , $output))
并且Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL' at line 1 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:526) at com.mysql.jdbc.Util.handleNewInstance(Util.java:406) at com.mysql.jdbc.Util.getInstance(Util.java:381) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1030) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3491) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3423) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1936) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2542) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1734) at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:995) at com.coolminds.action.OperatorBillCorrection.main(OperatorBillCorrection.java:27) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 只允许其中一个附加到$ output。所以count($ output)在第一次迭代后将为1,并将永久保持1。每个$ a都有相同的重复数字。

combinational随机更改数组中元素的位置。所以,算法的性能取决于....运气;-) 您可能会对shuffle()之类的内容感兴趣。

答案 1 :(得分:0)

如果输入中有重复的字符,则输出数组将包含较少的排列。所以你的循环永远不会完成。

您可以映射输入,然后从输出中重新映射,然后根据需要进行过滤:

// For a string '122' we get the permutations of '123' first and then process.

$output = op_code_no_repeats('123');

$filtered = array();
foreach($output as $permutation) {
    $filtered[] = str_replace('3', '2', $permutation);
}
$filtered = array_unique($filtered);

var_dump($filtered);

输出:

array (size=3)
  0 => string '122' (length=3)
  2 => string '212' (length=3)
  3 => string '221' (length=3)

你的代码带有关于阶乘和置换函数的守卫:

function factorial($n)
{
    if(! is_int($n) || $n < 1)
        throw new Exception('Input must be a positive integer.');
    if($n==1)
        return $n;

    return $n * factorial($n-1);
};

function op_code_no_repeats($a) {

    $_a  = str_split($a);

    if(array_unique($_a) !== $_a)
        throw new Exception('Does not work for strings with repeated characters.');

    $num = count($_a);
    $perms_count = factorial($num);

    $output = array();
    while(count($output) < $perms_count){
        shuffle($_a);
        $justnumber = implode('', $_a);
        if(!in_array($justnumber , $output))
            $output[] = $justnumber;
    }
    sort($output);

    return $output;
}