arrays - 在 MIPS 中对整数进行排序

标签 arrays sorting mips

我刚刚收到了一些帮助,解决了我在这个问题( Trouble with MIPS array )中遇到的一些 MIPS 代码问题,他们给我的代码工作正常。现在我尝试添加一个排序算法来对数组中存储的整数进行排序,但我得到的输出只是 0 后跟作为输入的字符串(正确的输出应该是日期后跟字符串)。这就是我正在编写的代码:

.data
num_array:   .space 400 #array
str_array:   .space 400
in_name: .asciiz "\nInsert name: "
in_date: .asciiz "\nInsert date (mmdd): "
appt:    .asciiz "\nList: "
spaz:    .asciiz " "
.text
main:      
la $s0, num_array        #load array in s0
la $s1, str_array
addi $t0, $zero, 0       #t0=0 counter
addi $s2, $zero, 0       #s1=0 array size counter
j    Input

Input:
# prompt for date
li  $v0, 4           
la  $a0, in_date
syscall

# read date
li  $v0, 5          
syscall

# store date in the num_array
sw $v0, 0($s0)

# increment counter and move to next position in the array
addi $t0, $t0, 1
addi $s2, $s2, 1
addi $s0, $s0, 4

# prompt for name
li      $v0, 4
la      $a0, in_name          
syscall                         #ask name

# store name (max 4 bytes) to str_array ($s1)  
move $a0, $s1
li      $a1, 4
li      $v0, 8
syscall                         #read name

# move to the beginnig of next string in $s1
# increment by 4 because length of each input word is 4
addi $s1, $s1, 4

beq $s2, 5, sort         #if array size=10 go to print
j   Input               #start over until s1=10

sort:

    addi    $t1, $zero, 0       
    addi    $t2, $zero, 0       
    addi    $s3, $zero, 0       #swap flag set at 0
    move    $t1, $s0        #first element of array in t1
    addi    $t2, $s0, 4     #second element of array in t2
        jal     ric
    j       print
ric: 
        add     $sp, $sp, -4            #stack pointer
    sw      $ra, 0($sp)             
  pro:  
    addi    $t5, $t5, 1     #counter t0++
    beq $t5, $s2, exit          #if counter=array size go to exit
    bgt $t1, $t2, swap          #swap if t1<t2
    j   pro         #go back
  swap:
    move    $t3, $t1               #$t3=$t1
            move    $t1, $t2               #$t1=$t2
            move    $t2, $t3               #$t2=$t3=$t1
    addi    $s3, $s3, 1     #s3++ (swap flag)   
    j   pro         #go back 
  exit:
    move    $s0, $t1
    addi    $s0, $s0, 4
        bgtz    $s3, sort       #if 2 elements were swapped start over
    lw      $ra, 0($sp)             #load return address
    add     $sp, $sp, 4             
    jr      $ra             #exit   

print:
# print "List:"
la  $a0, appt           
li  $v0, 4          
syscall             #print list

addi    $t0, $zero, 0       #t0=0 counter    
la $s0, num_array # address of num_array
la $s1, str_array # address of str_array
res:
# get number from num_array and print it
lw $a0, 0($s0)
li $v0, 1
syscall

# move to the next element, increment by 4 because numbers take 1 word = 4 bytes
addi $s0, $s0, 4 

# print space
la $a0, 32
li $v0, 11
syscall

# get string from str_array and print it
la $a0, 0($s1)
li $v0, 4
syscall

# print space
la $a0, 32
li $v0, 11
syscall

# move to the next element, increment by 4 because strs have 4 bytes length (in your case)
addi $s1, $s1, 4

# increment loop counter
addi $t0, $t0, 1
blt $t0, $s2, res # $s2 is size of the array


end:
li  $v0, 10         
syscall             #the end

有人可以指出我做错了什么吗?另外,关于如何将排序后的数字后跟相应的字符串作为输出,有什么建议吗? (因此,第一个作为输入给出的日期应该遵循作为输入给出的第一个日期,即使它们已排序)

编辑:我按照星号的建议更改了代码并尝试交换数字。现在输出不只是 0,而是放入相同的输入,但未排序。我做错了什么?

最佳答案

一种方法是对数字数组进行排序并跟踪字符串数组中的相应条目(当您在数字数组中的值周围进行随机播放时,在字符串数组中执行相同的操作)。我建议您开始实现一个简单的排序算法并首先对数字进行排序。例如,考虑实现冒泡排序。为此,您可以考虑实现 swap 过程来交换 2 个值。

编辑 这是他的 mips 版本的程序。它实现了冒泡排序过程。我在文件顶部对数字和字符串数组进行了硬编码(因此您必须进行一些调整才能使其与您的代码一起使用)。这个想法如下:当我交换数字数组中的数字时,我也会交换字符串数组中相应的字符串。

.data
    array: .word 3,2,1,4
    str_array: .ascii "ccc\0bbb\0aaa\0ddd\0"
    n: .word 4
.text

j main

str_swap:
    # swap two strings
    # $a0 - beginning of the first str
    # $a1 - beginning of the second str
    # Assume that str length is 3
    li $t6, 0 # loop counter
    li $t7, 3 # str length
str_loop:
    bgt $t6, $t7, str_loop_end
    lb $t8, 0($a0)  
    lb $t9, 0($a1)
    sb $t8, 0($a1)
    sb $t9, 0($a0)
    addi $a0, $a0, 1
    addi $a1, $a1, 1
    addi $t6, $t6, 1
    b str_loop
str_loop_end:
    jr $ra

swap:
    # $a0 - address of the first num
    # $a1 - address of the second num
    # $a2 - index of the first number in the array
    addi $sp, $sp, -4
    sw $ra, 0($sp)
    lw $s0, 0($a0)
    lw $s1, 0($a1)
    sw $s0, 0($a1)
    sw $s1, 0($a0)

    la $a0, str_array
    sll $a2, $a2, 2   # $a2 = $a2 * 4
    add $a0, $a0, $a2 # address of the first str
    addi $a1, $a0, 4  # address of the next string
    jal str_swap

    lw $ra, 0($sp)
    addi $sp, $sp, 4
    jr $ra

sort:
    # sort in non-decreasing order
    # $a0 - address of the array
    # $a1 - length of the array
    addi $sp, $sp, -12
    sw $ra, 0($sp)
    sw $a0, 4($sp)
    sw $a1, 8($sp)
    li $t0, 0 # outer index 
    move $t2, $a1
    subi $t2, $t2, 1 # upper bound = length - 1
outer:
    bgt $t0, $t2, outer_end
    li $t1, 0 # inner index
    lw $a0, 4($sp)
    inner:
        bge $t1, $t2, inner_end
        lw $t3, 0($a0) # $t3 = a[i]
        lw $t4, 4($a0) # $t4 = a[i+1]
        move $t5, $a0       # save $a0 in $t5
        bgt $t3, $t4, swap_elements # if a[i] > a[i+1]
        b inner_continue
    swap_elements:
        addi $a1, $a0, 4
        move $a2, $t1
        jal swap
    inner_continue:
        addi $t1, $t1, 1    # increment inner counter
        move $a0, $t5
        addi $a0, $a0, 4    # move to the next position in the array
        b inner

    inner_end:
        addi $t0, $t0, 1    # increment outer loop
        b outer
outer_end:
    lw $ra, 0($sp)  # restore $ra
    addi $sp, $sp, 12
    jr $ra


main:
    la $a0, array
    lw $a1, n
    jal sort # bubble sort the array

    addi    $t0, $zero, 0       #t0=0 counter    
    la $s0, array # address of num_array
    la $s1, str_array # address of str_array
    lw $s2, n
res:
    # get number from num_array and print it
    lw $a0, 0($s0)
    li $v0, 1
    syscall

    # move to the next element, increment by 4 because numbers take 1 word = 4 bytes
    addi $s0, $s0, 4 

    # print space
    la $a0, 32
    li $v0, 11
    syscall

    # get string from str_array and print it
    la $a0, 0($s1)
    li $v0, 4
    syscall

    # print space
    la $a0, 32
    li $v0, 11
    syscall

    # move to the next element, increment by 4 because strs have 4 bytes length (in your case)
    addi $s1, $s1, 4

    # increment loop counter
    addi $t0, $t0, 1
    blt $t0, $s2, res # $s2 is size of the array
end:
    li  $v0, 10         
    syscall             #the end

因此给出这个输入:

array: .word 3,2,1,4
str_array: .ascii "ccc\0bbb\0aaa\0ddd\0"
n: .word 4

产生以下输出:

1 aaa 2 bbb 3 ccc 4 ddd 
-- program is finished running --

关于arrays - 在 MIPS 中对整数进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20528668/

相关文章:

arrays - 如何将数组类型组参数映射到 LTI1p0

sorting - Elo 评级系统的匹配数

assembly - MIPS中的div divu

mips - 在SIGSEGV上显示_Unwind_Backtrace

arrays - 使用单一递归结构伪代码查找最小值和最大值

java - 我正在尝试逐行反转数组

c# - Linq 查询创建字符串数组错误列表

java - 在java中使用值对象内的阿拉伯值对映射进行排序

python - 如何在 pandas 数据框中找到每个月的 "n"最大值?

mips - 如何在 MIPS 中测试整数乘法溢出?