【问题标题】:Reverse the data stack using loops使用循环反转数据堆栈
【发布时间】:2020-05-17 17:58:32
【问题描述】:

我正在尝试使用两个循环来反转堆栈,一个循环将数据堆栈中的项目发送到返回堆栈。另一个是让它们从返回堆栈到数据堆栈。 不幸的是,它不起作用 & gforth 返回堆栈下溢错误。 下面是代码:

: srev ( n n2 n3 n4 n5 -- n5 n4 n3 n2 n)
 6 0 do >r loop 
 6 0 do r> loop ;

1 2 3 4 5 srev

【问题讨论】:

    标签: forth gforth


    【解决方案1】:

    您在这里遇到的麻烦是DO ... LOOP 将循环参数(索引和终止值)保留在返回堆栈上,并在循环结束时丢弃它们。这就是为什么>RR> 在循环中必须保持平衡。

    您的代码在循环期间将一个值放在返回堆栈上,然后在循环结束时将其丢弃,留下一个杂散循环参数仍然存在,整个事情变得混乱。

    你可以像这样得到你想要的结果...

    : REVERSE ( i*x i -- i*y ) 0 DO I ROLL LOOP ;
    

    ...虽然我有点不明白你为什么要这么做!

    编辑(在阅读 cmets 和 ruvim 的回复后):

    1. 你的初始反转堆栈算法无论如何都不会起作用,因为一系列R>s 将顺序反转到返回堆栈上,并且相应的>Rs 将其再次反转回参数堆栈,保持原样。

    2. 替代方法,类似于 ruvim,但没有递归,在这里

        : APPLY ( n*x xt n -- n*x' )
            DUP 1- -ROT                ( n*x n-1 xt n )
            0 DO                       ( n*x n-1 xt )
               2>R                     \ park n-1 xt on return stack 
               2R@ DROP ROLL           \ bring next item to top
               2R@ NIP EXECUTE         \ apply the function to it
               2R>                     \ clear junk off return stack for now
            LOOP                       ( n*x n-1 xt )
            2DROP
        ;
    

    它不会工作(因为使用ROLL)与任何影响堆栈深度的东西,如DROPDUP,但' 2* 4 APPLY 工作得很好!

    【讨论】:

    • 谢谢!这说得通。我解决一些问题的方式是堆栈上有一些数字。 1 2 3 4 5 。现在我需要执行一些操作,让我们对它们中的每一个说 x 。使用返回堆栈和两个循环似乎是一个好方法。所以,我的目标是: f 6 0 do 2* >r loop 6 0 do r> loop ;这应该为它工作。
    • 使用您的示例一段时间后。滚动后尝试 2*。行得通,只是在需要保存订单时,堆栈可能需要另一个反向操作。
    【解决方案2】:

    没有必要将 N 个顶部堆栈项目反转为 apply some operation。一个可能的解决方案如下。

    : apply-top ( i*x i xt -- j*x ) \ xt ( x -- k*x )
      swap dup 0= if 2drop exit then ( ... x xt i )
      rot >r 1- swap dup >r recurse ( R: x xt )
      2r> execute
    ;
    

    一些测试:

    2 3 4  3 ' 2* apply-top ( 4 6 8 ) . . .  \ 8 6 4
    2 3 4  3 ' drop apply-top ( ) \ it just drops 3 top items
    

    【讨论】:

    • 谢谢!它有效地解决了我在 cmets 中提到的问题。我尝试通过删除交换和计数 i 进行重构,并整合深度 1- 但我开始得到 stackoverflow。即使它应该工作相同。 : a3 depth 1- dup 0= if 2drop exit then rot >r 1- swap dup >r recurse 2r> execute ; 2 3 4 ' 2* a3
    • : a3 ( i*x xt -- j*x ) depth 1 = if drop exit then swap >r dup >r recurse 2r> execute ;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-06
    相关资源
    最近更新 更多