Finding all possible words from inputted character arrays (permutations)

天大地大妈咪最大 提交于 2019-12-23 05:11:51

问题


After reading through several posts I am still stumped with permutations and recursive functions. I am trying to create all possible 3 letter permutations of characters in an unequal length 2D array where the first letter is from the set {‘l’, ‘m’, ‘n’}, the second letter is from the set {‘q’, ‘r’} and the third letter is from the set {‘a’, ‘e’, ‘i’, ‘o’}. My code goes through the correct permutation pattern but does not print out the correct output. For example, if the first 8 permutations are supposed to be:

lqa
lqe
lqi
lqo
lra
lre
lri
lro

my code prints out:

lqa
e
i
o
ra
e
i
o

Any ideas on what the problem is? Here are the relevant pieces of my code:

rec(character_pools,0,3);
void rec(char** pool, int k, int j)
{
    if(k==j)
    {
        printf("\n");
        return;
    }
    int i,len=strlen(pool[k]);
    for (i=0;i<len;i++)
    {
        printf("%c",pool[k][i]);
        rec(pool,k+1,j);
    }
}

回答1:


This ended up working for me! Thx @Tsukuyo for the hint. Do I need to ask a separate question if I wanted to find the nth index of a string in the permutation?

void rec(char** pool, int k, int j, char* cur, int counter)
{
    if(k==j)
    {
        cur[k]=0;
        printf("Recursive call #%d %s\n",counter,cur);
        return;
    }
    int i,len=strlen(pool[k]);


    for (i=0;i<len;i++)
    {
        cur[k]=pool[k][i];
        rec(pool,k+1,j,cur,counter++);
    }
}



回答2:


The calling stack:

   rec(pool, 0, 3);
-> 'l'   rec(pool, 1, 3);
      -> 'q'   rec(pool, 2, 3);
            -> 'a'   rec(pool, 3, 3);
                  -> '\n'
            -> 'e'   rec(pool, 3, 3);
                  -> '\n'
            -> 'i'   rec(pool, 3, 3);
                  -> '\n'
            -> ...
      -> ...
-> ...

Update:
Not so recursion-like. But..it works:). Hope this helps.
Assume that the maximum length is 10.

#include <stdio.h>
#include <string.h>
#define ALL_DONE 1
#define NOT_YET  0

int rec(char (*pool)[10], int num, int start);

int main(void)
{
    int i, num;
    char pool[20][10];

    scanf("%d", &num);
    for (i = 0; i < num; i++){
        scanf("%s", pool[i]);
    }
    while ( !rec(pool, num, 0) );  // keepint calling until all permutations are printed
    return 0;
}

int rec(char (*pool)[10], int num, int start)
{
    static int ndx[20] = {0};  // record the index of each string

    if (start == num){
        printf("\n");
        return ALL_DONE;
    }
    printf("%c", pool[start][ndx[start]]);
    if ( rec(pool, num, start+1) == ALL_DONE ){
        ndx[start+1] = 0;
        ndx[start]++;
        if (ndx[start] == strlen(pool[start])){
            return ALL_DONE;
        return NOT_YET;
    }
    return NOT_YET;
}

explanation:

   rec(pool, 0, 0)[1st calling]     
-> 'l'   rec(pool, 1, 0)                    | ndx[0..2] = 0, 0, 0
      -> 'q'   rec(pool, 2, 0)              | ndx[0..2] = 0, 0, 0
            -> 'a'   rec(pool, 3, 0)        | ndx[0..2] = 0, 0, 0
                  -> '\n' retrun ALL_DONE   | ndx[0..2] = 0, 0, 0
            -> return NOT_YET               | ndx[0..2] = 0, 0, 1
      -> return NOT_YET                     | ndx[0..2] = 0, 0, 1
-> return NOT_YET                           | ndx[0..2] = 0, 0, 1
|
   rec(pool, 0, 0)[2nd]
-> 'l'   rec(pool, 1, 0)                    | ndx[0..2] = 0, 0, 1
      -> 'q'   rec(pool, 2, 0)              | ndx[0..2] = 0, 0, 1
            -> 'e'   rec(pool, 3, 0)        | ndx[0..2] = 0, 0, 1
                  -> '\n' return ALL_DONE   | ndx[0..2] = 0, 0, 1
            -> return NOT_YET               | ndx[0..2] = 0, 0, 2
      -> return NOT_YET                     | ndx[0..2] = 0, 0, 2
-> return NOT_YET                           | ndx[0..2] = 0, 0, 2
|
|  ...
|
   rec(pool, 0, 0)[4th]
-> 'l'   rec(pool, 1, 0)                    | ndx[0..2] = 0, 0, 3
      -> 'q'   rec(pool, 2, 0)              | ndx[0..2] = 0, 0, 3
            -> 'o'   rec(pool, 3, 0)        | ndx[0..2] = 0, 0, 3
                  -> '\n' return ALL_DONE   | ndx[0..2] = 0, 0, 3
            -> return ALL_DONE              | ndx[0..2] = 0, 0, 4
      -> return NOT_YET                     | ndx[0..2] = 0, 1, 0
-> return NOT_YET                           | ndx[0..2] = 0, 1, 0
|
| ...
| ...
|
   rec(pool, 0, 0)[5th]
-> 'l'   rec(pool, 1, 0)                    | ndx[0..2] = 0, 1, 0
      -> 'r'   rec(pool, 2, 0)              | ndx[0..2] = 0, 1, 0
            -> 'a'   rec(pool, 3, 0)        | ndx[0..2] = 0, 1, 0
                  -> '\n' return ALL_DONE   | ndx[0..2] = 0, 1, 0
            -> return NOT_YET               | ndx[0..2] = 0, 1, 1
      -> return NOT_YET                     | ndx[0..2] = 0, 1, 1
-> return NOT_YET                           | ndx[0..2] = 0, 1, 1
|
| ...
|
   rec(pool, 0, 0)[8th]
-> 'l'   rec(pool, 1, 0)                    | ndx[0..2] = 0, 1, 3
      -> 'r'   rec(pool, 2, 0)              | ndx[0..2] = 0, 1, 3
            -> 'o'   rec(pool, 3, 0)        | ndx[0..2] = 0, 1, 3
                  -> '\n' return ALL_DONE   | ndx[0..2] = 0, 1, 3
            -> return ALL_DONE              | ndx[0..2] = 0, 1, 4
      -> return ALL_DONE                    | ndx[0..2] = 0, 2, 0
-> return ALL_DONE                          | ndx[0..2] = 1, 0, 0
|
| FINISH



回答3:


You create a char array which will contain the string you want to work with char str[] = "ABC";

then you get the length of the string int n = strlen(str); and lastly you permutate.

You make a new function which will contain the input string, starting index of the string and ending index of the string. Check if the starting index (int s) equals the ending index (int e) if it does, that means you're done, if not you go into a loop where you go from start (s) to end (e), swap the values, recurse, swap again to backtrack.

An example in C++:

#include <stdio.h>
#include <string.h>

void swap(char *i, char *j)
{
    char temp;
    temp = *i;
    *i = *j;
    *j = temp;
}

void permutate(char *str, int start, int end)
{
    int i;
    if (start == end)
        printf("%s\n", str);
    else
    {
        for (i = start; i <= end; i++)
        {
            swap((str + start), (str + i));
            permutate(str, start + 1, end);
            swap((str + start), (str + i)); //backtrack
        }
    }
}

int main()
{
    char str[] = "ABC";
    int n = strlen(str);
    permutate(str, 0, n - 1);
    return 0;
}


来源:https://stackoverflow.com/questions/18928778/finding-all-possible-words-from-inputted-character-arrays-permutations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!