C中多个数组的笛卡尔积

时间:2012-05-04 15:11:19

标签: c arrays cartesian-product

我能够在C中实现静态数组数的笛卡尔积。但是我想构建一个动态的代码来获取输入数组的数量。有人可以解释如何“仅使用数组”这样做。如果这是不可能的阵列请建议我其他解决方案。谢谢。这是我的代码下面的3阵列的笛卡尔积。

#include<stdio.h>

int main(void)
{
        int array1[100];
        int array2[100];
        int array3[100];
        int cartesian_array[100][100];
        int m,n,o;
        int i,j;
        int p=0,q=0,r=0;
        int x,y,z;
        int cartesian_arr_row_len;
        int cartesian_arr_col_len;


        printf("Enter the size of first array:\n");
        scanf("%d",&m);

        printf("Enter the size of second array:\n");
        scanf("%d",&n);

        printf("Enter the size of third array:\n");
        scanf("%d",&o);

        printf("Enter the first array elements:\n");
        for(i=0;i<m;i++)
        scanf("%d",&array1[i]);

        printf("Enter the second array elements:");
        for(i=0;i<n;i++)
        scanf("%d",&array2[i]);

        printf("Enter the third array elements:");
        for(i=0;i<o;i++)
        scanf("%d",&array3[i]);

        cartesian_arr_row_len=m*n*o;
        cartesian_arr_col_len=3;

        x=cartesian_arr_row_len/m;
        y=cartesian_arr_row_len/(m*n);
        z=o;

        for(i=0;i<cartesian_arr_row_len;i++)
        {
                for(j=0;j<cartesian_arr_col_len;j++)
                {
                        if(j==0)
                        {
                                cartesian_array[i][j]=array1[p/x];
       p++;
                        }

                        if(j==1)
                        {
                                cartesian_array[i][j]=array2[q/y];
                                q++;
                                if(q>=n*y)
                                q=0;
                        }

                        if(j==2)
                        {
                                cartesian_array[i][j]=array3[r%z];
                                r++;
                        }
                }

        }

        printf("The Cartesian Product of two arrays is:\n");
        for(i=0;i<cartesian_arr_row_len;i++)
        {
                for(j=0;j<cartesian_arr_col_len;j++)
                {
                        printf("%d\t",cartesian_array[i][j]);
                }
                printf("\n");
        }

        return 0;
}

1 个答案:

答案 0 :(得分:2)

您能阅读Java代码并自行翻译吗?

import java.util.*;    

class CartesianIterator <T> implements Iterator <List <T>> {

        private final List <List <T>> lilio;    
        private int current = 0;
        private final long last;

        public CartesianIterator (final List <List <T>> llo) {
                lilio = llo;
                long product = 1L;
                for (List <T> lio: lilio)
                        product *= lio.size ();
                last = product;
        } 

        public boolean hasNext () {
                return current != last;
        }

        public List <T> next () {
                ++current;
                return get (current - 1, lilio);
        }

        public void remove () {
                ++current;
        }

        private List<T> get (final int n, final List <List <T>> lili) {
                switch (lili.size ())
                {
                        case 0: return new ArrayList <T> (); // no break past return;
                        default: {
                                List <T> inner = lili.get (0);
                                List <T> lo = new ArrayList <T> ();
                                lo.add (inner.get (n % inner.size ()));
                                lo.addAll (get (n / inner.size (), lili.subList (1, lili.size ())));
                                return lo;
                        }
                }
        }
}

class CartesianIterable <T> implements Iterable <List <T>> {

        private List <List <T>> lilio;  

        public CartesianIterable (List <List <T>> llo) {
                lilio = llo;
        }

        public Iterator <List <T>> iterator () {
                return new CartesianIterator <T> (lilio);
        }
}

class CartesianIteratorTest {

        public static void main (String[] args) {
                List <Character> la = Arrays.asList (new Character [] {'a', 'b'});
                List <Character> lb = Arrays.asList (new Character [] {'b', 'c'});      
                List <Character> lc = Arrays.asList (new Character [] {'c', 'a'});
                List <List <Character>> llc = new ArrayList <List <Character>> ();
                llc.add (la);
                llc.add (lb);
                llc.add (lc);

                CartesianIterable <Character> ci = new CartesianIterable <Character> (llc);
                for (List<Character> lo: ci)
                        show (lo);

                la = Arrays.asList (new Character [] {'x', 'y', 'z'});
                lb = Arrays.asList (new Character [] {'b'});    
                lc = Arrays.asList (new Character [] {'c'});
                llc = new ArrayList <List <Character>> ();
                llc.add (la);
                llc.add (lb);
                llc.add (lc);

                ci = new CartesianIterable <Character> (llc);
                for (List<Character> lo: ci)
                        show (lo);
        }

        public static void show (List <Character> lo) {
                System.out.print ("(");
                for (Object o: lo)
                        System.out.print (o);
                System.out.println (")");
        }
}

我不知道C中是否存在与迭代器类似的东西。iterable很可能对你无益。

代码的想法是,有一个计数器,它在结果集的所有元素上创建一个索引,并计算绑定到该值的元素。

如果我们有3组(1,2,3)(4,5)(6,7,8),我们预计会有18 = 3x2x3的结果。例如,对于迭代器位置7,我们可以如下计算结果:

7 % 3 = 1 => (1,2,3)[1] = 2 (number modulo 1st group size) 
7 / 3 = 2 (int division)  (number div 1st group size)
2 % 2 = 0 => (4,5)[0] = 4 (rest modulo 2nd group size) 
2 / 2 = 0 
0 % 3 = 0 => (7,8,9) => 7 

idx g1  g2  g3
 0  1   4   6   
 1  2   4   6   
 2  3   4   6   
 3  1   5   6   
 4  2   5   6   
 5  3   5   6   
 6  1   4   7   
 7  2   4   7   
 8  3   4   7   
 9  1   5   7   
10  2   5   7   
11  3   5   7   
12  1   4   8   
13  2   4   8   
14  3   4   8   
15  1   5   8   
16  2   5   8   
17  3   5   8