#include <stdio.h>
#include <stdbool.h>

// 交换数组中两个指定位置的元素
void swap(int arr[], int a, int b)
{
    int temp = arr[a];
    arr[a] = arr[b];
    arr[b] = temp;
}

// 递归生成数组的所有排列，并排除重复的排列
void permutation(int arr[], int size, int n)
{
    if (n == size)
    {
        for (int i = 0; i < size; i++)
        {
            printf("%d ", arr[i]);
        }
        printf("\n");
    }
    else
    {
        bool used[100] = {false}; // 用于标记重复元素
        for (int i = n; i < size; i++)
        {
            if (!used[arr[i]])
            {                                  // 检查当前元素是否已经被使用过
                used[arr[i]] = true;           // 标记当前元素为已使用
               
                swap(arr, i, n);               // 交换第i和n个元素，固定第n个位置的元素
                permutation(arr, size, n + 1); // 递归处理下一个位置
                swap(arr, i, n);               // 恢复原顺序，准备下一个交换
            }
        }
            
            // for (int i = 0; i < 10; ++i) {
            //      printf("used[%d] = %s ", i, used[i] ? "true" : "false");
            // }
            //  printf("\n");
    }
}

int main()
{
    int arr[] = {1, 2, 2, 3}; // 初始数组，包含重复元素
    int size = sizeof(arr) / sizeof(arr[0]);

    // 排序数组，以确保重复元素在一起
    // 这样处理后，重复元素会在相邻位置
    for (int i = 0; i < size - 1; i++)
    {
        for (int j = i + 1; j < size; j++)
        {
            if (arr[i] > arr[j])
            {
                swap(arr, i, j);
            }
        }
    }

    permutation(arr, size, 0);
    return 0;
}
