【问题标题】:Python's itertools.product in CC 语言中的 Python itertools.product
【发布时间】:2016-01-23 13:33:21
【问题描述】:

Python中有一个函数是这样运行的:

itertools.product("abc", repeat = 2)

返回以下内容:

("a", "a")
("a", "b")
("a", "c")
("b", "a")
("b", "b")
("b", "c")
("c", "a")
("c", "b")
("c", "c")

更改重复变量将更改元组中返回的项目数。 如何用 C 编写返回一个字符数组数组? (字符串数组)

更新:我现在有了我写的这个函数:

void cartesian(char *a, int al, char *b, int bl){
    int i, j;
    char c[al * bl][2];
    for(i = 0; i < al; i++){
        for(j = 0; j < bl; j++){
            c[(i * bl) + j][0] = *(a + i);
            c[(i * bl) + j][1] = *(b + j);
            printf("%c%c\n", *(a + i), *(b + j));
        }
    }
}

int main(){
    char a[] = "abc";
    char b[] = "ab";
    cartesian(a, strlen(a), b, strlen(b));
    return 0;
}

如何更改此函数,以便它可以接收一组 char 数组并生成笛卡尔积?数组可以包含任意数量的字符,并且可以有任意数量的数组

函数应该如下所示:

void cartesian(char *a, int l){
    /*Do cartesian*/
}

示例数组:

[
    ['a', 'b', 'c', '\0'],
    ['a', 'b', 'c', '\0'],
    ['a', 'b', 'c', '\0']
]

(包含空值以计算数组的长度) 应该产生

[
    ['a', 'a', 'a'],
    ['a', 'a', 'b'],
    ['a', 'a', 'c'],
    ['a', 'b', 'a'],
    ['a', 'b', 'b'],
    ['a', 'b', 'c'],
    ['a', 'c', 'a'],
    ['a', 'c', 'b'],
    ['a', 'c', 'c'],
    ['b', 'a', 'a'],
    ['b', 'a', 'b'],
    ['b', 'a', 'c'],
    ['b', 'b', 'a'],
    ['b', 'b', 'b'],
    ['b', 'b', 'c'],
    ['b', 'c', 'a'],
    ['b', 'c', 'b'],
    ['b', 'c', 'c'],
    ['c', 'a', 'a'],
    ['c', 'a', 'b'],
    ['c', 'a', 'c'],
    ['c', 'b', 'a'],
    ['c', 'b', 'b'],
    ['c', 'b', 'c'],
    ['c', 'c', 'a'],
    ['c', 'c', 'b'],
    ['c', 'c', 'c'],
]

【问题讨论】:

标签: python c cartesian-product


【解决方案1】:

这是根据您的规范的笛卡尔积的 C 实现。请注意,参数是char **a,而不是char *a,因为它是一个字符串数组。

这是previous answer.的变体

    void cartesian(char **a, unsigned int l)
    {
        unsigned int *indices = calloc(l, sizeof(int));
        unsigned int changed;
        do {
            unsigned int finished = 0;
            unsigned int i;
            changed = 0;
            /* Print the current tuple */
            for (i = 0; i < l; i++) {
                putchar(a[i][indices[i]]);
            }
            putchar('\n');
            /* Loop over the arrays in reverse order */
            for (i = l - 1; !changed && !finished; i--) {
                /* Increment */
                indices[i]++;
                if (a[i][indices[i]]) {
                    /* We moved to the next character */
                    changed = 1;
                }
                else {
                    /* End of string, so roll over */
                    indices[i] = 0;
                }
                finished = i == 0;
            }
        } while (changed);
        free(indices);
    }

【讨论】:

    【解决方案2】:

    以下 C 程序创建“abc”的所有可能排列。

    #include <stdio.h>
    #include <string.h>
    
    /* Function to swap values at two pointers */
    void swap(char *x, char *y)
    {
        char temp;
        temp = *x;
        *x = *y;
        *y = temp;
    }
    
    void permute(char *a, int l, int r)
    {
       int i;
       if (l == r)
         printf("%s\n", a);
       else
       {
           for (i = l; i <= r; i++)
           {
              swap((a+l), (a+i));
              permute(a, l+1, r);
              swap((a+l), (a+i)); //backtrack
           }
       }
    }
    
    int main()
    {
        char str[] = "abc";
        int n = strlen(str);
        permute(str, 0, n-1);
        return 0;
    }
    

    可能有一种更快的方法来编写此代码。运行时间 O(n*n!)。我后来才注意到您正在请求笛卡尔积。但是在类似的请求中可以找到几个堆栈溢出条目。 Generate the Cartesian Product of 2 vector<string>s In-Place?

    【讨论】:

    • OP 想要笛卡尔积,而不是排列。
    • 我不确定他实际上想要实现什么,因此我还是发布了代码。
    • 这也可以迭代完成,而不是递归完成?
    • 对于排列算法可能不是。但肯定是笛卡尔积。这就是为什么我还提供了指向同一问题的 C++ 代码的链接。如果你知道 C 应该很容易跟进。
    猜你喜欢
    • 2014-01-01
    • 2011-09-29
    • 2022-01-19
    • 1970-01-01
    • 2018-08-14
    • 2011-03-02
    • 1970-01-01
    • 2013-04-15
    • 2017-04-14
    相关资源
    最近更新 更多