使用模板计算2个数字的LCM
Calculate LCM of 2 numbers using templates
下面的程序计算这两个数字的LCM,预期输出为216,输入为54和24,但我得到57。
有人能帮我做同样的事情吗?让我知道下面的代码片段出了什么问题。
/* *********** /
*** LCM ******/
/**************/
template<bool cond, int V1, int V2>
struct IfCond
{
enum
{
value = V1
};
};
template<int V1, int V2>
struct IfCond<0, V1, V2>
{
enum
{
value = V2
};
};
template<int V1, int V2>
struct findMax
{
enum
{
result = V1 > V2,
value = IfCond<result, V1, V2>::value
};
};
template<int V1, int V2, int max>
struct findLCM
{
enum
{
result = findLCM<max % V1, max % V2, max+1>::result
};
};
template<int V2, int max>
struct findLCM<0, V2, max>
{
enum
{
result = findLCM<0, max % V2, max+1>::result
};
};
template<int V1, int max>
struct findLCM<V1, 0, max>
{
enum
{
result = findLCM<max % V1, 0, max+1>::result
};
};
template<int max>
struct findLCM<0, 0, max>
{
enum
{
result = max
};
};
int main()
{
std::cout<< findLCM<54, 24, findMax<54, 24>::value>::result << std::endl;
}
您需要的是:
template<int V1, int V2>
struct findGCD
{
enum { result = findGCD<V2, V1%V2>::result };
};
template<int V1>
struct findGCD<V1,0>
{
enum { result = V1 };
};
template<int V1, int V2>
struct findLCM
{
enum { result = (V1/findGCD<V1,V2>::result) * V2 };
};
int main()
{
std::cout<< findGCD<54, 24>::result << std::endl; // 6
std::cout<< findLCM<54, 24>::result << std::endl; // 216
}
如果你想通过线性搜索来实现,你需要这样的东西:
template <int V1, int V2, bool finished, int target>
struct findLCMHelper
{
enum { result = findLCMHelper<V1, V2,
target%V1 == 0 && target%V2==0,
target+1>::result };
};
template<int V1, int V2, int target>
struct findLCM<V1, V2, true, target>
{
enum { result = target-1 }; // Correct overshoot
};
template<int V1, int V2>
struct findLCM
{
enum { target = findMax<V1,V2>::value,
result = findLCMHelper<V1, V2,
target%V1 == 0 && target%V2==0,
target+1>::result };
};
不过我不喜欢那种双重测试。必须有一种方法来重构它。我希望这会破坏编译器——它将导致150多个模板实例化。
令人惊讶的是,cpp.sh拒绝与5400,24 实现盈亏平衡
我想你可以做这样的
#include <iostream>
template <int X, int Y>
struct findGDMH
{ static int const result = findGDMH<Y, X%Y>::result; };
template <int X>
struct findGDMH<X, 0>
{ static int const result = X; };
template <int X, int Y>
struct findGDM
{
static bool const largerIsX = (X > Y);
static int const A = (largerIsX ? X : Y);
static int const B = (largerIsX ? Y : X);
static int const result = findGDMH<A, B>::result;
};
template <int X>
struct findABS
{ static int const result = (X > 0 ? X : -X); };
template <int X, int Y>
struct findLCM
{ static int const result = findABS<X*Y>::result
/ findGDM<findABS<X>::result, findABS<Y>::result>::result; };
template <int X>
struct findLCM<X, 0>
{ static int const result = 0; };
template <int X>
struct findLCM<0, X>
{ static int const result = 0; };
template <>
struct findLCM<0, 0>
{ static int const result = 0; };
int main()
{
std::cout<< findLCM<54, 24>::result << std::endl;
return 0;
}
使用C++11,您可以使用constexpr
函数:
constexpr unsigned abs(int const op) {
return op >= 0 ? op : -op;
}
constexpr unsigned gcd(unsigned const a, unsigned const b) {
return b ? gcd(b, a % b) : a;
}
constexpr unsigned lcm(int const a, int const b) {
return abs(a * b) / gcd(abs(a), abs(b));
}
如果你想使用模板:
template <int Op>
struct abs {
static constexpr unsigned const value{Op >= 0 ? Op : -Op};
};
template <unsigned A, unsigned B>
static gcd : gcd<B, A % B> {};
template <unsigned A>
static gcd<A, 0> {
static constexpr unsigned const value{A};
};
template <int A, int B>
static lcm {
static constexpr unsigned const value{
abs<A * B>::value / gcd<abs<A>::value, abs<B>::value>::value
};
};
相关文章:
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 检查输入是否不是整数或数字
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- 如何用数字处理log(0)
- 最高有效数字侧的第N位
- 如何获取一个数字的前3位
- 查找最接近的大于当前数字的数字的索引
- 找到两对数字,使它们的乘积的绝对差最小化
- 我想做一个彼此不同但重复出现的数字
- 将数字转换为字母(例如:123 转换为一二三)
- C++如何计算用户输入的数字中的偶数位数
- 如何在C++中确定文本文件中的元素是字符还是数字
- 打印数字图案
- C++问题:用户认为数字1-100,程序提出问题不超过6次即可得到答案。无法正确
- 如何检查一个c++字符串中有多少相同的字符/数字
- C++ 中数组中所有数字的 LCM
- 使用模板计算2个数字的LCM
- C++程序来计算 1 到 20 之间的数字的 LCM(欧拉项目)
- c++中使用多个数字的LCM递归函数