4、C++源代码
编写一个程序解线性同余式ax≡c (mod m),为了使得到的所有解都在[0,m-1]范围内,需要简单的修改一下扩展的欧几里得算法,
为了使更简单的处理,要求a,c,m都为正整数,代码如下:
struct Triple
{
Triple(){}
explicit Triple(int g, int s, int t)
:g(g), s(s), t(t)
{
}
int g; //最大公约数
int s; //a的系数
int t; //b的系数
};
/*
@扩展的欧几里得算法
@输入:正整数a,b
@输出:三元组(g, s, t)使得sa + tb = g, 并且保证s > 0
*/
Triple EuclidEx(int a, int b)
{
Triple t0(a, 1, 0),
t1(b, 0, 1),
t2;
while (t1.g)
{
int q = t0.g / t1.g;
t2 = Triple(t0.g - q * t1.g,
t0.s - q * t1.s,
t0.t - q * t1.t);
t0 = t1;
t1 = t2;
}
if (t0.s < 0)
{
t0.s += b;
t0.t -= a;
}
return t0;
}
/*
@功能:求解线性同余式 ax≡c (mod m)
@前置条件:a, c, m是正整数
@参数:a, c, m
@返回值:pair<vector<int>, bool>
bool变量用于判断线性同余式是否有解,
vector<int>用于存放线性同余式的解集
*/
pair<vector<int>, bool> LinearCongruence(int a, int c, int m)
{
if ((a < 1) || (c < 1) || (m < 1))
return make_pair<vector<int>, bool>(vector<int>(), false);
Triple et = EuclidEx(a, m);
if (c % et.g != 0)
return make_pair<vector<int>, bool>(vector<int>(), false);
int x0 = (c * et.s) / et.g;
vector<int> vec(et.g);
for (int k = 0; k < et.g; ++k)
vec[k] = (x0 + k * m / et.g) % m;
return make_pair<vector<int>, bool>(vec, true);
}
5、测试
测试线性同余式893x ≡ 266(mod 2432) 和 943x ≡ 381(mod 2576)驱动程序如下:
int main()
{
int a, c, m;
cout<<"please input three positive integer: >";
cin>>a>>c>>m;
pair<vector<int>, bool> P = LinearCongruence(a, c, m);
if (P.second)
{
vector<int> vec = P.first;
cout<<a<<"x ≡ "<<c<<" (mod "<<m<<") 的解一共有"
<<vec.size()<<"个,分别为:"<<endl;
for (size_t i = 0; i < vec.size(); ++i)
{
cout<<vec[i];
if ((i != 0 && i% 10 == 0)
|| i == vec.size() - 1)
cout<<endl;
else
cout<<',';
}
}
else
{
cout<<a<<"x ≡ "<<c<<" (mod "<<m<<")"<<" 无解!"<<endl;
}
return 0;
}
运行结果如下图: