简体   繁体   English

组合和置换算法(递归)

[英]Combination and Permutation Algorithms (recursive)

I am working on a Java assignment and I am absolutely stumped. 我正在做Java作业,我很沮丧。

The question is: 问题是:

Write a function using Recursion to do the following: You have X different cards. 使用递归编写一个函数来执行以下操作:您有X张不同的卡。 You have only Y envelopes. 您只有Y个信封。 Y is less than or equal to X. For any given values of X and Y, Y小于或等于X。对于X和Y的任何给定值,

  1. display all possible ways you can fill the Y envelopes when Order is not important and Repetition is not allowed. 当“顺序”不重要且不允许重复时,显示所有可能的方式来填充Y信封。 hint: X! / (( XY)! * Y!)

  2. display all possible ways you can fill the Y envelopes when Order is important and Repetition is allowed hint: X^Y 显示当订单重要且允许重复hint: X^Y时可以填充Y信封的所有可能方式hint: X^Y

  3. display all possible ways you can fill the Y envelopes when Order is important and Repetition is not allowed hint: X! / (X – Y)! 当“顺序”很重要且不允许重复时,显示所有可能的方式来填充Y信封。提示: X! / (X – Y)! X! / (X – Y)!

  4. display all possible ways you can fill the Y envelopes when Order is not important and Repetition is allowed hint: (X + Y – 1)! / (Y! * (X – 1)!) 当“顺序”不重要且允许重复时,显示所有可能的方式来填充Y信封: (X + Y – 1)! / (Y! * (X – 1)!) (X + Y – 1)! / (Y! * (X – 1)!)

for example, under case (1), if X = {J, Q, K, A) and Y = 3 , then the output should be: {J,Q,K} {J,Q,A} {J,K,A} {Q,K,A}. 例如,在情况(1)下, if X = {J, Q, K, A) and Y = 3 ,则输出应为: {J,Q,K} {J,Q,A} {J,K,A} {Q,K,A}.

I do not want anyone to post any code and I'm not looking for anyone to solve this for me! 我不希望任何人发布任何代码,也不希望有人为我解决此问题! I am hoping that once I get the first part (question a) done that it'll unlock the flood gates. 我希望一旦完成第一部分(问题a),它将能够解锁防洪闸门。 Can someone please offer some guidance in working out the pseudocode algorithm, this is as far as I can get: 有人可以在制定伪代码算法方面提供一些指导吗,据我所知:

Fill the Y envelopes in order with increasing cards (ex: X=5, Y=3) {1, 2, 3}. 用增加的卡片顺序填充Y信封(ex: X=5, Y=3) {1, 2, 3}. Replace in the highest envelope with the highest card {1, 2, 5} , decrementing until we find it's original value {1, 2, 4} . 用最高的卡{1, 2, 5} 1,2,5 {1, 2, 5}替换最高的信封,并递减直到找到其原始值{1, 2, 4} Do this for every envelope from highest to lowest (where the number is not already in use) {1, 5, 4} {1, 3, 4} {5, 3, 4} {2, 3, 4}. 从最高到最低(没有使用该编号的每个信封) {1, 5, 4} {1, 3, 4} {5, 3, 4} {2, 3, 4}.

That's as far as I get before it falls apart because this is missing 3 combinations {1, 5, 3} {3, 4, 5} {5, 3, 2}. 据我所知,这已经消失了,因为它缺少3个组合{1, 5, 3} {3, 4, 5} {5, 3, 2}.

I would appreciate any help at all and as it's an assignment I'll re-iterate, I don't want the solution, I want help in coming to the solution on my own. 我将不胜感激,因为这是我要重申的一项任务,我不想要解决方案,我希望自己获得解决方案的帮助。 Thank you! 谢谢!

EDIT: I've tried all 3 solutions outlined and I'm still not getting it. 编辑:我已经尝试了所有3个解决方案概述,但我仍然不明白。 This is what I'm getting so far: 这是到目前为止我得到的:

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 {
        }
    }

}

Can anyone help point out my flaw? 谁能帮我指出我的缺点?

Your teacher wants you to use recursion. 您的老师希望您使用递归。

What is the answer, for a given X, if Y is zero? 对于给定的X,如果Y为零,答案是什么? Solve this using your code. 使用您的代码解决此问题。

What is the answer, for a given X, if I give you the solution for Y = some random whole number n for free, what is the solution for n + 1? 对于给定的X,答案是什么?如果我免费给您Y =一些随机整数n的解,那么n + 1的解是什么? In other words, if I tell you that the solution for X = 5, Y = 3 is { { ... }, { ... }, ... }, can you easily figure out the solution for X = 5, Y = 3 + 1 = 4? 换句话说,如果我告诉您X = 5的解,Y = 3是{{...},{...},...},那么您可以轻松地找出X = 5的解吗Y = 3 +1 = 4?

Here is an example for a totally different problem: 这是一个完全不同的问题的示例:

Lets say you know the first previous two Fibonacci numbers are 1 and 1. Then finding the next one is easy, right? 假设您知道前两个斐波那契数是1和1。然后找到下一个是容易的,对吗? it's 2. Now lets say you know the previous two are 1 and 2, the next one is 3! 现在是2。现在您可以知道前两个是1和2,下一个是3! If the previous two are 2 and 3, the next one is 5! 如果前两个是2和3,下一个是5!

Some pseudocode: 一些伪代码:

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);
}

See how fibHelp calls itself? 看看fibHelp怎么称呼自己? That's recursion! 那是递归! Just make sure you have a stop condition (my if statement). 只要确保您具有停止条件(我的if语句)即可。

For your specific problem, don't return void , instead have comboNoRep return a Set<Set<Integer>> . 对于您的特定问题,请不要返回void ,而应使comboNoRep返回Set<Set<Integer>> When y=0 , return a Set with one element (an empty Set ). y=0 ,返回一个Set具有一个元件(一个空Set )。 y=1 , return a Set that builds a bunch of Set s by adding one element to each set in the larger set (in the case of y=1 that Set is empty, and so forth). y=1 ,返回一个Set ,该Set通过向较大集合中的每个集合添加一个元素来构建一堆Set (在y=1的情况下Set为空,依此类推)。

Use Set and not List because you want to make sure that you don't have duplicates. 使用“ Set而不是“ List因为您要确保没有重复项。

You have to explore all the possible routes: 您必须探索所有可能的路线:

Create an empty list of "solutions" 创建“解决方案”的空列表

For every card a, your first set of solutions start by having the card in each envelope - x*y solutions 对于每张卡片,您的第一套解决方案都是将卡片放在每个信封中-x * y解决方案

For each card you picked: repeat, from the same set of cards removing the one you used until you run out of cards when you do your solution is completed and you put it in the array 对于您选择的每张卡:重复上述操作,从同一组卡中删除所使用的卡,直到解决方案完成后用完卡并将其放入阵列中为止

print the array 打印数组

For problem one, imagine your cards are named card_1 to card_x . 对于问题一,假设您的卡被命名为card_1card_x Observe that every possible way to fill Y envelopes either includes card_1 or doesn't. 请注意,填充Y信封的所有可能方式都包括card_1或不包括。 If it does, you've reduced the problem to filling Y-1 envelopes with cards 2 through X; 如果是这样,您就可以解决此问题,可以用卡2到X填充Y-1信封; if it doesn't you've reduced the problem to filling Y envelopes with cards 2 through X. 如果不是这样,则可以将问题减少为用卡片2到X填充Y信封。

Hopefully that's enough of a hint to help you out without being too much. 希望有足够的提示可以帮助您,而又不过分。 Good luck! 祝好运!

You can use the Exeter Algorithm for the first Part. 您可以对第一部分使用埃克塞特算法。 Refer below link for more information: 请参阅下面的链接以获取更多信息:

Visit Here: http://www.bearcave.com/random_hacks/permute.html 请访问此处:http://www.bearcave.com/random_hacks/permute.html

I don't know how to do it in JAVA but a snippet from my old C code may serve the purpose. 我不知道如何用JAVA做到这一点,但是我的旧C代码中的一个片段也许可以达到目的。

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM