【问题标题】:finding biggest number in a Postscript stack在 Postscript 堆栈中找到最大的数字
【发布时间】:2014-09-13 14:23:37
【问题描述】:

我无法让代码正常工作。 我正在比较堆栈上的前两个数字。最高的数字将在顶部结束,较低的数字将回滚到底部。

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

【问题讨论】:

    标签: loops compare max postscript


    【解决方案1】:

    首先,在为定义选择名称时要非常小心。 length 是操作员的名称。因此,当您的定义生效时(可能在 userdict 中),操作员(在 systemdict 中)不能按名称访问*。

    对于任何棘手的堆栈操作代码,在每行末尾编写描述堆栈的 cmets 是一个非常好的习惯。这是您可以使用“免费”变量名的地方。

    count    % ... n
    

    现在,由于我们立即使用此值,因此实际上根本不需要定义它。把它留在堆栈上。

    { %
    
    } repeat
    

    现在循环记录堆栈可能看起来很棘手,但实际上它是完全相同的。重复循环从堆栈中取出重复计数参数,因此该过程从下面的内容开始。

    { % ... 
    

    1 index 0 index 会比1 index 1 index 更好(对吗?因为第一个改变了堆栈深度)。但最好是2 copy

        2 copy gt { % ... x y  (x>y)
    

    这里的(x>y) 不在堆栈上,但代表了变量关系的知识2 1 rollexch 更好。

            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
    

    一天后编辑:嗯。问题。这是不对的。由于roll 发生在比较之后,因此在循环终止之前会有一个额外的不必要的roll,它将较小的被拒绝值之一放在顶部。

    快速解决方法是添加

    count 1 roll   % a ... y x  (x>y)
    

    在最后,在循环之后。但我认为更好的方法是先滚动,然后比较。

    如果我看到过的话,那就是“围栏张贴”问题。

    a b c d e f g h
                g>h
              f>g
            e>f
          d>e
        c>d
      b>c
    a>b
    

    所以我们实际上只需要 n-1 个比较。这导致了这个版本,我认为应该更好。

    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(第一个),但它现在无害了。

    [*] 在应用了bind 的过程中仍然可以访问它。

    【讨论】:

      猜你喜欢
      • 2011-11-24
      • 2021-08-05
      • 2016-05-17
      • 1970-01-01
      • 2012-02-20
      • 2014-12-24
      • 2016-11-12
      • 2021-09-14
      • 2012-06-26
      相关资源
      最近更新 更多