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, bool>
bool变量用于判断线性同余式是否有解,
vector用于存放线性同余式的解集
*/
pair, bool> LinearCongruence(int a, int c, int m)
{
if ((a < 1) || (c < 1) || (m < 1))
return make_pair, bool>(vector(), false);
Triple et = EuclidEx(a, m);
if (c % et.g != 0)
return make_pair, bool>(vector(), false);
int x0 = (c * et.s) / et.g;
vector vec(et.g);
for (int k = 0; k < et.g; ++k)
vec[k] = (x0 + k * m / et.g) % m;
return make_pair, 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, bool> P = LinearCongruence(a, c, m);
if (P.second)
{
vector vec = P.first;
cout<
运行结果如下图: