所以我在这里遇到这个问题,我需要使用2d char数组的所有可能组合来查找某个值。
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++)
{
}
}
}
因子基本上是读入函数的整数r的阶乘。是否有更简单的方法为2d字符数组创建排列?
答案 0 :(得分:1)
使用常规排列代码。你可以在SO上找到数以万计的例子,尽管大多数都是在字符串上写字。
在您的设置中,字符串在堆上分配,并由指向它们的指针表示。这很好,因为现在你可以通过交换指针来交换字符串:
#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;
}
为了简洁起见,我在此处使用了字符串文字,但如果您在示例中使用strdup
或malloc
和strcpy
,则代码也能正常运行。
如果您使用具有固定字符串大小的真实二维数组,如char a[10][20]
,则必须复制字符串的内容,这是昂贵的。在这种情况下,最好创建一个存储指向这些字符串的指针的第二个数组,并按上述步骤继续。
( Ceterum censeo :我仍然不相信您需要创建所有排列。)
编辑:如果您想找到所有相邻字符串之间的公共字母最少的排列,请不要首先交换字符串。代替:
w[i][j]
哈希字符串i
和j
之间的常用字母数。{0, 1, 2, ..., n}
开始对整数ixed数组进行排列。所以:
#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;
}
这个解决方案仍然基本上尝试了所有的排列,可能不是最优的。如果您将权重矩阵视为图形中的距离矩阵,您可以尝试使用任何已知的图形查找算法来解决问题。这看起来像是一个引人注目的推销员问题,其中的路径并没有完全循环。