【汇编语言实战】整数拆分问题

文章介绍了如何使用C语言和汇编语言实现一个递归算法,用于寻找给定整数的所有拆分方式。通过res数组存储解法,展示了从n开始拆分并递归处理剩余部分的过程。

输入一个N,输出所有拆分的方式。

例如输入3,输出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输出结果。

C语言描述:

#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;
    scanf("%d", &n);
    divN(n, 1);
    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

运行结果:

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

秋说

感谢打赏

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

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

打赏作者

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

抵扣说明:

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

余额充值