在Postscript堆栈中找到最大的数字

时间:2014-09-12 02:18:37

标签: loops compare max postscript

我无法让代码正常工作。 我正在比较堆栈中的前两个数字。最高的数字将最终排在最前面,而较低的数字将回滚到最底层。

    count 
    /length exch def        
    length {
             1 index 0 index gt { 
                   2 1 roll
                   count 1 sub -1 roll
            }if
    }repeat

1 个答案:

答案 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的程序中仍可访问。