实现一个字符串的所有排列组合

/*
 * 求一个字符串所有的排列组合,字符串可以有重复的字符,
 * 
 *(注意如果字符串中间有数组的话是没有进行清除的)
 */
/*
 * 思路:
 * 1.检查字符串是否规范,检查字符串长度,如果为空或者只有一个字符,直接输出,
 * 如果大于1初始化链表list并进行下面操作;
 * 2.从第一个字符开始逐一从后面取一个字符
 * 3.用一个缓存数组flag寄存前面的链表list,并清空链表list;
 * 4.将取出的字符与前面的字符串所排列出的各种组合进行重新排列,
 * 即用该字符与每一个缓存的flag键值进行排列;
 * 5.每生成一个新的字符串要与前面的已经排列好的字符进行对比,如果有重复的,则放弃加入链表list
 * 6.按照前面的步骤列出每一个不重复的字符串加入链表list,直到找出所有的排列
 */
class string_combinations {
    private $string;
    private  $list;
    public function __construct($string) { // 初始化
        $this->string = trim ( $string );
        $this->list = array ();
    }
    private  function check_str() {
        // 检查字符串
    }
    public function str_insert($string, $replace, $afternum) { // 将指定字符串插入指定的位置后面
        $before = substr ( $string, 0, $afternum );
        $after = substr ( $string, $afternum );
        $newstr = $before . $replace . $after;
        return $newstr;
    }
    public function str_combinations() {
        $list = $this->list; // 字符串排列数组
        $str = $this->string;
        $str_len = strlen ( $str ); // 字符串长度
        if ($str_len <= 1) { // 如果字符串长度为1,直接输出,并停止执行后面的代码
            $this->list [] = $str;
            return $this->list;
            exit ();
        }
        $flag = array (); // 缓存数组
        $list [] = substr ( $str, 0, 1 ); // 为$list设置初值
        for($i = 1; $i < $str_len; $i ++) { // 如果字符串大于1,执行n-1次循环
            $replace = substr ( $str, $i, 1 ); // 取出下一个要替换的字符
            unset ( $flag ); // 清空上一次的缓存
            $flag = $list; // 将上一次排列好的数组赋值给新的缓存
            $list = array (); // 清空上一次排列好的内容,准备接收新内容,注意不能用unset()清空,因为后面还要将其作为数组使用,而如果清空了,当没有数据时,其就是个普通变量
            $laststrlen = strlen ( $flag [0] ); // 上一次排列的字符串的长度
            foreach ( $flag as $value ) {
                for($k = $laststrlen; $k >= 0; $k --) { // 要替换的字符串的插入位置有$flag2str_len+1个,因此执行$flag2str_len次插入操作
                    $v = $this->str_insert ( $value, $replace, $k );
                    $res = array_search ( $v, $list ); // 检查数组中是否存在该值
                    if ($res === false) { // 如果不存在该值,则加入数组,如果存在不加入链表
                        $list [] = $v;
                    }
                }
            }
        }
        $this->list = $list;
        return $this->list;
    }
}
/* 测试 */
$str = '123';
$strcom = new string_combinations ( $str );
$list = $strcom->str_combinations ();
var_dump ( $list );
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值