递归导致额外不需要的数据
我正在编写一个模块来处理骰子滚动。给定 x 骰子的 y 面,我试图列出所有潜在的掷骰组合。
此代码假设有 3 个骰子,每个骰子的 3 个面都标记为 1、2 和 3。(我意识到我正在使用“幻数”,但这只是一种简化并使基本代码正常工作的尝试。)
int[] set = { 1, 1, 1 };
list = diceroll.recurse(0,0, list, set);
...
public ArrayList<Integer> recurse(int index, int i, ArrayList<Integer> list, int[] set){
if(index < 3){
// System.out.print("\n(looping on "+index+")\n");
for(int k=1;k<=3;k++){
// System.out.print("setting i"+index+" to "+k+" ");
set[index] = k;
dump(set);
recurse(index+1, i, list, set);
}
}
return list;
}
(dump() 是一种仅显示 list[] 内容的简单方法。目前未使用变量 i。)
我尝试做的是将 list[index] 加一,逐步执行列表的整个长度并随着我的进行而增加。
这是我的“最佳尝试”代码。这是输出:
粗体输出是我正在寻找的。我不知道如何摆脱其余的。 (假设三个骰子,每个骰子都有 3 个面。使用递归,这样我就可以将其扩展到任何具有 y 面的 x 骰子。)
[1][1][1][1][1][1]
[1][1][1][1][1][2][1][1][3][1][2][3]
[1][2][1][1][2][2][1][2][3][1][3][3]
[1][3][1] [1][3][2] [1][3][3] [2][3][3] [2][ 1][3]
[2][1][1][2][1][2][2][1][3][2][2][3]
[2][2][1][2][2][2][2][2][3][2][3][3]
[2][3][1] [2][3][2] [2][3][3] [3][3][3] [3][ 1][3]
[3][1][1][3][1][2][3][1][3][3][2][3]
[3][2][1][3][2][2][3][2][3][3][3][3]
[3][3][1][3][3][2][3][3][3]
我对格式表示歉意,这是我能想到的最好的格式。
任何帮助将不胜感激。 (这种方法实际上是为了将数据用于一些非常琐碎的事情,但已经变成了个人挑战。:)
编辑:如果有另一种方法来解决这个问题,我会洗耳恭听,但我也想解决我当前的问题并成功使用递归来做一些有用的事情。
编辑2: 运行包含“简单修复”的代码。当心未使用的变量和奇怪的黑客,我还没有清理它。
package code.testing;
import java.util.ArrayList;
public class CodeTesting {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
int[] set = { 1, 1, 1 };
list = recurse(0,0, list, set);
}
public static ArrayList<Integer> recurse(int index, int i, ArrayList<Integer> list, int[] set){
if(index < 3){
// System.out.print("\n(looping on "+index+")\n");
for(int k=1;k<=3;k++){
// System.out.print("setting i"+index+" to "+k+" ");
set[index] = k;
if (index==2){
dump(set);
}
recurse(index+1, i, list, set);
}
}
return list;
}
static void dump(int[] arr) {
for (int s : arr) {
System.out.format("[%s]", s);
}
System.out.println();
}
}
I'm writing a module to handle dice rolling. Given x die of y sides, I'm trying to come up with a list of all potential roll combinations.
This code assumes 3 die, each with 3 sides labeled 1, 2, and 3. (I realize I'm using "magic numbers" but this is just an attempt to simplify and get the base code working.)
int[] set = { 1, 1, 1 };
list = diceroll.recurse(0,0, list, set);
...
public ArrayList<Integer> recurse(int index, int i, ArrayList<Integer> list, int[] set){
if(index < 3){
// System.out.print("\n(looping on "+index+")\n");
for(int k=1;k<=3;k++){
// System.out.print("setting i"+index+" to "+k+" ");
set[index] = k;
dump(set);
recurse(index+1, i, list, set);
}
}
return list;
}
(dump() is a simple method to just display the contents of list[]. The variable i is not used at the moment.)
What I'm attempting to do is increment a list[index] by one, stepping through the entire length of the list and incrementing as I go.
This is my "best attempt" code. Here is the output:
Bold output is what I'm looking for. I can't figure out how to get rid of the rest. (This is assuming three dice, each with 3 sides. Using recursion so I can scale it up to any x dice with y sides.)
[1][1][1] [1][1][1]
[1][1][1] [1][1][2] [1][1][3] [1][2][3]
[1][2][1] [1][2][2] [1][2][3] [1][3][3]
[1][3][1] [1][3][2] [1][3][3] [2][3][3] [2][1][3]
[2][1][1] [2][1][2] [2][1][3] [2][2][3]
[2][2][1] [2][2][2] [2][2][3] [2][3][3]
[2][3][1] [2][3][2] [2][3][3] [3][3][3] [3][1][3]
[3][1][1] [3][1][2] [3][1][3] [3][2][3]
[3][2][1] [3][2][2] [3][2][3] [3][3][3]
[3][3][1] [3][3][2] [3][3][3]
I apologize for the formatting, best I could come up with.
Any help would be greatly appreciated. (This method was actually stemmed to use the data for something quite trivial, but has turned into a personal challenge. :)
edit: If there is another approach to solving this problem I'd be all ears, but I'd also like to solve my current problem and successfully use recursion for something useful.
edit2:
Running code including the "easy fix." Beware unused variables and weird hacks, I haven't cleaned it up yet.
package code.testing;
import java.util.ArrayList;
public class CodeTesting {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
int[] set = { 1, 1, 1 };
list = recurse(0,0, list, set);
}
public static ArrayList<Integer> recurse(int index, int i, ArrayList<Integer> list, int[] set){
if(index < 3){
// System.out.print("\n(looping on "+index+")\n");
for(int k=1;k<=3;k++){
// System.out.print("setting i"+index+" to "+k+" ");
set[index] = k;
if (index==2){
dump(set);
}
recurse(index+1, i, list, set);
}
}
return list;
}
static void dump(int[] arr) {
for (int s : arr) {
System.out.format("[%s]", s);
}
System.out.println();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
很抱歉我不得不重写代码,但它与您的算法几乎相同,只是进行了一些更正:
这是一个标准的连音递归生成器。如果要将所有
int[]
添加到List
中,请确保add(values.clone())
以便它们独立的int[]
对象。但是额外的输出有什么用呢?
问题是你在扔完所有骰子之前就过早地扔掉了。在伪代码中,这就是您正在做的事情:
对代码的一个简单修复是执行以下操作:
所以回到 Java 实现,修复只是将
dump(set);
移动到 < if (index < 3) 语句的 code>else 情况。I'm sorry I had to rewrite the code, but it's pretty much the same algorithm as yours with some corrections:
This is a standard tuplet recursive generator. If you want to add all the
int[]
into aList
, then make sure toadd(values.clone())
so they are independentint[]
objects.But what's with the extra output?
The problem is that you were dumping prematurely, before you're done throwing all the dices. In pseudocode, this is what you're doing:
An easy fix to your code is to do the following:
So back to the Java implementation, the fix is merely moving
dump(set);
to anelse
case for theif (index < 3)
statement.仅当
index == 2
时才调用dump()
。顺便说一下,
i
和list
似乎未使用。动词是“recur”。 :)Call
dump()
only whenindex == 2
.Incidentally,
i
andlist
seem unused. And the verb is "recur". :)这是一个非递归的替代方案。更改这两个常数即可计算不同骰子和不同骰子数量的所有组合。
Here is a non-recursive alternative. Change the two constants to calculate all combinations for different dices and different numbers of dice.