分析
- 类似于整数划分问题 , 因子分解也可以递归求解
- 通过划分解树 , 可以观察到以下规律    - 一个数的所有因子中有如下规律- 该数的因子的因子, 一定是该数的因子
- 但是该数的因子A , 不一定是该数因子B 的因子
 
 设q(n,m) n的所有因子分解中 , 一定包含m因子的 , 分解个数 q(n,m) = q(n,n) n<m - = q(n,m/[小于m的n的因子]) + q(n/m,n/m) n>m
- = q(n,[小于n的n的因子]) + 1 n=m
- = 0 m =1
- = 1 n为质数<br />
 
- 一个数的所有因子中有如下规律
解的输出
- 输出位置 : 在 n = m , 和 n 为质数的两个位置输出
- 解的存储 , 用stack sta 存储
- 解的输出 , 用tsta 辅助sta输出
- 因子的入栈, 出栈时机
- 首先求出n的所有因子- [小于m的n的因子] , 注意次小于m的n的因子,不一定是m的因子 , 此处需要判断
 
- [小于m的n的因子] , 注意次小于m的n的因子,不一定是m的因子 , 此处需要判断
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<stack>
using namespace std;
int divisors[100];
int divisorsNum;
stack<int> sta;
stack<int> tsta;
int firstM = 0; 
//输出一次结果
void printOneResault() {
    int flag = 0;
    while (!sta.empty()) {
        tsta.push(sta.top());
        sta.pop();
    }
    //格式化输出 
    if( firstM != tsta.top()){
        firstM = tsta.top();
        flag = 1;
    }
    if(flag){
        printf("\n");
    } else{
        printf("\t|");
    }
    while (!tsta.empty()) {
        int n = tsta.top();
        tsta.pop();
        sta.push(n);
        printf("%d ", n);
    }
}
//获得下一个较小的因子 
int getNextSmall(int n) {
    if (n == 1) {
        return 1;
    }
    else {
        for (int i = 0; i < divisorsNum; i++) {
            if (divisors[i] == n) {
                return divisors[i - 1];
            }
        }
    }
    return -1;
}
//如果是1 或者 质数 则只有一个分解方式 
int isPrime(int n) {
    for (int i = 2; i <= sqrt(n); i++) {
        if (n % i == 0) {
            return 0;
        }
    }
    return 1;
}
//核心方法 
int function(int n, int m) {
    int resNum1 = 0;
    int resNum2 = 0;
    //如果待分解数n是1或者是质数   直接输出
    if (isPrime(n)) {
        //输出一次结果 
        sta.push(n);
        printOneResault();
        sta.pop();
        return 1;
    }
    //如果m不是n的因子 则继续寻找下一个因子
    else if (n % m != 0) {
        //!!!!!!!! 注意: 一个数的所有因子中 , 某因子 ,不一定是其他因子的因子 例如 [40] {1,2,4,5,8,10.20.40} 其中5不是8的因子 
        //由于 在一次求解过程中,公用最大n的因子 , 所以需要过滤掉 类似于function(8,5) 这样的参数
        //在n的所有因子中 , 小因子A 的所有因子也一定包含在 , n的不大于A的因子中 , 但不全都是A的因子  
        return function(n, getNextSmall(m));
    }
    //如果因子为一 则不输出, 因为和 p(n,n) 中的 +1 重复
    else if (m == 1) {
        return 0;
    }
    else if (n == m) {
        //输出return 1 的组合 
        sta.push(n);
        printOneResault();
        sta.pop();
        return function(n, getNextSmall(n)) + 1;
    }
    //n>m 则结果分解为有一定包含m因子  和 不一定包含m因子的  两群结果
    else if (n > m && m != 1) {
        //一定包括m 
        sta.push(m);
        resNum2 = function(n / m, n / m);
        sta.pop();
        //不一定包括 m 
        int smallM = getNextSmall(m);
        resNum1 = function(n, smallM);
        return resNum1 + resNum2;
    }
    //m>n 的情况
    else {
        return function(n, n);
    }
}
int main()
{
    int n;
    while (1) {
        printf("请输入一个数 : ");
        scanf("%d", &n);
        divisorsNum = 0;
        //获得所有因子 
        for (int i = 1; i <= n; i++) {
            if (n == (n / i) * i) {
                divisors[divisorsNum] = i;
                divisorsNum++;
            }
        }
        //获得所有组成
        printf("\n---> %d 的因式分解个数: %d\n", n, function(n, n));
    }
    return 0;
}
 
                         
                                

