32位汇编整数拆分

问题描述
输入一个N,输出所有拆分的方式。
如input: 3
output: 
1+1+1
1+2
3

算法思想
用一个数组res[]存放拆分的解,用全局变量存放拆分的方法数。
divN(n,k)使用n表示要分解的整数,k表示res数组下标,即第k次拆分。
先从divN(n,1)开始,用num表示第k个拆分的数,即res[k]=num,
让num在[1,n]内遍历。用rest=n-num表示拆分后剩下的整数值。若rest等于零,
代表本次拆分结束,输出拆分解。否则处理第k+1个数组元素,即divN(rest,k+1),
依次类推,直到rest为0输出结果。

源代码

#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
int res[10000] = { 0 }; //res数组存放解
int times = 0; //times计算拆分的次数
void divN(int n, int k) { //n是需要拆分的整数,k是指res数组的下标
    int rest; //存放拆分后剩余的整数
    for (int num = 1;num <= n; num++) {  //从1开始尝试拆分
         if (num >= res[k - 1] ) { //拆分的解要大于或等于前一个解保证不重复
            res[k] = num; //将这次拆分存放在res数组中
            rest = n - num; //剩下的是n-num
            if (rest == 0) { //如果没有剩下的,说明本次拆分结束
                times++;  //拆分次数加1
		printf("%3d:", times);
                for (int j = 1; j < k; j++) {  //输出解
                    printf("%d+", res[j]);
                }
                printf("%d\n", res[k]);
            }
            else divN(rest, k + 1);  //如果有剩下的,继续求出res[k+1]
        }
    }
}
int main() {
    int n;
    printf("Please enter a integer N:");
    scanf_s("%d", &n);
    divN(n, 1);
    printf("there are %d ways to divide the integer %d.", times,n);
    system("pause");
    return 0;
}

汇编代码

INCLUDE Irvine32.inc
.data
    s1 db 'Please enter a integer N:',0
    s2 db 'there are',0
    s3 db 'ways to divide the integer',0
    res dd 40000 dup(?)
    times dd 0
    n dd 0
.code
main PROC
    mov edx,offset s1
    call writestring
    call readInt
    mov n,eax
    mov ecx,1
    push ecx
    push eax
    call divN
    call outres
    exit
main ENDP

divN PROC
    push ebp
    mov ebp,esp
    pushad

    mov ecx,[ebp+8]     ;ecx:n
    mov ebx,[ebp+12]    ;ebx:k
    mov esi,0   ;esi:rest
    mov edx,offset res ;edx:res[]
    mov edi,1   ;edi:num
again:
    cmp edi,ecx
    jg final
    cmp edi,[edx+ebx*4-4]
    jl final
    mov [edx+ebx*4],edi
    mov eax,ecx
    sub eax,edi
    mov esi,eax
    cmp esi,0
    jne next
    add times,1
next1:
    ; mov eax,times
    ; call writedec
    push ebx
    call output
next:
    inc ebx

    ; mov eax,ebx
    ; call writedec
    ; call crlf

    push ebx
    push esi
    call divN
    dec ebx
    inc edi
    jmp again
final:
    popad
    pop ebp
    ret 8
divN ENDP

output PROC
    push ebp
    mov ebp,esp
    pushad
    mov edx, offset res     ;edx:res
    mov edi,[ebp+8]         ;edi:k
    mov esi,1               ;esi:j
again:
    cmp esi,edi
    jge final
    mov eax,[edx+esi*4]
    call writedec
    mov al,'+'
    call writechar
    inc esi
    jmp again
final:
    mov eax,[edx+edi*4]
    call writedec
    call crlf
    popad
    pop ebp
    ret 4
output ENDP

outres PROC
    push ebp
    mov ebp,esp
    pushad
    mov edx,offset s2
    call writeString
    mov al,' '
    call writechar
    mov eax,times
    call writedec
    mov al,' '
    call writechar
    mov edx,offset s3
    call writestring
    mov al,' '
    call writechar
    mov eax,n
    call writedec
    call crlf
    popad
    pop ebp
    ret 
outres ENDP
END main

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值