在 C 中将所有排列列为列表

问题描述 投票:0回答:1

努力找出我的代码有什么问题。我想了解为什么我的直觉是错误的。我想生成一堆列表的原因是希望在开始时进行枚举。但我做错了什么?

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

int maxI(int n)
{
    int result = 1;
    for (int i = 1; i <= n; i++)
    {
        result *= i;
    }
    return result;
}

void swap(int *x, int *y)
{
    int temp;
    temp = *x;
    *x = *y;
    *y = temp;
}

int **pMut(int *arr, int size, int max)
{
    int **results = (int **)malloc(sizeof(int *) * max);

    // pointer index, outer loop with reset, inner loop with swaps
    int index, x, y;

    for (index = 0; index < max; index++)
    {
        results[index] = (int *)malloc(sizeof(int) * size);

        for (x = 0; x < size - 1; x++)
        {
            for (y = 1; y < size; y++)
            {
                swap(&arr[x], &arr[y]);

                for (int z = 0; z < size; z++)
                {
                    results[index][z] = arr[z];
                }
            }
        }
    }

    swap(&arr[x], &arr[y]);

    return results;
}

int main()
{
    int target[] = {1, 2, 3};
    int size = sizeof(target) / sizeof(target[0]);
    int max = maxI(size);
    int **result = pMut(target, size, max);

    for (int index = 0; index < max; index++)
    {
        for (int x = 0; x < size; x++)
        {
            printf("%d", result[index][x]);
        }
        printf("\n");
    }

    for (int i = 0; i < max; i++)
    {
        free(result[i]);
    }

    free(result);

    return 0;
}

结果显示:

321
123
321
123
321
123

我在我想要的地方玩过,但交换回来重置循环,但它要么是 123 6 次,要么是出界和其他重复。

c
1个回答
0
投票

在评估您的解决方案时,为了导出和打印整数的各种组合/排列,您似乎正在尝试应用我发现的“C”程序示例的功能“https://www.geeksforgeeks.org/write -a-c-program-to-print-all-permutations-of-a-given-string/" 提供字符串到整数数组的排列。 如果这只是巧合,您可能需要参考这个例子。

在检查您的代码时,您的程序似乎正在尝试派生一个二维整数数组来存储各种排列,而不是我认为被用作构建块的示例中发生的递归函数调用。

使用该示例,以下是代码的重构版本,以适应整数排列而不是字符排列。

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

// Function to swap two integers - based upon the swapping of characters
void swap(int* x, int* y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}

void permuteRec(int* str, int idx, int n) {

    // Base case
    if (idx == n - 1) {
        for (int i = 0; i < n; i++)
            printf("%d  ", str[i]);
        printf("\n");
        return;
    }

    for (int i = idx; i < n; i++) {

        // Swapping
        swap(&str[idx], &str[i]);

        // First idx+1 integers
        permuteRec(str, idx + 1, n);

        // Backtrack
        swap(&str[idx], &str[i]);
    }
}

int main() {
    int str[] = {1, 2, 3};
    int n = sizeof(str) / sizeof(str[0]);
    permuteRec(str, 0, n);                  // Bypass using a wrapper function as the size is being calculated within the main function
    return 0;
}

您将看到示例程序和您的程序的相似之处,主要区别在于在“main”函数中导出数组元素的数量并且不使用包装程序。

测试此重构代码会产生以下终端输出。

craig@Vera:~/C_Programs/Console/PermInteger/bin/Release$ ./PermInteger 
1  2  3  
1  3  2  
2  1  3  
2  3  1  
3  2  1  
3  1  2  

作为进一步的测试,测试了四个元素的数组大小,只是为了证明排列数已导出并打印。

int main() {
    int str[] = {1, 2, 3, 4};
    int n = sizeof(str) / sizeof(str[0]);
    permuteRec(str, 0, n);                  // Bypass using a wrapper function as the size is being calculated within the main function
    return 0;
}

craig@Vera:~/C_Programs/Console/PermInteger/bin/Release$ ./PermInteger 
1  2  3  4  
1  2  4  3  
1  3  2  4  
1  3  4  2  
1  4  3  2  
1  4  2  3  
2  1  3  4  
2  1  4  3  
2  3  1  4  
2  3  4  1  
2  4  3  1  
2  4  1  3  
3  2  1  4  
3  2  4  1  
3  1  2  4  
3  1  4  2  
3  4  1  2  
3  4  2  1  
4  2  3  1  
4  2  1  3  
4  3  2  1  
4  3  1  2  
4  1  3  2  
4  1  2  3  

再次,如果您没有参考,我建议您参考随附的页面链接,并查看如何使用递归调用来代替尝试在二维数组中创建和存储数据。

© www.soinside.com 2019 - 2024. All rights reserved.