代码之家  ›  专栏  ›  技术社区  ›  PowerApp101

从有序字符序列递归生成有序子字符串?

  •  3
  • PowerApp101  · 技术社区  · 17 年前

    得到答案后编辑


    假设我有一个由字符s[0]:s[N]组成的字符串s,其中每个字符s[I]<=s[i+1]

    aaacdddghzz
    

    例如,我会

    a
    aa
    aaa
    ad
    aad
    aaad
    add
    aadd
    aaadd
    addd
    aaddd
    aaaddd
    d
    dd
    ddd
    .
    .
    .
    ac
    aac
    .
    .
    .
    acdddghzz
    aacdddghzz
    aaacdddghzz
    

    但不是

    ca
    hdz
    ...etc
    

    现在我知道如何计算出有多少个组合。创建字符串中字母频率的直方图。所以在上面的例子中

    a=3
    d=3
    c=1
    g=1
    h=1
    z=2
    

    公式是 (a+1)(c+1)(d+1)(g+1)(h+1)(z+1) = 4*4*2*2*2*3 = 384 . 有384个子字符串保持s[i]<=s[i+1]关系。

    5 回复  |  直到 17 年前
        1
  •  5
  •   Salman A    17 年前

    以上是Ryan Shaw的回答:

    根据每个字母的数量,以基数计算每个数字,而不是以二进制进行计数。例如:

    a d c g h z
    3 3 1 1 1 2
    

    因此,我认为:

    0 0 0 0 0 0
    0 0 0 0 0 1
    0 0 0 0 0 2
    0 0 0 0 1 0
    0 0 0 0 1 1 
    0 0 0 0 1 2
    0 0 0 1 0 0
    ...
    0 0 0 1 1 2
    0 0 1 0 0 0
    ...
    0 0 1 1 1 2
    0 1 0 0 0 0 
    ...
    0 3 1 1 1 2
    1 0 0 0 0 0
    ...
    3 3 1 1 1 2
    

    1 2 0 0 1 1 => addhz
    3 0 0 0 1 2 => aaahzz
    

    以及守则:

    void GetCounts(const string &source, vector<char> &characters, vector<int> &counts)
    {
        characters.clear();
        counts.clear();
    
        char currentChar = 0;
        for (string::const_iterator iSource = source.begin(); iSource != source.end(); ++iSource)
        {
            if (*iSource == currentChar)
                counts.back()++;
            else
            {
                characters.push_back(*iSource);
                counts.push_back(1);
                currentChar = *iSource;
            }
        }
    }
    
    bool Advance(vector<int> &current, const vector<int> &max)
    {
        if (current.size() == 0)
            return false;
    
        current[0]++;
        for (size_t index = 0; index < current.size() - 1 && current[index] > max[index]; ++index)
        {
            current[index] = 0;
            current[index + 1]++;
        }
        if (current.back() > max.back())
            return false;
        return true;
    }
    
    string ToString(const vector<int> &current, const vector<char> &characters)
    {
        string result;
        for (size_t index = 0; index < characters.size(); ++index)
            for (int i = 0; i < current[index]; ++i)
                result += characters[index];
        return result;
    }
    
    int main() { 
        vector<int> max;
        vector<char> characters;
    
        GetCounts("aaadddcghzz", characters, max);
    
        vector<int> current(characters.size(), 0);
        int index = 1;
        while (Advance(current, max))
        {
            cout << index++ << ":" << ToString(current, characters) << endl;
        }
    }
    
        2
  •  2
  •   Dave    17 年前

    下面是生成所有子序列的递归算法。

    /* in C -- I hope it will be intelligible */
    
    #include <stdio.h>
    
    static char input[] = "aaabbbccc";
    static char output[sizeof input];
    
    /* i is the current index in the input string
     * j is the current index in the output string
     */
    static void printsubs(int i, int j) {
        /* print the current output string */
        output[j] = '\0';
        printf("%s\n", output);
        /* extend the output by each character from each remaining group and call ourselves recursively */
        while(input[i] != '\0') {
            output[j] = input[i];
            printsubs(i + 1, j + 1);
            /* find the next group of characters */
            do ++i;
            while(input[i] == input[i - 1]);
        }
    }
    
    int main(void) {
        printsubs(0, 0);
        return 0;
    }
    

    如果您的兴趣仅仅是计算有多少子序列,那么您可以更有效地进行计算。只需计算每个字母的数量,每个值加1,然后将它们相乘。在上述示例中,对于(3+1)*(3+1)*(3+1)*(3+1)*(2+1)=192个子序列,有3个a、3个b、3个c和2个d。这样做的原因是,您可以在0和3A、0和3B、0和3C、0和2D之间进行选择,以及 所有这些选择都是独立的

        3
  •  1
  •   yinyueyouge    17 年前

    考虑到集合{a,a,a,d,d,d,c,g,h,z,z},您的目标是按顺序列出其所有唯一子集,除了空集: {a} {a,a,a} {a,a,a,d}

    {}     = 000
    {C}    = 001
    {B}    = 010
    {BC}   = 011
    {A}    = 100
    {AC}   = 101
    {AB}   = 110
    {ABC}  = 111
    

    看到模式了吗?只需使用一个从0增长到2^n-1的整数。如果整数的第i位是1,则从集合中提取第i个元素。

    注意:因为在您的示例中,字符串中有重复项;因此,生成后,可能需要删除重复项。

        4
  •  0
  •   cjs    17 年前

    嗯,在我看来,有一种解决方案与您的类似,但与您的输出不匹配(请参见我对问题的评论),就是简单地遍历原始字符串的尾部列表(例如,对于“abc”,遍历“abc”、“bc”和“c”),并为每个字符串生成前缀列表(“abc”、“ab”、“a”,然后是“bc”、“b”,然后是“c”)。这和你想要的相比如何?

        5
  •  0
  •   Ray Tayek    17 年前

    我使用了这个java代码( http://www.merriampark.com/comb.htm )结果只有383个。代码生成了太多的副本,所以我不得不扔掉很多。我只得到了383分(见下文)。您可能想看看STL中的下一个组合的C++代码(但是我很难在任何地方找到源代码)。电源组可能是最好的方法(但也可能有重复的方法)。

    a
    aa
    aaa
    aaac
    aaacg
    aaacgh
    aaacghz
    aaacghzz
    aaacgz
    aaacgzz
    aaach
    aaachz
    aaachzz
    aaacz
    aaaczz
    aaad
    aaadc
    aaadcg
    aaadcgh
    aaadcghz
    aaadcghzz
    aaadcgz
    aaadcgzz
    aaadch
    aaadchz
    aaadchzz
    aaadcz
    aaadczz
    aaadd
    aaaddc
    aaaddcg
    aaaddcgh
    aaaddcghz
    aaaddcghzz
    aaaddcgz
    aaaddcgzz
    aaaddch
    aaaddchz
    aaaddchzz
    aaaddcz
    aaaddczz
    aaaddd
    aaadddc
    aaadddcg
    aaadddcgh
    aaadddcghz
    aaadddcghzz
    aaadddcgz
    aaadddcgzz
    aaadddch
    aaadddchz
    aaadddchzz
    aaadddcz
    aaadddczz
    aaadddg
    aaadddgh
    aaadddghz
    aaadddghzz
    aaadddgz
    aaadddgzz
    aaadddh
    aaadddhz
    aaadddhzz
    aaadddz
    aaadddzz
    aaaddg
    aaaddgh
    aaaddghz
    aaaddghzz
    aaaddgz
    aaaddgzz
    aaaddh
    aaaddhz
    aaaddhzz
    aaaddz
    aaaddzz
    aaadg
    aaadgh
    aaadghz
    aaadghzz
    aaadgz
    aaadgzz
    aaadh
    aaadhz
    aaadhzz
    aaadz
    aaadzz
    aaag
    aaagh
    aaaghz
    aaaghzz
    aaagz
    aaagzz
    aaah
    aaahz
    aaahzz
    aaaz
    aaazz
    aac
    aacg
    aacgh
    aacghz
    aacghzz
    aacgz
    aacgzz
    aach
    aachz
    aachzz
    aacz
    aaczz
    aad
    aadc
    aadcg
    aadcgh
    aadcghz
    aadcghzz
    aadcgz
    aadcgzz
    aadch
    aadchz
    aadchzz
    aadcz
    aadczz
    aadd
    aaddc
    aaddcg
    aaddcgh
    aaddcghz
    aaddcghzz
    aaddcgz
    aaddcgzz
    aaddch
    aaddchz
    aaddchzz
    aaddcz
    aaddczz
    aaddd
    aadddc
    aadddcg
    aadddcgh
    aadddcghz
    aadddcghzz
    aadddcgz
    aadddcgzz
    aadddch
    aadddchz
    aadddchzz
    aadddcz
    aadddczz
    aadddg
    aadddgh
    aadddghz
    aadddghzz
    aadddgz
    aadddgzz
    aadddh
    aadddhz
    aadddhzz
    aadddz
    aadddzz
    aaddg
    aaddgh
    aaddghz
    aaddghzz
    aaddgz
    aaddgzz
    aaddh
    aaddhz
    aaddhzz
    aaddz
    aaddzz
    aadg
    aadgh
    aadghz
    aadghzz
    aadgz
    aadgzz
    aadh
    aadhz
    aadhzz
    aadz
    aadzz
    aag
    aagh
    aaghz
    aaghzz
    aagz
    aagzz
    aah
    aahz
    aahzz
    aaz
    aazz
    ac
    acg
    acgh
    acghz
    acghzz
    acgz
    acgzz
    ach
    achz
    achzz
    acz
    aczz
    ad
    adc
    adcg
    adcgh
    adcghz
    adcghzz
    adcgz
    adcgzz
    adch
    adchz
    adchzz
    adcz
    adczz
    add
    addc
    addcg
    addcgh
    addcghz
    addcghzz
    addcgz
    addcgzz
    addch
    addchz
    addchzz
    addcz
    addczz
    addd
    adddc
    adddcg
    adddcgh
    adddcghz
    adddcghzz
    adddcgz
    adddcgzz
    adddch
    adddchz
    adddchzz
    adddcz
    adddczz
    adddg
    adddgh
    adddghz
    adddghzz
    adddgz
    adddgzz
    adddh
    adddhz
    adddhzz
    adddz
    adddzz
    addg
    addgh
    addghz
    addghzz
    addgz
    addgzz
    addh
    addhz
    addhzz
    addz
    addzz
    adg
    adgh
    adghz
    adghzz
    adgz
    adgzz
    adh
    adhz
    adhzz
    adz
    adzz
    ag
    agh
    aghz
    aghzz
    agz
    agzz
    ah
    ahz
    ahzz
    az
    azz
    c
    cg
    cgh
    cghz
    cghzz
    cgz
    cgzz
    ch
    chz
    chzz
    cz
    czz
    d
    dc
    dcg
    dcgh
    dcghz
    dcghzz
    dcgz
    dcgzz
    dch
    dchz
    dchzz
    dcz
    dczz
    dd
    ddc
    ddcg
    ddcgh
    ddcghz
    ddcghzz
    ddcgz
    ddcgzz
    ddch
    ddchz
    ddchzz
    ddcz
    ddczz
    ddd
    dddc
    dddcg
    dddcgh
    dddcghz
    dddcghzz
    dddcgz
    dddcgzz
    dddch
    dddchz
    dddchzz
    dddcz
    dddczz
    dddg
    dddgh
    dddghz
    dddghzz
    dddgz
    dddgzz
    dddh
    dddhz
    dddhzz
    dddz
    dddzz
    ddg
    ddgh
    ddghz
    ddghzz
    ddgz
    ddgzz
    ddh
    ddhz
    ddhzz
    ddz
    ddzz
    dg
    dgh
    dghz
    dghzz
    dgz
    dgzz
    dh
    dhz
    dhzz
    dz
    dzz
    g
    gh
    ghz
    ghzz
    gz
    gzz
    h
    hz
    hzz
    z
    zz
    
    推荐文章