Java 组合和置换算法(递归)

Java 组合和置换算法(递归),java,recursion,permutation,combinations,repeat,Java,Recursion,Permutation,Combinations,Repeat,我正在做一个Java作业,我完全被难住了 问题是: 使用递归编写函数以执行以下操作:您有X张不同的卡。你只有三个信封。Y小于或等于X。对于任何给定的X和Y值 当顺序不重要且不允许重复时,显示填充Y信封的所有可能方式提示:X!/((X-Y)!*Y!) 当顺序重要且允许重复时,显示填充Y信封的所有可能方式提示:X^Y 当顺序重要且不允许重复时,显示填充Y信封的所有可能方式提示:X!/(X-Y) 当顺序不重要且允许重复时,显示填充Y信封的所有可能方式提示:(X+Y–1)!/(Y!*(X–1)!) 例如

我正在做一个Java作业,我完全被难住了

问题是:

使用递归编写函数以执行以下操作:您有X张不同的卡。你只有三个信封。Y小于或等于X。对于任何给定的X和Y值

  • 当顺序不重要且不允许重复时,显示填充Y信封的所有可能方式<代码>提示:X!/((X-Y)!*Y!)

  • 当顺序重要且允许重复时,显示填充Y信封的所有可能方式
    提示:X^Y

  • 当顺序重要且不允许重复时,显示填充Y信封的所有可能方式提示:
    X!/(X-Y)

  • 当顺序不重要且允许重复时,显示填充Y信封的所有可能方式提示:
    (X+Y–1)!/(Y!*(X–1)!)

  • 例如,在情况(1)下,
    如果X={J,Q,K,A)和Y=3
    ,那么输出应该是:
    {J,Q,K}{J,Q,A}{J,K,A}{Q,K,A}。

    我不希望任何人发布任何代码,也不希望任何人为我解决此问题!我希望在完成第一部分(问题a)后,它将解锁防淹门。请有人在制定伪代码算法时提供一些指导,这是我所能做到的:

    在Y信封中依次填充递增的卡片
    (例如:X=5,Y=3){1,2,3}。
    用最高的卡片替换最高信封中的
    {1,2,5}
    ,递减直到我们找到它的原始值
    {1,2,4}
    。 对每个信封从高到低(数字尚未使用)执行此操作。
    {1,5,4}{1,3,4}{5,3,4}{2,3,4}。

    这就是我在它崩溃之前所得到的,因为它缺少3个组合
    {1,5,3}{3,4,5}{5,3,2}.

    我将非常感谢任何帮助,因为这是一个任务,我将重复,我不想要解决方案,我想要帮助我自己找到解决方案。 谢谢大家!

    编辑:我已经尝试了概述的所有3种解决方案,但我仍然没有得到它。这是我目前得到的:

    public static void comboNoRep(String[] a, int y, boolean[] used)
    {
    
        if(y == 0) {
            // found a valid solution.
            System.out.println(result);
        }
    
        for(int i=0; i<a.length; i++) {
            if(!used[i]) {
                used[i] = true;
                result = result + a[i];
                comboNoRep(a, y - 1, used);
                result = result + " ";
                used[i] = false;
            }
            else {
            }
        }
    
    }
    
    publicstaticvoidcombonorep(使用字符串[]a,int y,布尔[])
    {
    如果(y==0){
    //找到了一个有效的解决方案。
    系统输出打印项次(结果);
    }
    
    对于(int i=0;i您必须探索所有可能的路线:

    创建“解决方案”的空列表

    对于每一张卡a,您的第一组解决方案首先是将卡放入每个信封中-x*y解决方案

    对于您拾取的每张卡:重复,从同一组卡中移除您使用的卡,直到您完成操作时卡用完。您的解决方案完成并将其放入阵列中


    打印阵列

    您必须探索所有可能的路线:

    创建“解决方案”的空列表

    对于每一张卡a,您的第一组解决方案首先是将卡放入每个信封中-x*y解决方案

    对于您拾取的每张卡:重复,从同一组卡中移除您使用的卡,直到您完成操作时卡用完。您的解决方案完成并将其放入阵列中


    打印数组

    对于问题一,假设您的卡被命名为
    card_1
    card_x
    。请注意,填充Y信封的所有可能方法要么包括
    card_1
    ,要么不包括。如果是,您将问题简化为用卡2到x填充Y-1信封;如果不是,您将问题简化为fi用卡片2到X打印Y信封


    希望这是一个足够的提示,可以帮助你解决问题,而不会太多。祝你好运!

    对于问题一,想象你的卡被命名为
    card\u 1
    card\u x
    。注意,填充Y信封的所有可能方法要么包括
    card\u 1
    ,要么没有。如果是这样,你就把问题简化为填充Y-1信封对于第2张到第X张卡片;如果没有,您将问题简化为用第2张到第X张卡片填充Y个信封


    希望这是一个足够的提示,可以在不太过分的情况下帮助您。祝您好运!

    您的老师希望您使用递归

    对于给定的X,如果Y为零,答案是什么?用你的代码解决这个问题

    答案是什么,对于给定的X,如果我免费给你Y=某个随机整数n的解,n+1的解是什么?换句话说,如果我告诉你X=5,Y=3的解是{{…},{…},{…},},你能很容易地找出X=5,Y=3+1=4的解吗

    下面是一个完全不同问题的示例:

    假设你知道前两个斐波那契数是1和1。那么找到下一个很容易,对吗?是2。现在让我们假设你知道前两个是1和2,下一个是3!如果前两个是2和3,下一个是5

    一些伪代码:

    public int fib(int stop) {
         if (stop < 2) return 1;
         return fibHelp(stop - 2, 1, 1);
    }
    
    public int fibHelp(int stop, int oneBelow, int twoBelow) {
       if (stop == 0) return oneBelow;
    
       return fibHelp(stop - 1, oneBelow + twoBelow, oneBelow);
    }
    
    public int-fib(int-stop){
    如果(停止<2)返回1;
    返回帮助(停止-2,1,1);
    }
    公共int-fibHelp(int-stop、int-one-down、int-two-down){
    如果(停止==0),则返回下面的一个;
    返回fibHelp(停止-1,一下+二下,一下);
    }
    
    看看fibHelp是如何调用自己的?这是递归!只要确保您有一个停止条件(我的if语句)

    对于您的特定问题,不要返回
    void
    ,而是让
    comboNoRep
    返回一个
    Set
    。当
    y=0
    时,返回一个带有一个元素的
    Set
    (一个空的
    Set
    ).
    y=1
    ,返回一个
    集合
    ,该集合通过向较大集合中的每个集合添加一个元素来构建一组
    集合
    (在
    y=1
    的情况下,
    集合
    为空,以此类推)


    使用
    Set
    而不是
    List
    ,因为您希望确保没有重复项。

    您的老师希望您使用递归

    对于给定的X,如果Y为零,答案是什么?
    #include <stdio.h>
    
    //Print Function
    void print(const int *arr, const int size)
    {
        int i;
    
        if (arr != 0) 
        {
            for (i = 0; i < size; i++)
                printf("%d ", arr[i]);
            printf("\n");
        }
    }
    
    //Permute Function
    void permute(int *arr, const int start, const int sets, const int len)
    {  
        int i,tmp;
    
        if (start == sets-1)
            print(arr, sets);
        else
        {
            for (i = start; i < len; i++)
            {
                tmp = arr[i];
    
                arr[i] = arr[start];
                arr[start] = tmp;
    
                permute(arr, start+1, sets, len);   //<-- Recursion
    
                arr[start] = arr[i];
                arr[i] = tmp;
            }
        }
    }
    
    int main()
    {
      int sets,arr[] = {1, 2, 3, 4, 5};
    
      //Accept Number Of Sets To Form
      printf("Enter Number Of Sets: ");
      scanf("%d",&sets);
    
      //Call Permute Function
      permute(arr, 0, sets, sizeof(arr)/sizeof(int));
    
      return 0;
    }