0

用户的输入是为了确定数字(最多 20 位)是否是回文,但我还需要随后找到模式数字。如果模式数字并列,则应打印具有最大值的数字。

我可以使用基本的分支、负载和运算符,例如除法、乘法和加法。

目前我的数字回文方法只是在找到输入字符串的长度后逐个字符进行比较。

更新:使用计数器数组的想法创建了一个解决方案。在查找字符串长度的计数循环期间,我计算了每个数字的出现次数。在 find_mode 循环中,我稍后会遍历 counters 数组并比较每个出现的次数。可能不是最佳的(最少指令数),但它可以工作。谢谢gusbro的指导!

    .data
buf1:   .space  21     # receive original input in this buffer
counters: .byte 0,0,0,0,0,0,0,0,0,0 # counters for digits 0-9 for number of occurrences

# the following are constant strings that you can use for your prompts and messages
msgin:  .asciiz "Enter up to 20 digits without spaces: "
msg1:   .asciiz "\nYour string: "
msg2:   .asciiz " IS a palindrome\n"
msg3:   .asciiz " IS NOT a palindrome\n"
msg4:   .asciiz "\nThe mode digit is: "

# print this string for a newline character
nline:  .asciiz "\n"

    .text
main:
li $v0, 4 
la $a0, msgin
syscall # print msgin
li $v0, 8
la $a0, buf1
la $a1, 20
syscall # read string
li $v0, 4
la $a0, msg1
syscall # print msg1
li $v0, 4
la $a0, buf1
syscall # print user input

la $a1,buf1
add $t3, $0, $0 # counter of input length

count:
lb $t1,($a1)
beq $t1, 10, initialize # branches if it reaches the LF character

#this part is for the mode digit counters
subu $t1, $t1, '0'
lb $t2, counters($t1)
addi $t2, $t2, 1
sb $t2, counters($t1) # update counters(i)

addi $t3, $t3, 1 # increase counter
addi $a1,$a1,1 # traverse the string
b count

initialize:
la $a1, buf1 # sets up pointer going forwards
la $a2, buf1 # sets up pointer going backwards

div $t4, $t3, 2 # get the amount needed to traverse backwards, so that odd number palindromes work too

addi $t3, $t3, -1 # last digit will be at (input length - 1)
add $a2, $a2, $t3 # move the second pointer to the last digit

check:
beq $t4, $0, isPalindrome # if the traverse counter = 0, nothing left to traverse
lb $t1, ($a1) # starting digit
lb $t2, ($a2) # ending digit
bne $t1, $t2, isNotPalindrome
addi $t4, $t4, -1 # reduce amount to traverse by 1
addi $a1,$a1,1 # move pointer forwards
addi $a2,$a2,-1 # move pointer backwards   
b check

isPalindrome:
li $v0, 4
la $a0, msg2
syscall # print is palindrome
b mode

isNotPalindrome:
li $v0, 4
la $a0, msg3
syscall # print not palindrome
b mode

mode:   
addi $t7, $0, 0 # counter for number of occurrences
add $t6, $0, $0 # counter to know if done iterating
addi $t5, $0, 0 # the mode digit
la $a1, counters

find_mode:
beq $t6, 10, print # stops iterating through
lb $t1, ($a1)
bge $t1, $t7, store_mode # number of occurences are higher, go store the new mode digit
addi $t6, $t6, 1 # moves counter forward
addi $a1, $a1, 1 # moves pointer forward
b find_mode

store_mode:
add $t7, $t1, $0 # stores the highest number of occurrences
add $t5, $t6, $0 #stores the actual number
addi $t6, $t6, 1 #moves counter forward
addi $a1, $a1, 1 # moves pointer forward
b find_mode

print:
li $v0, 4
la $a0, msg4
syscall
li $v0, 1
move $a0, $t5 # prints mode digit
syscall

exit:
li $v0,10
syscall
4

1 回答 1

1

您可能有一个由 10 个计数器组成的数组(每个数字一个)。当您计算字符串是否是回文时,您可以更新这些计数器:首先在数据部分声明数组:

counters: .byte 0,0,0,0,0,0,0,0,0,0   # counters for 10 digits

然后在检查字符串是否为回文时更新计数器

addi $a2,$a2,-1 #move pointer backwards  --- your code
  subu $t1, $t1, '0'
  lb $t2, counters($t1)
  addi $t2, $t2, 2
  sb $t2, counters($t1) # update counters(i)
b check  # --------your code

如果是回文,您仍然必须考虑字符串是偶数还是奇数(如果不考虑中间数字,则计算中间数字):

# This code should go after you print that the string is palindrome
# Update counter if string was odd
  andi $t3, $t3, 1
  bnez $t3, even
  lb $t1, ($a1)
  subu $t1, $t1, '0'
  lb $t2, counters($t1)
  addi $t2, $t2, 1
  sb $t2, counters($t1) # update counters(i)
even:

现在对计数器进行线性搜索以获得模式:

  addu $a1, $0, 9
  xor $t2, $t2, $t2
find_mode:
  lb $t1, counters($a1)
  ble $t1, $t2, not_mode
  move $t2, $t1
  move $t3, $a1
not_mode:  
  subu $a1, $a1, 1
  bnez $a1, find_mode

并打印结果...

  li $v0, 4
  la $a0, msg4
  syscall
  li $v0, 1
  move $a0, $t3
  syscall
于 2013-02-08T18:41:55.080 回答