伪代码/Java神秘算法
我有一个算法,我想弄清楚它的作用。我相信你们中的一些人可以看看这个并告诉我它的作用,但我已经看了半个小时了,但我仍然不确定。当我尝试玩它时,它只是变得混乱。你有什么技巧来分解这样的算法?我如何分析这样的事情并知道发生了什么?
我的猜测是它按从小到大的顺序对数字进行排序,但我不太确定。
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];
I have an algorithm, and I want to figure it what it does. I'm sure some of you can just look at this and tell me what it does, but I've been looking at it for half an hour and I'm still not sure. It just gets messy when I try to play with it. What are your techniques for breaking down an algoritm like this? How do I analyze stuff like this and know whats going on?
My guess is its sorting the numbers from smallest to biggest, but I'm not too sure.
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
Here's an equivalent I tried to write in Java, but I'm not sure if I translated properly:
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];
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
Google 永远不会停止带来惊喜,因为29号我走吗? ;)
Java 翻译是一个好主意,一旦运行,如果您在可视化算法时遇到问题,您将能够逐步浏览它以准确了解算法的作用。
一些提示:伪代码的数组索引为
1
到n
,Java 的数组索引为0
到length - 1
>。您的循环需要修改以适应这一点。此外,您还保留了循环中的增量 -i++
、j++
。将 b 设为魔术常量大小也不是一个好主意 - 查看伪代码,我们可以看到它最多被写入
n - 1
次,因此这将是其大小的一个很好的起点。您可以调整它的大小以适合最后。最后提示,该算法的时间复杂度为 O(n2)。这很容易确定 - 外部 for 循环运行 n 次,内部 for 循环运行 n / 2 次,总运行时间为 (n * (n / 2))。 n * n 占主导地位,这是 Big O 所关心的,使其成为 O(n2) 算法。
Google never ceases to amaze, due on the 29th I take it? ;)
A Java translation is a good idea, once operational you'll be able to step through it to see exactly what the algorithm does if you're having problems visualizing it.
A few pointers: the psuedo code has arrays indexed
1
throughn
, Java's arrays are indexed0
throughlength - 1
. Your loops need to be modified to suit this. Also you've left the increments off your loops -i++
,j++
.Making b magic constant sized isn't a good idea either - looking at the pseudo code we can see it's written to at most
n - 1
times, so that would be a good starting point for its size. You can resize it to fit at the end.Final tip, the algorithm's O(n2) timed. This is easy to determine - outer for loop runs n times, inner for loop n / 2 times, for total running time of (n * (n / 2)). The n * n dominates, which is what Big O is concerned with, making this an O(n2) algorithm.
最简单的方法是抽取一小部分数字样本并在纸上进行计算。在您的例子中,我们采用数字
a[] = {3,6,1,19,2}
。现在我们需要逐步执行您的算法:初始化:
迭代后 1:
迭代后 2:
迭代后 3:
迭代后 4:
结果
b[] = {3,6,19}
您可能会猜到它在做什么。
The easiest way is to take a sample but small set of numbers and work it on paper. In your case let's take number
a[] = {3,6,1,19,2}
. Now we need to step through your algorithm:Initialization:
After Iteration 1:
After Iteration 2:
After Iteration 3:
After Iteration 4:
Result
b[] = {3,6,19}
You probably can guess what it is doing.
您的代码非常接近伪代码,但存在一些错误:
for
循环缺少增量规则:i++
、j++
k=0
、a[0]
、i=1
等。 ,这不是排序,更多的是过滤 - 您会得到一些元素,但顺序相同。
Your code is pretty close to the pseudo code, but these are a few errors:
for
loops are missing the increment rules:i++
,j++
k=0
,a[0]
,i=1
, e.t.c.Also, this isn't sorting, more of a filtering - you get some of the elements, but in the same order.
此类操作的基本技术是用铅笔和纸手动执行。
更先进的技术是将代码分解为多个部分,弄清楚这些部分的作用,然后在心里重新组装它。 (技巧是选择分解的边界。这需要练习。)
一旦你变得更好,你将开始能够“阅读”伪代码......尽管这个例子对于大多数人来说可能有点太粗糙了编码员可以这样处理。
The basic technique for something like this is to hand execute it with a pencil and paper.
A more advanced technique is to decompose the code into parts, figure out what the parts do and then mentally reassemble it. (The trick is picking the boundaries for decomposing. That takes practice.)
Once you get better at it, you will start to be able to "read" the pseudo-code ... though this example is probably a bit too gnarly for most coders to handle like that.
转换为 java 时,请小心数组索引,因为此伪代码似乎暗示从 1 开始的索引。
从静态分析来看:
然后你可以开始检查你的答案:
When converting to java, be careful with array indexes, as this pseudocode seems to imply a 1-based index.
From static analysis:
k = k+1
as meaning "the next time we write to b, we're going to write to the next element")Then you can start to sanity check your answer:
先生?谁发明了这些家庭作业问题?
顺便说一句:因为这是同时执行
扫描
和过滤器
,并且过滤器
取决于扫描
,哪种语言具有必要的功能来简洁地表达这一点,使得序列只遍历一次?Srsly? Who invents those homework questions?
By the way: since this is doing both a
scan
and afilter
at the same time, and thefilter
depends on thescan
, which language has the necessary features to express this succinctly in such a way that the sequence is only traversed once?