我有一个算法,我想知道它的作用。我相信你们中的一些人可以看看这个并告诉我它的作用,但我已经看了半个小时了,我仍然不确定。当我尝试玩它时,它会变得混乱。打破像这样的算法你有什么技巧?我如何分析这样的东西,知道发生了什么?
我的猜测是它将数字从最小到最大排序,但我不太确定。
1. mystery(a1 , a2 , . . . an : array of real numbers)
2. k = 1
3. bk = a1
4. for i = 2 to n
5. c = 0
6. for j = 1 to i − 1
7. c = aj + c
8. if (ai ≥ c)
9. k = k + 1
10. bk = ai
11. return b1 , b2 , . . . , bk
这是我尝试用Java编写的等价物,但我不确定我是否正确翻译了:
public int[] foo(int[] a) {
int k=1;
int nSize=10;
int[] b=new int[nSize];
b[k]=a[1];
for (int i=2;i<a.length;){
int c=0;
for (int j=1;j<i-1;)
c=a[j]+c;
if (a[i]>=c){
k=k+1;
b[k]=a[i];
答案 0 :(得分:8)
Google永远不会惊愕,因为29日我会接受它? ;)
Java翻译是一个好主意,一旦操作,您将能够逐步查看算法,如果您在查看时遇到问题,该算法会做什么。
一些指示:伪代码的数组索引为1
到n
,Java的数组被索引0
到length - 1
。您的循环需要修改以适应这种情况。此外,您已将增量从循环中移除 - i++
,j++
。
使b magic常量大小也不是一个好主意 - 查看伪代码我们可以看到它最多被写入n - 1
次,因此这对于它的大小来说是一个很好的起点。你可以调整它以适应最后的效果。
最后一个提示,算法的O(n 2 )定时。这很容易确定 - 外部循环运行n次,内部循环n / 2次,总运行时间为(n *(n / 2))。 n * n占主导地位,这就是Big O关注的问题,使其成为O(n 2 )算法。
答案 1 :(得分:3)
最简单的方法是取一个样本但是一小组数字并在纸上进行处理。在你的情况下,让我们取数字a[] = {3,6,1,19,2}
。现在我们需要逐步完成您的算法:
初始化:
i = 2
b[1] = 3
迭代后1:
i = 3
b[2] = 6
迭代后2:
i = 4
b[2] = 6
迭代3之后:
i = 5
b[3] = 19
迭代4之后:
i = 6
b[3] = 19
结果b[] = {3,6,19}
你可能猜到它在做什么。
答案 2 :(得分:2)
您的代码非常接近伪代码,但这些是一些错误:
for
循环缺少增量规则:i++
,j++
k=0
,a[0]
,i=1
,e.t.c。此外,这不是排序,更多是过滤 - 你得到一些元素,但顺序相同。
答案 3 :(得分:1)
我如何分析这样的东西,知道发生了什么?
这种类似的基本技术是用铅笔和纸手动它。
更先进的技术是将代码分解为多个部分,找出部件的作用,然后在心理上重新组装它。 (诀窍是选择分解的边界。这需要练习。)
一旦你做得更好,你就会开始能够“读取”伪代码......虽然这个例子对于大多数编码人员来说可能有点过于粗糙。
答案 4 :(得分:1)
转换为java时,请注意数组索引,因为这个伪代码似乎暗示了一个基于1的索引。
来自静态分析:
k = k+1
意思是“下次我们写入b时,我们要写到下一个元素“)然后你可以开始理智地检查你的答案:
答案 5 :(得分:0)
def funct(*a)
sum = 0
a.select {|el| (el >= sum).tap { sum += el }}
end
Srsly?谁发明了这些家庭作业问题?
顺便说一句:因为这同时同时执行scan
和filter
,而filter
取决于scan
,哪种语言具有这样简洁地表达这个序列的必要特征是序列只被遍历一次?