我主要是一名 Python 开发人员,但偶尔也会使用 C++。我正在尝试使用 C++ 中的扩展欧几里得算法来实现模乘法逆。在 Python 中,使用元组拆包,代码简洁且惯用:
def inv_modulo(a: int, b: int) -> int:
_s, s = 1, 0
_t, t = 0, 1
while a % b != 0:
q, r = divmod(a, b)
_s, s = s, _s - q * s
_t, t = t, _t - q * t
a, b = b, r
return s
我想在 C++ 中复制此行为并编写了以下代码:
long long inv_modulo(long long a, long long b) {
long long old_s = 1, s = 0;
long long old_t = 0, t = 1;
while (a % b != 0) {
auto [q, r] = std::lldiv(a, b);
std::tie(old_s, s) = std::make_tuple(s, old_s - q * s);
std::tie(old_t, t) = std::make_tuple(t, old_t - q * t);
std::tie(a, b) = std::make_tuple(b, r);
}
return s;
}
我对此实施有三个具体问题:
AFAIK,
std::tie
最初是为完全相同的用途而设计的;作为作业的左侧,尽管稍后可能会出现其他有用的案例。这个习语在OP片段中很好地说明了相对论:
std::tie
在作业的左侧std::tuple
构造函数(或 std::make_tuple
对于较旧的标准修订版)位于赋值的右侧。std::tie
创建一个对元素的引用的临时元组,这些元素需要从另一个元组分配。
每个程序的主要目标是功能和可读性。只有在仔细的基准测试之后才会出现优化问题。