我正在从事Java任务,我绝对难以接受。
问题是:
使用Recursion编写一个函数来执行以下操作:您有X个不同的卡。你只有Y信封。 Y小于或等于X.对于X和Y的任何给定值,
显示订单不重要且不允许重复时填写Y信封的所有可能方式。 hint: X! / (( X-Y)! * Y!)
显示订单重要且允许重复时填写Y信封的所有可能方式hint: X^Y
显示订单重要时可以填写Y信封的所有可能方式,并且不允许重复提示:X! / (X – Y)!
显示订单不重要时可以填写Y信封的所有可能方式,并允许重复提示:(X + Y – 1)! / (Y! * (X – 1)!)
例如,在情况(1),if X = {J, Q, K, A) and Y = 3
下,输出应为:{J,Q,K} {J,Q,A} {J,K,A} {Q,K,A}.
我不希望任何人发布任何代码,我也不希望任何人为我解决这个问题!我希望,一旦我完成了第一部分(问题a),它将解锁洪水门。有人可以提供一些指导来制定伪码算法,这是我能得到的:
随着卡(ex: X=5, Y=3) {1, 2, 3}.
的增加,按顺序填写Y信封
用最高卡{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 {
}
}
}
任何人都可以帮助指出我的缺陷吗?
答案 0 :(得分:1)
您的老师希望您使用递归。
对于给定的X,如果Y为零,答案是什么?使用您的代码解决这个问题。
答案是什么,对于给定的X,如果我给你解决Y =一些随机整数n免费,n + 1的解决方案是什么?换句话说,如果我告诉你X = 5的解,Y = 3是{{...},{...},...},你能否轻松找出X = 5的解, Y = 3 + 1 = 4?
以下是一个完全不同问题的示例:
让我们说你知道前两个Fibonacci数字是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);
}
了解fibHelp如何调用自身?这是递归!只要确保你有一个停止条件(我的if语句)。
针对您的具体问题,请不要返回void
,而应让comboNoRep
返回Set<Set<Integer>>
。在y=0
时,请使用一个元素(空Set
)返回Set
。 y=1
,通过向较大集合中的每个集合添加一个元素,返回构建一堆Set
的{{1}} Set
y=1
是空的,等等。)
使用Set
而非Set
,因为您要确保没有重复项。
答案 1 :(得分:0)
您必须探索所有可能的路线:
创建一个“解决方案”的空列表
对于每张卡片a,您的第一套解决方案首先将卡片放在每个信封中 - x * y解决方案
对于您挑选的每张卡片:重复,从同一组卡片中移除您使用的卡片,直到您完成解决方案并且将其放入阵列中时用完卡片
打印数组
答案 2 :(得分:0)
对于问题一,假设您的卡片被命名为card_1
到card_x
。请注意,填充Y信封的每种可能方式都包括card_1
或不包括{{1}}。如果是这样,你就减少了用2到X卡填充Y-1信封的问题;如果没有,你就把问题减少到用信用卡2到X填充Y信封。
希望这足以帮助你而不是太多。祝你好运!
答案 3 :(得分:0)
您可以将Exeter算法用于第一部分。有关更多信息,请参阅以下链接:
Visit Here: http://www.bearcave.com/random_hacks/permute.html
我不知道如何在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;
}