问答题 对CSTRN起的50个字符的串,统计相同字符的字符数,找出相同字符数最多的字符,存于CMORE单元中。
【正确答案】方法一:
   DATA    SEGMENT
   CSTRN   DB  'A23HJL4KJ6LJ7L5L56JKJLLJK75KJ2Lafbgmn……'
   CMORE   DB    0
   TOTAL   DB    0
   DIFF    DB    1
   DATA   ENDS
   CODE  SEGMENT
     ASSUME  CS: CODE,DS: DATA
   START: MOV  AX,DATA
          MOV  DS,AX
          MOV  SI,00H
          MOV  CX,50-1
   BEG:   MOV  DX,CX    ;用DX保存字符串长度的初始值
          MOV  AL,CSTRN[SI]    ;取第一个字符
   A0:    INC  SI
   LP:    CMP  AL,CSTRN[SI]    ;寻找第一个相同的字符
          MOV  DI,SI    ;暂存SI的地址
          JNZ  NFS    ;不相同,转NFS(未找到)
          INC  DIFF    ;将DIFF内容加1,表示找到一个相同的字符
          INC  SI
          PUSH CX    ;保存CX的内容
          SUB  CX,SI    ;求剩余部分移动次数.为串移动做准备
          MOV  BL,AL    : 保存AL中的内容
   LP1:   MOV  AL,[SI+1]    ;将下一个数前移一位
          MOV  [SI],AL
          INC  SI
          LOOP LP1
          MOV  SI,DI    ;将SI恢复到移动之前
          POP  CX    ;恢复移动前的CX计数
          DEC  CX
          MOV  AL,BL    ;恢复AL中的内容
   NFS:   INC  TOTAL    ;累加计数
          CMP  DX,TOTAL    ;判断是否结束
          JZ   A2
          JMP  A0
   A2:    MOV  BL,DIFF    ;暂存找到的相同字符的个数
          CMP  BL,CMORE    ;新、旧串进行比较
          JC   NFS1
          XCHG BL,CMORE    ;CMORE中始终保留相同字符数最多的字符
   NFS1:  SUB  DX,DIFF      ;用字符串总长度减DIFF,得到新字符串长度
          MOV  CX,DX    ;新字符串的长度
          PUSH CX
          MOV  SI,0
   A3:    MOV  AL,CSRTN[SI+1]    ;将第一个字符替换,重新查找
          MOV  [SI],AL
          LOOP A3
          MOV  DIFF,00H    ;计数清零
          POP  CX
          JZ   OVER
          MOV  SI,0
          JMP  BEG
   OVER:  MOV  AH,4CH
          INT    21H
   CODE ENDS
   END START
   方法二: 先排序再统计
   DATA  SEGMENT
   CSTRN DB'ABCDAD907bafhasdirhnfAFAGRIDFSAHKLAFAOAJFSIa436asf'
   CMORE    DB  ?
     N1    DB 0
     N2    DB 0
   DATA  ENDS
   CODE  SEGMENT
     ASSUME CS: CODE,DS: DATA
   START: MOV  AX,DATA
          MOV  DS,AX
          MOV  CX,50-1
          LEA  SI,CSTRN
   LOP1:  PUSH SI    ;按升序排序
          MOV  DX,CX
   LOP2:  MOV  AL,[SI]
          CMP  AL,[SI+1]
          JBE  NEXT
          XCHG AL,[SI+1]
          MOV[SI],AL
   NEXT:  INC  SI
          DEC  DX
          JNZ  LOP2
          POP  SI
          LOOP LOP1
          MOV  CX,50
          MOV  AH,02H
   LP:    MOV  DL,[SI]    ;显示排序后的字符串
          INT  21H
          INC  SI
          LOOP LP
          MOV  DL,0DH    ;显示换行符
          INT  21H
          MOV  DL,0AH
          INT  21H
          MOV  CX,50
          MOV  SI,0
          MOV  AL,[SI]
   LP1:   CMP  AL,[SI]    ;判断是否相同
          JNZ  A1   ;不相同,转A1
          INC  N1   ;个数加1
          INC  SI    ;改变地址指针
          LOOP LP1
   A1:    MOV  AL,N1
          CMP  AL,N2   ;与N2比较
          JB   A2   ;小于,转A2
          MOV  N2,AL    ;大于,N2存较大数
          MOV  AL,[SI-1]    ;把字符放入CMORE
          MOV  CMORE,AL
          MOV  AL,0
          MOV  N1,AL
          MOV  AL,[SI]    ;改变AL,使其指向下一个不相同的数
   A2:    LOOP LP1
          MOV  DL,CMORE    ;显示个数最多的字符
          MOV  AH,02H
          INT  21H
          MOV  DL','
          INT  21H
          MOV  AL,N2   ;显示个数最多的字符的个数
          CMP  AL,9
          JA   A3
          ADD  AL,30H    ;显示一位字符
          MOV  DL,AL
          INT  21H
          JMP  OVER
   A3:    MOV  AH,0
          MOV  BL,10
          DIV  BL
          ADD  AX,3030H    ;两位字符显示
          MOV  DL,AL
          MOV  DH,AH
          MOV  AH,02H
          INT  21H
          MOV  DL,DH
          INT  21H
   OVER:  MOV  AH,4CH
          INT  21H
   CODE ENDS
   END START
【答案解析】由于本题为一个参数不确定问题,因此在编程时应设置两种变量,一个是相同字符的统计变量,另一个是总计数统计量,作为判断字符结束的条件。由于字符存在大小写问题,因此共计有62个字符,分别为0~9,A~Z,a~z。本题有可能没有相同的字符。本题可使用两种解法,第一种为前向移动,第二种为将字符串全部进行排序,然后再统计字符数最多的字符。为简化程序设计,只保留当前数量最多的相同字符,使用串移动方式去除相同的字符。如原串为AB××××××AC×××××××AG×××,经过第一遍统计后,串中含3个A字符,统计完A后,将3存于CMORE单元中,同时将字符A从串中删除,串变为B××××××C×××××××G×××,串的长度也减3,再统计下一个字符。如新串的长度大于原来的,就用新串长度代之。