一、原理
杨辉三角,是二项式系数在三角形中的一种几何排列,每个数等于它上方两数之和,杨辉三角中第 n 行第 m 个数为,通过二项式定理,我们可以知道
在二项式中,,所以当,我们便可以利用来计算杨辉三角中的数字
对于一些比较小的数字,可以定义 long long 类型来解决,但是对于一些较大的数字会产生溢出,对于这样的问题,可以定义一个数组来解决。另外,杨辉三角中每一个数都为正数,可以进行分子分母同分
(1)同分
1. 把 m_m 中 m_n 的公因式删除,并更新m_n
2. 把 m_n 中 m_m 的公因式删除,并更新m_m
void YangHui::Adjust1(std::vector<int>& n, std::vector<int>& m)
{
// 删除 m_m 中 m_n 的公因式
int count = 0;
if (0 == m.size() || 0 == n.size())
return;
for (size_t i = 0; i < n.size(); i++)
{
for (size_t j = 0; j < m.size(); j++)
{
if (0 == n[i] % m[j])
{
n[i] = n[i] / m[j];
m.erase(m.begin() + j);
j--;
count++;
}
if (1 == n[i])
{
n.erase(n.begin() + i);
count++;
i--;
break;
}
}
}
if (count == 0)
return;
// 删除 m_n 中 m_m 的公因式
Adjust1(m, n);
}
3. 把 m_m 分解为质数,重复a、b步骤
void YangHui::Adjust2(std::vector<int>& m)
{
if (0 == m.size())
return;
int size = m.size();
for (int i = 0; i < size; i++)
{
for (int j = 2; j <= m[i]; j++)
{
if (0 == m[i] % j)
{
m[i] /= j;
m.push_back(j);
j--;
}
}
}
}
(2)大位数阶乘
1. 在 v 中插入1,用 m_n 中第一项与 v 中所有项相乘
2. 计算每一位的进位,计算出最终进位
3. 把进位加到 v 首项,重复进行,直到 m_n中没有元素
void YangHui::Cal(std::vector<int>& n)
{
Adjust();
std::vector<int> v;
v.push_back(1);
for (size_t i = 0; i < n.size(); ++i)
{
int len = v.size();
for (int j = 0; j < len; ++j)
{
v[j] *= n[i];
}
int jinwei = 0;
for (int j = len - 1; j >= 0; --j)
{
int temp = jinwei + v[j];
jinwei = temp / 10;
v[j] = temp % 10;
}
// 把进位写入 v 中
while (jinwei)
{
v.insert(v.begin(), jinwei % 10);
jinwei /= 10;
}
}
std::cout << "结果:";
int len = v.size();
for (int i = 0; i < len; ++i)
{
std::cout << v[i];
}
std::cout << std::endl;
v.clear();
}
二、测试结果:
(1)小数字
(2)大数字
三、源代码:YangHui.h
#include <iostream>
#include <vector>
class YangHui
{
public:
YangHui(int _n = 0, int _m = 0);
void Adjust();
void GetResult();
private:
void Adjust1(std::vector<int>& n, std::vector<int>& m);
void Adjust2(std::vector<int>& m);
void Cal(std::vector<int>& n);
private:
std::vector<int> m_n;
std::vector<int> m_m;
};
YangHui.cpp
#include "YangHui.h"
void menu()
{
std::cout << "###########################################" << std::endl;
std::cout << "###### 杨 辉 三 角 ######" << std::endl;
std::cout << "##########################################" << std::endl;
std::cout << "###### 1. 计 算 ######" << std::endl;
std::cout << "###### 0. 退 出 ######" << std::endl;
std::cout << "##########################################" << std::endl;
std::cout << "请选择>";
}
YangHui::YangHui(int n, int m)
{
m_n.resize(m);
for (int i = 0; i < m; i++)
{
m_n[i] = n - i;
}
m_m.resize(m);
for (int i = 0; i < m; i++)
{
m_m[i] = m - i;
}
}
void YangHui::Adjust()
{
Adjust1(m_n, m_m);
Adjust2(m_m);
Adjust1(m_n, m_m);
// 此时 m_m 没有元素
}
void YangHui::Adjust1(std::vector<int>& n, std::vector<int>& m)
{
// 删除 m_m 中 m_n 的公因式
int count = 0;
if (0 == m.size() || 0 == n.size())
return;
for (size_t i = 0; i < n.size(); i++)
{
for (size_t j = 0; j < m.size(); j++)
{
if (0 == n[i] % m[j])
{
n[i] = n[i] / m[j];
m.erase(m.begin() + j);
j--;
count++;
}
if (1 == n[i])
{
n.erase(n.begin() + i);
count++;
i--;
break;
}
}
}
if (count == 0)
return;
// 删除 m_n 中 m_m 的公因式
Adjust1(m, n);
}
// 分解 m_m 为质数
void YangHui::Adjust2(std::vector<int>& m)
{
if (0 == m.size())
return;
int size = m.size();
for (int i = 0; i < size; i++)
{
for (int j = 2; j <= m[i]; j++)
{
if (0 == m[i] % j)
{
m[i] /= j;
m.push_back(j);
j--;
}
}
}
}
void YangHui::GetResult()
{
Cal(m_n);
}
// 大位数阶乘
void YangHui::Cal(std::vector<int>& n)
{
Adjust();
std::vector<int> v;
v.push_back(1);
for (size_t i = 0; i < n.size(); ++i)
{
int len = v.size();
for (int j = 0; j < len; ++j)
{
v[j] *= n[i];
}
int jinwei = 0;
for (int j = len - 1; j >= 0; --j)
{
int temp = jinwei + v[j];
jinwei = temp / 10;
v[j] = temp % 10;
}
// 把进位写入 v 中
while (jinwei)
{
v.insert(v.begin(), jinwei % 10);
jinwei /= 10;
}
}
std::cout << "结果:";
int len = v.size();
for (int i = 0; i < len; ++i)
{
std::cout << v[i];
}
std::cout << std::endl;
v.clear();
}
void Result()
{
int num[2];
std::cout << "请输入坐标(n m):";
for (int i = 0; i < 2; i++)
{
std::cin >> num[i];
}
if (num[0] < num[1])
{
std::cout << "n > m" << std::endl;
return;
}
num[1]--;
num[0]--;
if (num[0] < 2 * num[1])
num[1] = num[0] - num[1];
YangHui h(num[0], num[1]);
h.GetResult();
}
int main()
{
int choise = 0;
while (1)
{
menu();
std::cin >> choise;
if (1 == choise)
Result();
else if (0 == choise)
break;
else
continue;
}
return 0;
}