【问题标题】:Palindrome Generation in MIPSMIPS 中的回文生成
【发布时间】:2020-02-27 21:11:30
【问题描述】:

我需要帮助来编写一个生成回文的程序。我设法使字符串反转,但我无法将原始字符串和反转字符串组合在一起。当我写 abc 时,我需要得到 abccba,或者当我写 hello 时,我需要得到 helloolleh。现在我只得到 cba 或 olleh。有人可以帮我解决这个问题吗?

.data
msg1: .asciiz "Enter the length of your input: "
msg2: .asciiz "Enter your input: "
msg3: .asciiz "Output of the program is: "

output: .space 256 # will store the output palindrome

.text
la $a0,msg1
li $v0,4
syscall

li $v0,5
syscall
move $s1,$v0 # $s1 has the length of the string



la $a0,msg2
li $v0,4
syscall


li $a1,1024
li $v0,8
syscall
move $s0,$a0 # $s0 has the starting address of the string

#
# YOUR CODE GOES HERE(You can use additional labels at the end)
#


move $a3,$s0
move $a1,$s1




add $a3,$a3,$a1
la $a2, output($zero)
jal reverse 



la $a0,msg3
li $v0,4
syscall




la $a0,output($zero)
li $v0,4
syscall

li $v0,10
syscall


reverse:
    # $a0 - address of string to reverse
    # a1 - length of the string
    # a2 - address of string where to store the reverse
    addi $sp, $sp, -4
    sw $ra, 0($sp)
    bltz $a1, reverse_end
    lb $t0, 0($a3)
    subi $a1, $a1, 1
    subi $a3, $a3, 1
    sb $t0, 0($a2)
    addi $a2, $a2, 1
    jal reverse
reverse_end:
    lw $ra, 0($sp)
    addi $sp, $sp, 4
    jr $ra

编辑:这也是回文生成的 C++ 实现。

回文生成递归算法的C++实现

#include <iostream>
#include <string>

using namespace std;

string palindrom(string input, int rem_length)
{

  if(rem_length!=0)
  {
    input=input.substr(0,1)+palindrom(input.substr(1,input.length()-1), \\
                                      rem_length-1)+input.substr(0,1);
  }
  return input;
}

int main()
{
  string input;
  cin >> input;

  input = palindrom(input, input.length());

  cout << input<< endl;

  system("pause");

  return 0;
}

【问题讨论】:

    标签: assembly mips mips32


    【解决方案1】:

    看来您只需要先将输入字符串复制到output 字符串,当您将output 数组传递给reverse 函数时,您需要将指针前进输入字符串长度(传递@987654324 @) 所以反转的字符串将写在它旁边。

    我还认为您应该使用缓冲区进行输入。还要注意输入字符串末尾的 '\n' 字符,因为它会在那里。

    考虑到这些,我将您的代码更改为此

    .data
    msg1: .asciiz "Enter the length of your input: "
    msg2: .asciiz "Enter your input: "
    msg3: .asciiz "Output of the program is: "
    
    input: .space 128
    output: .space 256 # will store the output palindrome
    
    .text
    la $a0,msg1
    li $v0,4
    syscall
    
    li $v0,5
    syscall
    move $s1,$v0 # $s1 has the length of the string
    
    la $a0,msg2
    li $v0,4
    syscall
    
    move $a1, $1
    la $a0, input
    li $v0,8
    syscall
    move $s0,$a0 # $s0 has the starting address of the string
    
    #
    # YOUR CODE GOES HERE(You can use additional labels at the end)
    #
    move $a3,$s0 # a3 = (char *)input
    move $a1,$s1 # a1 = strlen(input)
    
    
    # replacing the read in new line char with 0
    la $t4, input
    add $t4, $t4, $a1
    sb $zero, ($t4)
    
    # copy the string to the resulting string
    move $t0, $s1 # i = strlen(input)
    move $t1, $s0
    la $t3, output
    
    copy_loop:
    beq $t0, $zero, copy_end # i != 0
    lb $t2, ($t1) 
    sb $t2, ($t3) # *output = *input
    addi $t1, $t1, 1 # advancing the input ptr
    addi $t3, $t3, 1 # advancing the output ptr
    subi $t0, $t0, 1 # i--
    b copy_loop
    
    copy_end:
    
    add $a3,$a3,$a1 # a3 = &input[strlen(input)]
    subi $a3,$a3,1 # subtracting one since the last input char is at input[strlen(input)-1]
    la $a2, output
    add $a2, $a2, $a1 # passing the address of output advanced by the input length
    jal reverse 
    
    la $a0,msg3
    li $v0,4
    syscall
    
    la $a0,output($zero)
    li $v0,4
    syscall
    
    li $v0,10
    syscall
    
    reverse:
        # $a0 - address of string to reverse
        # a1 - length of the string
        # a2 - address of string where to store the reverse
        addi $sp, $sp, -4
        sw $ra, 0($sp)
        bltz $a1, reverse_end
        lb $t0, 0($a3)
        subi $a1, $a1, 1
        subi $a3, $a3, 1
        sb $t0, 0($a2)
        addi $a2, $a2, 1
        jal reverse
    reverse_end:
        lw $ra, 0($sp)
        addi $sp, $sp, 4
        jr $ra
    

    这似乎适用于您在 MARS 4.5 MIPS 模拟器中的示例。

    这段代码很可能以更优化的方式完成,但似乎仍然可以完成工作。

    编辑想法:将输入保存到输出字符串,这样就不需要复制了,因此代码可以减少到这个(仅相关部分)

    move $a1, $1
    la $a0, output # !! using the output buffer for the input
    li $v0,8
    syscall
    move $s0,$a0 # $s0 has the starting address of the string
    
    #
    # YOUR CODE GOES HERE(You can use additional labels at the end)
    #
    move $a3,$s0 # a3 = (char *)input
    move $a1,$s1 # a1 = strlen(input)
    
    # the whole copy thing deleted and don't need to be bothered by the new
    # lines, it will be overwritten with the reversed string anyway
    
    add $a3,$a3,$a1 # a3 = &input[strlen(input)]
    subi $a3,$a3,1 # subtracting one since the last input char is at input[strlen(input)-1]
    la $a2, output
    add $a2, $a2, $a1 # passing the address of output advanced by the input length
    jal reverse 
    

    【讨论】:

    • @cvsrt 很高兴它有帮助。请参阅我所做的编辑。使添加的代码更小。
    • 这段代码很可能以更优化的方式完成 OMFG 是的。特别是如果您不必使其递归!就地数组反转是递归做的最不自然的事情之一。由于read 为您提供长度,您可以通过几条指令获得指向用户输入末尾的指针。 (并且您已经在 reg = end 地址中有起始地址,用于向后循环)。因此,从字符串的末尾向后循环读取指针和向前循环写入指针,执行复制和反转。如果您一次只使用一个字符,这需要一个简单的 lbu / sb 循环。
    猜你喜欢
    • 2015-04-17
    • 2022-11-10
    • 2021-05-19
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多