伪代码/Java神秘算法

伪代码/Java神秘算法,java,algorithm,sorting,pseudocode,Java,Algorithm,Sorting,Pseudocode,我有一个算法,我想知道它的作用。我相信你们中的一些人可以看看这个,告诉我它的作用,但我已经看了半个小时了,我仍然不确定。当我试着玩它的时候,它会变得一团糟。你用什么技巧来破解这样的算法?我如何分析这样的东西,知道发生了什么 我的猜测是它将数字从最小到最大排序,但我不太确定 1. mystery(a1 , a2 , . . . an : array of real numbers) 2. k = 1 3. bk = a1 4. for i = 2 to n

我有一个算法,我想知道它的作用。我相信你们中的一些人可以看看这个,告诉我它的作用,但我已经看了半个小时了,我仍然不确定。当我试着玩它的时候,它会变得一团糟。你用什么技巧来破解这样的算法?我如何分析这样的东西,知道发生了什么

我的猜测是它将数字从最小到最大排序,但我不太确定

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];
public int[]foo(int[]a){
int k=1;
int nSize=10;
int[]b=新的int[nSize];
b[k]=a[1];

对于(int i=2;i,您的代码与伪代码非常接近,但有几个错误:

  • 您的
    for
    循环缺少增量规则:
    i++
    j++
  • Java数组是基于0的,而不是基于1的,因此您应该初始化
    k=0
    a[0]
    i=1
    ,e.t.c
此外,这不是排序,更多的是过滤——您可以获得一些元素,但顺序相同

我如何分析这样的东西,知道发生了什么

这样做的基本技巧是用铅笔和纸手工完成

一种更高级的技术是将代码分解成多个部分,找出这些部分的作用,然后在心里重新组装(技巧是选择分解的边界。这需要实践)


一旦你做得更好,你就可以开始“读取”伪代码了……尽管这个例子对于大多数程序员来说可能有点太难处理了。

当转换为java时,要小心数组索引,因为这个伪代码似乎意味着一个基于1的索引

从静态分析来看:

  • a是输入,不会改变
  • b是输出
  • k似乎是指向b元素的指针,它只会在某些情况下递增(因此我们可以将
    k=k+1
    理解为“下次写入b时,我们将写入下一个元素”)
  • 第6-7行中的循环完成了什么?那么c的值是多少
  • 那么,使用前面的答案,第8行何时为真
  • 由于第9-10行仅在第8行为真时执行,这说明输出中的元素如何
然后,您可以开始检查您的答案:

  • 是否设置输出的所有元素
  • 尝试使用[1,2,3,4]这样的输入来运行psuedocode——您希望输出是什么
永远不会停止惊奇,我想应该在29号吧?;)

Java翻译是一个好主意,一旦开始运行,您将能够逐步了解算法的具体功能,如果您在可视化算法时遇到问题

几点提示:psuedo代码通过
n
索引数组
1
,Java的数组通过
length-1
索引
0
。您的循环需要进行修改以适应这一点。此外,您还保留了循环的增量-
i++
j++

使b magic常量变大也不是一个好主意-查看伪代码,我们可以看到它最多写入
n-1次,因此这将是一个很好的大小起点。您可以调整它的大小,以适应结尾


最后一个提示,算法的O(n2)计时。这很容易确定-外部为循环运行n次,内部为循环运行n/2次,总运行时间为(n*(n/2))。n*n占主导地位,这是大O所关心的,使其成为O(n2)算法。

最简单的方法是取一个样本,但取一小部分数字,然后将其写在纸上。在您的情况下,让我们取数字
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}

你大概可以猜到它在做什么

def funct(*a)
  sum = 0
  a.select {|el| (el >= sum).tap { sum += el }}
end
斯利?谁发明了这些家庭作业问题


顺便问一下:既然这是同时进行
扫描
过滤
,而
过滤
取决于
扫描
,那么哪种语言有必要的功能来简洁地表达这一点,从而使序列只被遍历一次呢?

哦,请确保你把作业放在适当的位置在Seibel的地下室吃了一顿便餐。