我有一个伪代码,我已经翻译成java代码,但是无论何时我运行代码,我得到一个空的arraylist作为结果,但它应该给我一个随机的整数列表。 这是伪代码:
Algorithm 1. RandPerm(N)
Input: Number of cities N
1) Let P = list of length N, (|P|=N) where pi=i
2) Let T = an empty list
3) While |P| > 0
4) Let i = UI(1,|P|)
5) Add pi to the end of T
6) Delete the ith element (pi) from P
7) End While
Output: Random tour T
这是java代码:
public static ArrayList<Integer> RandPerm(int n)
{
ArrayList<Integer> P = new ArrayList<>(n);
ArrayList<Integer> T = new ArrayList<>();
int i;
while(P.size() > 0)
{
i = CS2004.UI(1, P.size());// generate random numbers between 1 and the size of P
T.add(P.get(i));
P.remove(P.get(i));
}
return T;
}
我不知道自己做错了什么。
答案 0 :(得分:1)
ArrayList<Integer> p = new ArrayList<>(n);
...创建一个空列表,初始容量为n
。
所有这一切都告诉ArrayList
要初始化为支持存储的大小数组 - 大多数情况下,通过指定它来实现无用的任务。
因此while(p.size() > 0)
运行零次,因为p.size()
在开始时为零。
在伪代码中,“pi = i”在我看来,你想要像这样初始化列表:
for(int i=0;i<n;i++) {
p.add(i)
}
(我已经小写了你的变量名 - 在Java中,惯例是变量startWithALowerCaseLetter - 只有类名StartWithUpperCase。它也是赋予变量描述性名称的Java约定,所以也许cityIdentifiers
答案 1 :(得分:0)
您可能想知道,即使您解决了P始终为空的问题,您的实施还会遇到两个问题。
一个是P.remove(P.get(i))
如果列表具有相等的值项,则不一定会删除第i个项。它从头开始扫描并删除第一次出现的项目。见ArrayList.remove(Object obj)。您应该使用P.remove(i)
代替正确的结果。
然后表现为O(n ^ 2)。原因是ArrayList通过将所有后续项目向左移动一个槽来移除项目,这是O(n)操作。为了获得更好的性能,您可以通过将项目交换到最后来实现自己的“删除”操作。生成下一个随机索引时,请在[0, beginning index of the removed items at the end)
范围内生成它。交换为O(1),整体性能为O(n)。顺便说一下,这叫做Knuth Shuffle。