Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 生成字符串及其子字符串列表置换的算法_Algorithm_List_Permutation - Fatal编程技术网

Algorithm 生成字符串及其子字符串列表置换的算法

Algorithm 生成字符串及其子字符串列表置换的算法,algorithm,list,permutation,Algorithm,List,Permutation,这个算法已经逃避我一段时间了。假设我得到了字符串“cccaatt”。我试图生成重复字母的每个子串的所有可能变化。例如,“cccaatt”作为输入将返回: 猫, 卡特, caat, 卡亚特, ccat, ccatt, ccaat, ccaatt, cccat, cccatt, 中国民航总局, cccaatt 结果的顺序并不重要,只要它返回所有结果。通常,输入是一个字符串,由g组重复字母组成,每组k_n个字母长 我的直觉是,这是一个递归算法,但它的确切结构一直很难理解 将字符串分解为数字列表和重复次

这个算法已经逃避我一段时间了。假设我得到了字符串“cccaatt”。我试图生成重复字母的每个子串的所有可能变化。例如,“cccaatt”作为输入将返回:

猫, 卡特, caat, 卡亚特, ccat, ccatt, ccaat, ccaatt, cccat, cccatt, 中国民航总局, cccaatt

结果的顺序并不重要,只要它返回所有结果。通常,输入是一个字符串,由g组重复字母组成,每组k_n个字母长


我的直觉是,这是一个递归算法,但它的确切结构一直很难理解

将字符串分解为数字列表和重复次数,即“cccaatt”=>[(c,3),(a,2),(t,2)]。然后可以递归地定义问题

Let xs = [(a_1, n_1), (a_2, n_2), (a_3, n_3), ... (a_k, n_k)]
define Perm(xs):
    if len(xs) == 1:
        return all length variations of xs
    else:
        return every sequence in Perm(x[:-1]) appended with one or more from x[-1]
我很快就会有一个python示例

perm(“cccaatt”) >['cat','ccat','cccat','caat','ccaat','catt','ccatt','cccatt','caatt','ccatt','cccaatt'] 附加代码

def perm(xs):
如果不是xs:
返回[]
#将它们分组为正确的格式,可能应该使用groupby+zip
l=[(xs[0],1)]
对于xs[1:]中的x:
最后,num=l[-1]
如果last==x:
l[-1]=(最后一个,num+1)
其他:
l、 附加((x,1))
#印刷品(l)
打印(递归(l))
#这是真正的工作要做的地方。
def递归(xs):
如果len(xs)==1:
返回[xs[0][0]*x代表范围(1,xs[0][1]+1)内的x)
prev=递归(xs[:-1])
char,num=xs[-1]
返回[y+x*char代表上一页y的范围(1,num+1)中的x]

如果您存储字母表和每个字母的最大出现次数(如注释中所述),您可以执行以下操作:

function variations(letter_type, current string) {
    if (letter_type is in the alphabet) {
        while (string has fewer than the max amount of that letter) {
            add one of that letter to current string
            variations(next letter, current string)
        }
    } else {
        print current string // since there are no more letters to add
    }
}
在Java中:

public class Variations {

    static String[] alphabet = {"c","a","t"};
    static int[] maximums = {3, 2, 2};

    public static void main(String[] args) {
        variations(0, "");
    }

    public static void variations(int letter_type, String curr) {
        if (letter_type < alphabet.length) {
            for (int i = 1; i <= maximums[letter_type]; i++) {
            curr += alphabet[letter_type];
            variations(letter_type+1, curr);
            }
        } else {
            System.out.println(curr);
        } 
    }

}
公共类变体{
静态字符串[]字母表={“c”,“a”,“t”};
静态int[]最大值={3,2,2};
公共静态void main(字符串[]args){
变化(0“”);
}
公共静态无效变量(整数字母类型,字符串货币){
if(字母类型<字母表长度){

对于(inti=1;i,pythonitertools模块具有强大的工具来分组,然后迭代组中的成员,从而生成以下程序

我展示了一些中间结果,并使用pprint模块预打印了答案:

Python 2.7.3 (default, Aug  1 2012, 05:16:07) 
[GCC 4.6.3] on linux2
Type "copyright", "credits" or "license()" for more information.
>>> import itertools
>>> instring = "cccaatt"
>>> [(x[0], list(x[1])) for x in itertools.groupby(instring)]
[('c', ['c', 'c', 'c']), ('a', ['a', 'a']), ('t', ['t', 't'])]
>>> xx = [list(x[0]*n for n in range(1, len(list(x[1]))+1)) for x in itertools.groupby(instring)]
>>> xx
[['c', 'cc', 'ccc'], ['a', 'aa'], ['t', 'tt']]
>>> list(itertools.product(*xx))
[('c', 'a', 't'), ('c', 'a', 'tt'), ('c', 'aa', 't'), ('c', 'aa', 'tt'), ('cc', 'a', 't'), ('cc', 'a', 'tt'), ('cc', 'aa', 't'), ('cc', 'aa', 'tt'), ('ccc', 'a', 't'), ('ccc', 'a', 'tt'), ('ccc', 'aa', 't'), ('ccc', 'aa', 'tt')]
>>> from pprint import pprint as pp
>>> pp(list(itertools.product(*xx)))
[('c', 'a', 't'),
 ('c', 'a', 'tt'),
 ('c', 'aa', 't'),
 ('c', 'aa', 'tt'),
 ('cc', 'a', 't'),
 ('cc', 'a', 'tt'),
 ('cc', 'aa', 't'),
 ('cc', 'aa', 'tt'),
 ('ccc', 'a', 't'),
 ('ccc', 'a', 'tt'),
 ('ccc', 'aa', 't'),
 ('ccc', 'aa', 'tt')]
>>> 
或者作为一种功能:

>>> def stringexpand(instring):
    xx = [list(x[0]*n for n in range(1, len(list(x[1]))+1)) for x in itertools.groupby(instring)]
    return list(itertools.product(*xx))

>>> pp(stringexpand("cccaatt"))
[('c', 'a', 't'),
 ('c', 'a', 'tt'),
 ('c', 'aa', 't'),
 ('c', 'aa', 'tt'),
 ('cc', 'a', 't'),
 ('cc', 'a', 'tt'),
 ('cc', 'aa', 't'),
 ('cc', 'aa', 'tt'),
 ('ccc', 'a', 't'),
 ('ccc', 'a', 'tt'),
 ('ccc', 'aa', 't'),
 ('ccc', 'aa', 'tt')]
>>> 
您似乎需要从各个部分连接字符串。这可以通过以下方式完成:

def stringexpand(instring):
    xx = [list(x[0]*n for n in range(1, len(list(x[1]))+1)) for x in itertools.groupby(instring)]
    return [''.join(parts) for parts in itertools.product(*xx)]
返回:

['cat',
 'catt',
 'caat',
 'caatt',
 'ccat',
 'ccatt',
 'ccaat',
 'ccaatt',
 'cccat',
 'cccatt',
 'cccaat',
 'cccaatt']

试着保留一个字母数组['c'、'a'、't']和一个重复计数数组[3,2,2]。这会使递归更容易。