arrays - Creating the cartesian product of two lists into a new list in C -


i want create array cartesian product of 2 arrays. example:

const char *first[] = {"1", "2","3"}; const char *second[] = { "a" , "b" , "c", "e"}; 

the result array:

cartesian = {"(1,a)","(1,b)","(1,c)",....}; 

this have now:

int main(int argc, const char * argv[]) {      const char *first[] = {"1", "2","3"};     const char *second[] = { "a" , "b" , "c", "e"};      int size = sizeof(first) * sizeof(second);      char *both[size];     int i=0;      (int f=0; f<sizeof(first); f++) {          (int s=0; s<sizeof(second); s++) {           char *temp[size];            strcpy(temp[s], "("+first[f]+ ","second[s]+")");            both[i] = temp;            i++;        }    }    return 0; } 

problems in code:

  1. sizeof(first)(and sizeof(second)) gives number of string literals in array * sizeof(char*). need discard second part. divide sizeof(char*) or sizeof(*str) @bluepixy suggested same sizeof(str[0]):

    int size = (sizeof(first) / sizeof(*first)) * (sizeof(second) / sizeof(*second)); 
  2. your loops:

    for (int f=0; f<sizeof(first); f++) (int s=0; s<sizeof(second); s++) 

    suffer same problem. suggest using

    int size1 = sizeof(first) / sizeof(*first); int size2 = sizeof(second) / sizeof(*second)  (int f=0; f < size1; f++) (int s=0; s < size2; s++) 
  3. your body of loop has many problems. remove it. following steps show there.

steps resolve problems:

  1. you need allocate memory char *both[size];. allocate memory body of loop:

    int i=0;  (int f=0; f < size1; f++) {     (int s=0; s < size2; s++)     {         both[i] = malloc(strlen(first[f]) + strlen(second[s]) + 4);         /*mallocing space 2 brackets, comma, nul-terminator , coordinates*/         i++; //increment counter     } } 
  2. strcpy wrong function use here. use sprintf instead:

    int i=0;  (int f=0; f < size1; f++) {     (int s=0; s < size2; s++)     {         both[i] = malloc(strlen(first[f]) + strlen(second[s]) + 4);          sprintf(both[i], "(%s,%s)",first[f],second[s]); // make string         i++;     } } 
  3. after loop, both populated according needs. print them using:

    for(int j=0; j<i ; j++)     printf("%s \n",both[j]); 
  4. after use, free allocated memory using:

    for(int j=0; j<i ; j++)     free(both[j]); 

fixed program:

#include <stdio.h> #include <stdlib.h> //for malloc , free #include <string.h> //for strlen  int main(int argc, const char * argv[]) {      const char *first[] = {"1", "2","3"};     const char *second[] = { "a" , "b" , "c", "e"};      int size = (sizeof(first) / sizeof(*first)) * (sizeof(second) / sizeof(*second));      char *both[size];     int i=0;      int size1 = sizeof(first) / sizeof(*first);     int size2 = sizeof(second) / sizeof(*second)      (int f=0; f < size1; f++)     {         (int s=0; s < size2; s++)         {             both[i] = malloc(strlen(first[f]) + strlen(second[s]) + 4);             sprintf(both[i], "(%s,%s)",first[f],second[s]);             i++;         }     }      for(int j=0; j<i ; j++)         printf("%s\n",both[j]);      for(int j=0; j<i ; j++)         free(both[j]);      return 0; //or return(exit_success); } 

other notes:

  • check result of malloc see if successful in allocating memory. malloc returns null on failure.
  • checking result of sprintf good, although not neccessary. sprintf returns negative number on failure.

Comments