在MIPS中查找Word数组中的重复整数

时间:2016-11-02 15:38:29

标签: algorithm assembly mips maze

我正在编写一个MIPS程序,使用左手规则算法解决随机生成的迷宫。我试图找到一种方法来跟踪迷宫中的最佳路径,因为它完成了LHR算法。

在程序中,$ t9是一个32位数字,用于存储正在穿越迷宫的汽车的当前位置和方向。位31-24将行位置存储在8位2C编号中,23-16存储列位置。我已经知道如何隔离行号和列号,我知道如何将它们存储到.data空间中的单词数组中,但我不确定我是怎么做的找到已经访问过哪些空格,即数组中的重复值。

到目前为止,当它完成迷宫时,数组看起来像这样:

0001020110 [从0,0开始,转到0,1,转到0,2,转到0,1,然后是1,0],我需要找到一种方法将其复制到新数组中,或基本上除掉0,1,因为它访问了那个空间两次并使其成为000210.

或者,我可以将行和列拆分为两个单独的数组。非常感谢任何帮助。

到目前为止,这是该算法的代码。我只包含了我的主要功能,因为所描述的其他功能只链接到移动汽车的功能,而且不会改变汽车的位置。

.data
rows:       .space  100
cols:       .space  100
location:   .space  100

.text

la $a0, location
jal _leftHandRule
j endProgram


_leftHandRule:
#a0: address of location space
.text
goForward:
addi $t8, $zero, 1
andi $t4, $t9, 0x80000      #if the value in 0x80000 (bit 19, row 8) is not 0, then the car is in row 8, and has finished the maze

#row
srl $t5, $t9, 24
andi $t6, $t5, 0xff
sw $t6, location($t7)
addi $t7, $t7, 1       #increments t7 in as the array location counter

#column
srl $t5, $t9, 16
andi $t6, $t5, 0xff
sw $t6, location($t7)
addi $t7, $t7, 1    #increments t7 for the next loop

bne $t4, $zero, endLeftHandRule
andi $t0, $t9, 0x08
bne $t0, $zero, hitWall     #if the value in 0x08 is not zero, there is a wall in front of the car
andi $t2, $t9, 0x04
beq $t2, $zero, noLeftWall  #if the value in 0x04 is zero, there is no left wall beside the car 
j goForward

1 个答案:

答案 0 :(得分:0)

我不会在位置流中寻找重复的坐标对,因为它是O(N)(其中N是路径的长度)。

我会在算法开始时将MxN位visited数组初始化为零(M,N =列/行的最大迷宫大小)(因此数组的大小为M * N / 8字节,或者当使用整个字节代替位,然后使用M * N字节)。

然后,当您访问特定的[x,y]位置时,将visited中的相应位/字节设置为1,如visited[y*N + x] = 1

要测试您是否已到过某个位置,请查看visited[y*N + x]值。那是O(1)测试。

最后,如果你的迷宫定义已经是M * N,并且你可以修改每个单元格中有一些空闲的未使用位,你可以使用那个而不是单独的数组(它不是很明显问题,迷宫是如何定义的,但是在代码中有一些魔法,比如单独的前/左墙,所以也许可以把这个访问位塞进去。)

如果你可以在LHR期间摧毁迷宫定义,你也可以添加假墙来标记你已经尝试过的方式(所以一旦你前进,你就会创建"前进"墙背后的墙原始位置,阻止LHR前进"下次,当它访问原始位置时,它现在将看到路线被阻止。

实际上我不确定这些信息将如何帮助创建LHR算法的最佳路径,我花了5s思考,我还需要其他的东西,可能包含递归,所以我会知道访问过的细胞通过返回特定的递归深度。然后再次,这将是堆栈上的巨大压力,这样写它,所以我会去数组,并可能从LHR变为一些广泛的第一次搜索,因为LHR有点深度优先,这是不太理想的..所以我已经离开了你的道路。仅将我的答案描述为如何将特定单元格标记为已访问,您将如何使用它取决于您。

多考虑5s。你实际上可能真的想在你的"位置"中找到特定的第一次访问单元格。输出,覆盖返回它的盲分支。

你可以通过阅读"位置"从启动到$ t7的数据,当你找到带有当前行/列的两个字节时,在它之后重置t7,否则当达到t7时,它找不到"#34;未找到" (因此,对于每一步,您都可以在"位置"数据中进行O(N)搜索。

但是我仍然会选择另一个"迷宫"数组,这次不仅存储"访问"旗帜,但"指向下一个"。只需在LHR期间覆盖它而无需任何测试(O(1)"测试"每个LHR步骤)。

到达迷宫结束后,我会回去开始,然后沿着"方向前往下一个",产生"位置"带坐标的数据。它将从开始到结束遵循LHR路径而没有死端分支(因为只有特定单元格的下一个"的最后一个方向将保留,这将导致退出。