我工作的分配类似于二叉树时遇到困难,了解如何正确C.编写以下问题递归过程要将呼叫在MIPS
int choose(int n, int k){
if (k == 0) {
return 1;
} else if (n == k) {
return 1;
} else if (n < k) {
return 0;
} else {
return choose(n-1, k-1) + choose(n-1, k);
}
}
我的想法是使用三个寄存器每次调用$s0, $s1, $s2
时将值存储到堆栈中,其中$s0
将包含更新后的值n
; $s1
将维持值k
;并且$s2
将在第二个choose(n-1, k)
中保留值k
,因为该值只会在父呼叫改变时才会降低。我选择这个的原因是因为k
的值不是从这个函数中的每个调用中减去的,它应该是相同的,直到父进程在先前的调用中递减它为止。
这是我试图做的Choose
程序。问题是我没有得到正确的答案,当然。
Choose:
#store current values onto stack
addi $sp, $sp, -16
sw $ra, 0($sp)
sw $s0, 4($sp)
sw $s1, 8($sp)
sw $s2, 12($sp)
#check values meet criteria to add to $v0
beq $s1, $0, one
beq $s0, $s1, one
blt $s0, $s1, zero
beq $s2, $0, one
#no branches passed so decrement values of n and k
subi $s0, $s0, 1
subi $s1, $s1, 1
#move values of registers to $a's for argument passing
move $a0, $s0
move $a1, $s1
jal Choose #call procedure again
#this is where I'm having my problems
#not sure how to loop the procedure to get
#the second half of the equation Choose(n-1,k)
#which is the reason for the next 2 lines of code
move $a2, $s2
jal Choose
add $v0, $v0, $v1
j Choose_Exit
#add one to $v1 from branch passed
one:
addi $v1, $v1, 1
j Choose_Exit
#branch returns 0
zero:
addi $v1, $v1, 0
j Choose_Exit
#return values to caller from stack
Choose_Exit:
lw $s2, 12($sp)
lw $s1, 8($sp)
lw $s0, 4($sp)
lw $ra, 0($sp)
addi $sp, $sp, 16
jr $ra
所以我在了解如何正确地实现两倍于该递归过程将它们加在一起的问题。我可以理解如何在MIPS中创建递归过程来执行阶乘,因为这总是任何语言的递归定义。但是,使用不同论点的递归,然后将它们加在一起会让我困惑不已。
当写在纸上时,我明白这个过程可以用父母和孩子的二叉树来表示。父母是单功能Choose(n,k)
,孩子是Choose(n-1, k-1) + Choose(n-1, k)
,并且叶子孩子从if
声明中分支一次,它将一个数字传递给等待另一个被呼叫者部分的加数的父母返回其值等。等等
任何帮助指出我在正确的方向,我做错了什么我的方法会很好。我明白了一开始,我明白了最后,只需要一些帮助来帮助理解中间最重要的部分。
第1步:建立一个约定 - 参数进入'$ a0'和'$ a1',返回值到'$ v0'和寄存器'$ s0' -' $ s7'是callee-save(即退出前必须恢复)。第二步:坚持惯例 - 你知道现在的论点在哪里。如果您需要使用'$ s'寄存器,请将其保存在堆栈中,并在最后将其恢复。如果您需要在呼叫中保留一个值,请将其移入“$ s”寄存器。步骤3:程序 - 一旦你在'$ v0'中选择了(n-1,k-1)*的结果*将它移动到一个保存的寄存器并且调用*选择(n,k-1)*。从这里继续。 –
请注意,“*移入'$ s'寄存器*”符合使用条件。所以,如上所述,你还需要... –
@MargaretBloom感谢您的意见。我理解你对约定的描述以及为什么它很重要。我的教授已经告诉我们你说的是什么,你是对的,因为我应该使用这个约定。有了这个说法,我仍然不确定我如何用我现在的代码实现我想要的。我真的很感激更多的关于如何在需要不同的参数值的时候发生单个递归过程的实例。当第一次调用这个过程时,我没有包含所有使用'$ a#'寄存器的代码来传递参数。 – Pwrcdr87