You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MIPS线性搜索结果异常及两种搜索比较次数统计求助

解决你的MIPS搜索程序问题:修复线性错误+统计比较次数

咱们一步步来解决你遇到的两个问题,先搞定线性搜索的错误,再处理比较次数的统计。

一、修复线性搜索的错误

问题根源

你调用binarySearch之后再调用linear,但binarySearch是递归函数,它会修改$a1和$a2这两个寄存器的值(递归过程中要更新左右边界)。当binarySearch返回时,$a2已经不是初始的数组长度10了,而是递归结束后的边界值。

举个例子:你查找目标2时,binarySearch最后会把$a2设为1,这时候linear的循环条件bge $s4, $a2会在s4=1时就跳出循环,根本没机会检查索引1对应的元素(也就是2),所以直接返回-1。

修复方案

有两种简单的修复方式,选哪种都可以:

方案1:调用linear前重新加载数组长度

在main函数里,调用binarySearch之后,重新从内存读取length到$a2,覆盖被修改后的值:

main:
la $a0, array
li $a1, 0
lw $a2, length
li $a3, 4  # 这里注释写错了,应该是"Load item to search for into $a3"
jal binarySearch
lw $a2, length  # 新增:重新加载数组长度
jal linear
# 后续打印代码不变

方案2:让linear自己读取数组长度

修改linear函数,直接从内存读取length,不依赖$a2参数,避免受前面函数的影响:

linear:
li $t0, 0  # 用$t0代替$s4,避免破坏调用者的$s寄存器(符合MIPS调用约定)
lw $t2, length  # 直接读取数组长度
j linearLoop
linearLoop:
bge $t0, $t2, linearFailed  # 用$t2代替$a2作为循环终止条件
lw $t1, 0($a0)
beq $t1, $a3, linearFound
addi $a0, $a0, 4
addi $t0, $t0, 1
j linearLoop
linearFound:
move $v1, $t0
j exitLoop
linearFailed:
li $v1, -1
j exitLoop
exitLoop:
jr $ra

这里额外提一句:MIPS的$s寄存器是被调用者保存的,也就是说如果你的函数(比如linear)要使用$s寄存器,需要先把它的值压栈保存,函数结束后恢复,否则会覆盖调用者(比如main)中$s寄存器的值。所以用$t寄存器代替$s4更稳妥。

二、统计两种搜索的比较次数

1. 线性搜索的比较次数统计

这个你思路是对的,每次循环都会做一次元素比较,我们只需要加一个计数器变量,每次比较时递增即可:

首先在.data段新增计数器变量:

.data
array: .word 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
length: .word 10
newline: .asciiz " \n"
linear_count: .word 0  # 线性搜索比较次数计数器

然后修改linear函数,每次比较前(或后)更新计数器:

linear:
li $t0, 0
lw $t2, length
sw $zero, linear_count  # 每次搜索前重置计数器为0
j linearLoop
linearLoop:
bge $t0, $t2, linearFailed
lw $t1, 0($a0)
# 统计比较次数
lw $t3, linear_count
addi $t3, $t3, 1
sw $t3, linear_count
beq $t1, $a3, linearFound
addi $a0, $a0, 4
addi $t0, $t0, 1
j linearLoop

之后在main里打印计数器的值即可,比如在打印线性搜索结果后:

move $a0, $v1
li $v0,1
syscall
la $a0, newline
li $v0,4
syscall
# 打印线性搜索比较次数
lw $a0, linear_count
li $v0,1
syscall
la $a0, newline
li $v0,4
syscall

2. 二分搜索的比较次数统计

二分搜索是递归的,每次进入函数后都会做一次元素比较(beq和bgt是基于同一次加载的元素的判断,算一次比较),所以我们同样用全局计数器来统计:

首先在.data段新增计数器:

.data
# 其他变量...
binary_count: .word 0  # 二分搜索比较次数计数器

然后修改binarySearch函数,在加载数组元素后,更新计数器:

binarySearch:
addi $sp, $sp, -4
sw $ra, 0($sp)
blt $a2, $a1, binaryFailed

add $t0, $a1, $0
sub $t1, $a2, $a1
srl $t1, $t1, 1
add $t0, $t1, $t0
sll $t1, $t0, 2
add $t1, $t1, $a0
lw $t1, 0($t1)

# 统计比较次数
lw $t2, binary_count
addi $t2, $t2, 1
sw $t2, binary_count

beq $t1, $a3, binaryFound
bgt $t1, $a3, binaryGreater
addi $a1, $t0, 1
j binarySearch
j binaryEnd
# 后续binaryFound/binaryGreater/binaryFailed/binaryEnd代码不变

然后在main里调用binarySearch前重置计数器:

main:
la $a0, array
li $a1, 0
lw $a2, length
li $a3, 4
sw $zero, binary_count  # 重置二分搜索计数器
jal binarySearch
# 后续代码不变

最后在main里打印二分搜索的比较次数,比如在打印二分搜索结果后:

move $a0, $v0
li $v0, 1
syscall
la $a0, newline
li $v0,4
syscall
# 打印二分搜索比较次数
lw $a0, binary_count
li $v0,1
syscall
la $a0, newline
li $v0,4
syscall

这样就能准确统计两种搜索的比较次数了。

内容的提问来源于stack exchange,提问作者FloydVu0531

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 17:02:27