不知道我的算法使用什么数据结构

时间:2013-09-07 18:47:14

标签: java algorithm

我试图编写我的第一个算法,这是我想要的伪代码。该算法假设为k点置换集合{0,1,2,3,4,5,6,7,8,9}。例如,n =设定0-9,因此n = 10且r = k n ^ r置换

所以U = {0,1,2,3,4,5,6,7,8,9}(单链表)
S最初为空,让k = 2。该集合应该有10 ^ 2个排列。遵循伪代码一步一步..

1)"从U"中删除e和"添加到S"

的末尾
U={1,2,3,4,5,6,7,8,9}

S={0}

2)然后它" PuzzleSolve(k-1,S,U)"再次,因为k!= 1

U={2,3,4,5,6,7,8,9}

现在S = {0,1}且k = 1,因此它会检查解决方案。假设它没有找到解决方案...... 1返回U并从S中删除。

现在:

U ={2,3,4,5,6,7,8,9,1}

S ={0}

所以这一直在重复,直到U中的所有数字都与0匹配,因为第一行中有for循环。不过我的问题是,如何从S的末尾删除e?我想让S成为链表,但我认为不可能从单链表的末尾删除链接。我应该为S使用什么数据结构?

Algorithm PuzzleSolve(k,S,U):

Input: Integer k, sequence S, and set U (universe of elements to test)

Output: Enumeration of all k-length extensions to S using elements in U without repetitions


**for** all e in U **do**
  Remove e from U {e is now being used}
  Add e to the end of S
  **if** k = 1 **then**
         Test whether S is a configuration that solves the puzzle
         **if** S solves the puzzle **then**
           **return** “Solution found: ” S
**else**
  PuzzleSolve(k - 1, S,U)
Add e back to U {e is now unused}
Remove e from the end of S

3 个答案:

答案 0 :(得分:2)

在这种情况下,使用数组或arrayList是有意义的。由于您已经知道集合的大小,因此无需使用链接列表。但是,根据您的问题,您是否必须创建自己的结构或是否可以使用内置结构尚不清楚。如果您无法使用数组,则可以实现链接列表。您应该使链接列表可迭代,以便您可以使用for-each-loops迭代它。

您在创建链接列表方面需要帮助吗?

答案 1 :(得分:1)

你发布的问题有点令人困惑,因为你写的就好像我们坐在你旁边看你的作业......我们不是。伪代码描述了一个递归的强力算法来解决问题 - 尝试所有可能的解决方案,直到找到有效的解决方案。

另一方面,你的问题是“算法应该置换k点的集合”。呃...不是根据伪代码。

通过阅读伪代码,我的理解是你从宇宙集开始:

{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

你想尝试所有“宇宙的有序k元组,没有重复”。我们的意思是:

(0, 1), (0, 2), (0, 3), ..., (0, 9)
(1, 0), (1, 2), (1, 3), ..., (1, 9)
(2, 0), (2, 1), (2, 3), ..., (2, 9)
...
(9, 0), (9, 1), (9, 2), ..., (9, 8)

这不是编写代码所必需的,但是“没有重复的有序k元组”的数量可以通过|U| * (|U| - 1) * ... * (|U| - k + 1)或在这种情况下公式化地描述:

10 * (10 - 1) => 90 (you can cross-check with the brute-force enumeration
above)

现在回答你的问题,我只想使用ArrayList,这是基础java库的一部分:http://docs.oracle.com/javase/1.5.0/docs/api/java/util/ArrayList.html

如果您不需要您不想编写自己的数据结构。支持ArrayList的代码非常重要。除非你的教授禁止你使用它们,否则我不会试图模仿它的部分内容。你可以使用基本数组,但抽象很好......为什么不使用呢?使用ArrayList实现伪代码会更容易,因为伪代码几乎与ArrayList上的操作完全相同,例如remove()add()

如果您编写了自己的数据结构,则必须执行类似的操作...... 可能是练习的一部分。如果您在使用该实现时遇到问题,请在单独的帖子中提出新问题。

答案 2 :(得分:0)

使用数组,并使用索引:

int[] all; int u_begin, u_end, s_begin, s_end;

,其中

u_begin=0; u_end=10-k-1; s_begin=10-k, s_end=9;

基本上,数组的开头是U,结尾是S,你使用索引来跟踪分隔的位置。 我使用了4个索引让你理解得更好,但实际上只需要一个,k,你可以从中计算其他所有内容。

当您的代码需要

Remove e from U {e is now being used}
  Add e to the end of S

更改k的值,将其增加1。 并通过修改索引和适当交换元素来调整算法以使用数组。