4.1 编写程序,从键盘接收一个小写字母,然后找出他的前导字符和后续字符,再按顺序显示这三个字符

方法一:

运行效果:

输入B,输出显示ABC;输入A,输出显示@AB

思路:

1、通过键盘输入接收一个字母。

2、将输入的字母减去1,得到前导字符,然后输出。

3、将输入的字母加上1,得到中间字符,然后输出。

4、将输入的字母加上1,得到后续字符,然后输出。

通过MOV AH,07H调用中断接收输入字符,之后输入的字符就存储在AL中,只需要对AL进行操作就可以了。
 

Tips: MOV AH 01H 和 MOV AH 07H的区别:

MOV AH 01H:按下任何键,将其对应字符的ASCII码送入AL中,并在屏幕上显示该字符。

MOV AH 07H:按下任何键,将其对应字符的ASCII码送入AL中,不在屏幕上显示该字符。

使用MOV AH 01H的效果:

使用MOV AH 07H的效果:(本博客使用的是07H)

两者均是从键盘接收字符并存入AL中,只是显示的区别。

代码如下:

DATAS SEGMENT        ;数据段
DATAS ENDS

STACKS SEGMENT        ;堆栈段
STACKS ENDS

CODES SEGMENT                                   ;代码段
          ASSUME CS:CODES,DS:DATAS,SS:STACKS    ;设置段寄存器 代码段寄存器CS:CODES 数据段寄存器DS:DATAS 堆栈段寄存器SS:STACKS
    START:                                      ;程序入口
          MOV    AX,DATAS                       ;设置数据段
          MOV    DS,AX
    
          MOV    AH,07H                         ;输入无回显 是指在输入字符时,字符不会在屏幕上显示出来
          INT    21H                            ;中断 AL=输入字符
    
          SUB    AL,1                           ;将输入的字符减1,得到其前导字符
          MOV    DL,AL                          ;将前导字符存入DL
          MOV    AH,02H                         ;输出前导字符
          INT    21H                            ;中断 DL=输出字符
    
          ADD    AL,1                           ;将输入的字符加1,得到中间字符
          MOV    DL,AL                          ;将中间字符存入DL
          MOV    AH,02H                         ;输出中间字符
          INT    21H                            ;中断 DL=输出字符
    
          ADD    AL,1                           ;将输入的字符加1,得到其后续字符
          MOV    DL,AL                          ;将后续字符存入DL
          MOV    AH,02H                         ;输出后续字符
          INT    21H                            ;中断 DL=输出字符

          MOV    AH,4CH                         ;结束程序
          INT    21H                            ;中断 0=结束程序
CODES ENDS                                      ;代码段结束
    END START                                     ;程序结束 

在上述代码中,我们可以总结出输出一个字符的固定格式

MOV DL,要显示的字符现在所存入的寄存器(例如本例中是AL)

MOV AH,02H

INT 21H

方法二:

从方法一中我们看出,当输出的字母是A时,打印出来的三个连续字符是“@AB”,这是因为A的ascll码前一位是“@”,如何实现当输出的字母是A时,打印出来的三个连续字符是“ZAB”呢?运行效果如下所示:

思路:

1、定义一组字符串,让'a','z'首尾相接,'zabcdefghijklmnopqrstuvwxyza'

2、接收用户从键盘输入的字母,将输入字母与字符串的字母进行比较。

3、如果字符不相等,则继续循环直到找到匹配的字符;找到匹配字符后,通过DEC指令将当前所在字符串的位置减1,以便指向输入字符的前导字符,输出;再加1,找到中间字符,输出;再加1,找到后续字符,输出。

代码如下:

DATA SEGMENT
      STRING DB 'zabcdefghijklmnopqrstuvwxyza'
      CRLF   DB 0AH,0DH,'$'                         ;回车换行符
DATA ENDS

STACK SEGMENT PARA STACK
            DW  128 DUP(?)      ;定义栈段
            TOP LABEL WORD      ;栈顶指针
STACK ENDS

CODE SEGMENT
            ASSUME CS:CODE,DS:DATA,SS:STACK

      START:
            MOV    AX,DATA
            MOV    DS,AX
  
            MOV    AX,STACK                      ;设置栈段
            MOV    SS,AX                         ;设置栈顶指针
            LEA    SP,TOP                        ;设置栈顶
  
            MOV    AH,1                          ;读入一个字符
            INT    21H                           
  
            LEA    DI,STRING                     ;把STRING的地址放到DI
      L1:   INC    DI                            ;INC:+1,指向字符串的第一个字符 ,‘z’
            CMP    AL,[DI]                       ;比较当前字符和字符串的第一个字符
            JNE    L1                            ;如果不相等,则继续比较下一个字符
  
            DEC    DI                            ;如果相等,DEC:-1,指向前导字符
  
            MOV    AH,9                          ;显示字符串
            LEA    DX,CRLF                       ;显示回车换行符
            INT    21H
  
            MOV    CX,3                          ;设置循环次数
      L2:   MOV    DL,[DI]                       ;把字符串的字符放到DL
            MOV    AH,2                          ;显示字符
            INT    21H
            INC    DI                            ;指向下一个字符
            LOOP   L2                            ;循环CX次
  
            MOV    AH,4CH                        ;退出程序
            INT    21H
CODE ENDS
       
         END START

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,这是一个很有意思的问题。 我们可以使用 Manacher 算法来解决这个问题,它可以在线性时间内找到一个字符串中的所有回文子串。 具体步骤如下: 1. 首先将原字符串 S 转化为一个新的字符串 T,使得 T 的长度为奇数,这可以通过在相邻的字符之间插入一个特殊字符来实现,例如将字符串 "abc" 转化为 "^a#b#c$"; 2. 定义一个数组 P,其中 P[i] 表示以字符 T[i] 为中心的最长回文子串的半径长度; 3. 定义两个变量 C 和 R,其中 C 表示当前已知的最长回文子串的中心位置,R 表示该回文子串的右边界; 4. 遍历字符串 T,对于每个位置 i,计算 P[i] 的值: 4.1 如果 i 在当前已知的最长回文子串的右边界 R 的左侧,那么可以利用已知的信息来快速计算 P[i] 的值,具体步骤如下: 4.1.1 计算 i 的对称点 j = 2C - i; 4.1.2 如果 j 的回文半径小于 R - i,那么 P[i] = P[j]; 4.1.3 否则 P[i] 至少为 R - i,需要从 R 开始扩展,直到不能再扩展为止。 4.2 如果 i 在当前已知的最长回文子串的右边界 R 的右侧,那么必须从 i 开始暴力扩展,直到不能再扩展为止。 5. 遍历数组 P,找到最长的回文子串的半径长度 mx 和其在字符串 T 中的中心位置 idx,则最长前缀回文子串为 S[0:idx-mx/2],最长后缀回文子串为 S[idx+mx/2:n-1],其中 n 是原字符串 S 的长度。 Manacher 算法的时间复杂度为 O(n),可以满足题目要求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Flying778

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值