C 如何排列2d字符数组

C 如何排列2d字符数组,c,C,所以我这里有一个问题,我需要使用2d字符数组的所有可能组合来找到一个特定的值 void permutate(int i, int r, int m, int factor, int count, char** danceRoutines); int main(void) { int routines, i, j, loop, factor, min, count = 0; printf("Please enter the number of routines (min 2,

所以我这里有一个问题,我需要使用2d字符数组的所有可能组合来找到一个特定的值

void permutate(int i, int r, int m, int factor, int count, char** danceRoutines);

int main(void)
{
    int routines, i, j, loop, factor, min, count = 0;

    printf("Please enter the number of routines (min 2, max 10): \n");
    scanf("%d", &routines);
    factor = factorial(routines);

    //Check for routine < 2 and routine > 10
    if(routines < 2 || routines > 10)
    {
        printf("Please, between 2 and 10 \n");
        return;
    }

    //Store the dancers they enter into a 2d array of size routines *  MAX
    char **danceRoutines = (char**)malloc(sizeof(char*) * routines);
    for(i = 0; i < routines; i++)
    {
        char *s = (char*)malloc(sizeof(char));
        scanf("%s", s);
        danceRoutines[i] = s;
    }

    min = quickChanges(danceRoutines, routines, 0);
    printf("This is min: %d", min);
    permutate(0, routines, min, factor, count, danceRoutines);

    for(loop = 0; loop < routines; loop++)
    {
        free(danceRoutines[loop]);
    }

    free(danceRoutines);
    return 0;
}

void permutate(int i, int r, int m, int factor, int count, char** danceRoutines)
{
    int k, l, test, last;
    if(last == 0)
    {
        printf("%d", m);
    }

    for(k = 0; k < r; k++)
    {
        int length = strlen(danceRoutines[k]);
        char *line = (char*)malloc(sizeof(char) * length);
        strcpy(line, danceRoutines[k]);
        strcpy()
        for(l = 1; l < factor / r; l++)
        {

        }
    }
}
void置换(int i,int r,int m,int factor,int count,char**s);
内部主(空)
{
int例程,i,j,循环,因子,min,计数=0;
printf(“请输入例程的数量(最少2个,最多10个):\n”);
scanf(“%d”,和例程);
因子=因子(常规);
//检查例行程序<2和例行程序>10
如果(例行程序<2 | |例行程序>10)
{
printf(“请介于2和10之间”);
返回;
}
//将他们输入的舞者存储到一个2d大小数组中*MAX
char**danceRoutines=(char**)malloc(sizeof(char*)*例程);
对于(i=0;i<例程;i++)
{
char*s=(char*)malloc(sizeof(char));
scanf(“%s”,s);
舞者远足[i]=s;
}
最小值=快速更改(舞者路线、例程,0);
printf(“这是最小值:%d”,最小值);
置换(0,例程,最小值,因子,计数,舞者行程);
for(循环=0;循环<例程;循环++)
{
自由(舞者之旅[循环]);
}
免费(跳舞);
返回0;
}
无效置换(整数i、整数r、整数m、整数因子、整数计数、字符)
{
int k,l,test,last;
如果(最后==0)
{
printf(“%d”,m);
}
对于(k=0;k

Factor基本上是读入函数的整数r的阶乘。有没有更简单的方法为2d字符数组创建置换?

使用常规置换代码。你可能会在这里找到无数这样的例子,尽管大多数都是排列字符串的字母

在您的设置中,字符串在堆上分配,并由指向它们的指针表示。这很好,因为现在您可以通过交换指针来交换字符串:

#include <stdlib.h>
#include <stdio.h>



void permute(const char **str, size_t n, size_t i)
{
    size_t j;

    if (i == n) {        
        // permutation found: print the strings (or do other stuff)
        for (j = 0; j < n; j++) {
            if (j) printf(" ");
            printf("%s", str[j]);
        }
        puts("");
    } else {
        // recurse deeper with each of the remaining strings as next string

        for (j = i; j < n; j++) {
            const char *swap;

            swap = str[i]; str[i] = str[j]; str[j] = swap;
            permute(str, n, i + 1);
            swap = str[i]; str[i] = str[j]; str[j] = swap;
        }
    }
}

int main(void)
{
    const char *str[] = {
        "red", "green", "blue", "white"
    };

    permute(str, 4, 0);

    return 0;
}

这个解决方案基本上仍然尝试所有置换,可能不是最优的。如果在图中考虑权重矩阵为距离矩阵,则可以尝试用任何已知的图的PAH查找算法来解决该问题。这看起来像是ravelling-saller问题,路径不是完整的循环。

您只为临时字符串
s
分配了一个字符,而没有释放它。另外,
strcpy()
?“我需要使用所有可能的组合…以便找到某个值。”您想要实现什么?为了寻找某个值而生成所有置换看起来像是过度杀戮。也许有更好的解决方案。对不起,排列函数不完整,因为我不知道该怎么做。我在网上找到了关于排列1D数组的东西,但不是2D字符数组。我基本上是想切换线条,所以我有不同的2D字符数组变体,比如:ABC-DEF-ABCDE和ABC-ABCDE-DEF,然后我需要计算一个最小值,但我已经记下来了。我只需要知道如何正确地切换线条,这样它就可以评估2d阵列的所有可能组合。如果你的问题“有更简单的方法吗?”真的意味着“有方法吗?”再一次,你想实现什么?您是否需要创建所有排列并存储它们?是否可以一次创建一个排列并进行检查,以便只需要一个数组?您需要查找所有排列吗?很抱歉造成混淆。我会尽力弄清楚我需要完成什么。假设我有一个字符串的2D字符数组。每行都是一行,索引范围从0一直到用户输入的行数。比如说:0123我想做的是让每一个可能的组合都保持第一行的完整性:0123,0132,0213,0231,0312,0321然后,我想切换第一行和第二行,并再次找到所有可能的组合,第一行保持完整性:1023,1032,1230,1203,1302,1320等等。每次阵列被破坏的时候谢谢你!如果代码对我不起作用,我会给你回电话的。我无法找到计算特定最小值的算法,因此我假设只有通过检查所有可能的方式重新排列2D数组,然后通过每个变量计算最小值,才有可能,但从未达到基本情况。我应该粘贴我程序的全部代码吗?这可能会有所帮助。我想如果我知道如何做排列就足够了。你是什么意思,它从来没有达到基本情况?上面的代码生成n!独特的组合。在我看来,你应该退后一步,决定你真正想要什么。事实上,这已经达到了基本情况。它没有打印出我所需要的,而是打印出最小值,它打印出函数计算的每个值。我不知道你一直在说的“最小值”是什么。你当然可以做其他事情,比如找到最小值,而不是打印出解决方案。但这是你应该做的事情;这超出了你问题的范围。(如果你认为这不是一个新问题,你可以问一个新问题。)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>

#define MAX 10

int weight[MAX][MAX];
int best[MAX];
int min;


void permute(int *perm, size_t n, size_t i, int sum)
{
    size_t j;

    if (sum >= min) return;

    if (i == n) {
        if (sum < min) {
            min = sum;
            memcpy(best, perm, n * sizeof(*perm));
        }
    } else {
        for (j = i; j < n; j++) {
            int swap;
            int w = 0;

            if (i) w = weight[perm[i - 1]][perm[j]];

            swap = perm[i]; perm[i] = perm[j]; perm[j] = swap;
            permute(perm, n, i + 1, sum + w);
            swap = perm[i]; perm[i] = perm[j]; perm[j] = swap;
        }
    }
}

int common(const char *s, const char *t)
{
    int res = 0;

    while (*s && *t) {
        if (*s == *t) {
            res++; s++; t++;
        } else {
            if (*s < *t) s++; else t++;
        }
    }

    return res;
}

void best_perm(const char **str, size_t n)
{
    int perm[n];
    size_t i, j;

    for (i = 0; i < n; i++) perm[i] = i;

    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            weight[i][j] = weight[j][i] = common(str[i], str[j]);
        }
    }

    min = INT_MAX;

    permute(perm, n, 0, 0);

    for (i = 0; i < n; i++) {
        if (i) printf(" %d ", weight[best[i - 1]][best[i]]);
        printf("%s", str[best[i]]);
    }
    printf("\nOverall penalty: %d\n", min);    
}

int main(void)
{
    const char *str[] = {
        "acdeg", "acgh", "dg", "aeh", "cegh", 
        "abcfgh", "abc", "abc", "fgh", "abcdefgh"
    };

    best_perm(str, 10);

    return 0;
}