我无法让代码正常工作。 我正在比较堆栈中的前两个数字。最高的数字将最终排在最前面,而较低的数字将回滚到最底层。
count
/length exch def
length {
1 index 0 index gt {
2 1 roll
count 1 sub -1 roll
}if
}repeat
答案 0 :(得分:2)
首先,要非常谨慎地为您的定义选择名称。 length
是运营商的名称。因此,当您的定义生效时(可能在userdict
中),运算符(在systemdict
中)无法通过名称*访问。
对于任何棘手的堆栈操作代码,在每行末尾编写描述堆栈的注释是一个非常好的习惯。这是你可以使用" free"变量名称。
count % ... n
现在,由于我们立即使用此值,实际上根本不需要定义它。把它留在堆栈上。
{ %
} repeat
现在循环可能看起来很难记录堆栈但实际上它完全相同。 repeat循环从堆栈中取出repeat-count参数,因此过程从下面的内容开始。
{ % ...
1 index 0 index
会更好1 index 1 index
(对吧?因为第一个移动了堆栈深度)。但它最好2 copy
。
2 copy gt { % ... x y (x>y)
这里的(x>y)
不在堆栈上,而是代表知识的变量'关系。
2 1 roll
更好exch
。
exch % ... y x (x>y)
count 1 sub -1 roll %
这会将第二个从底部拉到顶部。请参阅我的roll
运营商指南:Positive j to roll away, negative to retrieve.
exch % a b ... y x (x>y)
但是如果x<y
那么我们仍然想从底部滚动下一个数字,对吧?所以if
子句应该在这里结束。
} if
count 1 sub -1 roll % a ... y x b
如果删除1 sub
,则会抓取堆栈底部。然后我认为它应该做你所描述的。
} repeat
组装。
count % ... n
{ % ...
2 copy gt { % a ... x y (x>y)
exch % a ... y x (x>y)
} if % a ... y x (x>y)
count -1 roll % ... y x a (x>y)
} repeat
编辑,一天后:嗯。问题。这不对。由于{<1}}在比较之后发生了,所以在循环终止之前会有一个额外的不必要的roll
,这会将一个较小的被拒绝的值放在最佳。
快速解决方法是添加
roll
最后,在循环之后。但我认为更好的方法是首先滚动,然后比较。
这是一个&#34;围栏发布&#34;如果我看到一个问题。
count 1 roll % a ... y x (x>y)
所以我们实际上只需要进行n-1次比较。这导致这个版本,我认为应该更好。
a b c d e f g h
g>h
f>g
e>f
d>e
c>d
b>c
a>b
还有一个不必要的count 1 sub % a b c ... x y n-1
{
count -1 roll % b c ... x y a
2 copy gt { exch } if % b c ... x y a (a>y)
} repeat
(第一个),但它现在无害。
[*]在已应用roll
的程序中仍可访问。