多个参数的 GCD
GCD of multiple parameters
我的目标是在 C++ 中概括 std <algorithm>
header 中可用的 __gcd()
。它应该能够调用 std::vector
数组的一系列值。
通用模板 __gcd()
在直接传递参数时工作得很好。如下所示:
math::GCD(1,2,58,54);
然而,当我试图传递一个向量值的范围时(代码在下面给出),它显示了以下错误:
D:\Programming\C++\CPP Programs\My Test\My Test.cpp|33|error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and '__gnu_cxx::__normal_iterator<int*, std::vector<int> >')|
我不知道如何重载 operator<<
或在此模板/程序中包含重载函数。(假设错误是由于 operator<<
的重载已丢失)
namespace math
{
template <typename M, typename N>
constexpr auto GCD(const M& m, const N& n) {
return __gcd(m, n);
}
template <typename M, typename ...Rest>
constexpr auto GCD(const M& first, const Rest&... rest) {
return __gcd(first, GCD(rest...));
}
}
int main()
{
vector<int> vec={1,2,58,54,102,2,37,13,8};
for(auto i=0; i<vec.size()-3; ++i)
cout<<math::GCD(vec.begin()+i, vec.begin()+i+4)<<endl;
return 0;
}
谁能帮我重载 operator<<
或(如果不是这样)找出错误?
提前致谢。
我终于做到了。感谢@Incomputable 的最后评论。但是,我必须使用 math
名称将新模板(用于迭代器)与我们在问题中使用的两个模板分开。就像下面这样:
#include <iostream>
#include <vector>
template<typename T64> constexpr T64 calcGCD(T64 a, T64 b)
{
return (a==0 && b!=0) ? b: a;
while(b)
{
T64 t = a % b;
b = a;
a = t;
}
return a;
}
template <typename Iterator> constexpr auto GCD(Iterator first, Iterator last)
{
auto itrFirst = first;
auto itrEnd = last;
int Size = std::distance(itrFirst,itrEnd);
int Result = 0;
if(Size >=2 )
{
int A = *itrFirst;
std::advance (itrFirst,1);
int B = *itrFirst;
Result = calcGCD(A,B);
std::advance (itrFirst,1);
for(int i = 2; i<Size; ++i)
{
A = *itrFirst;
Result = calcGCD(Result,A);
std::advance (itrFirst,1);
}
}
else return *itrFirst;
return Result;
}
namespace math
{
template <typename M, typename N>
constexpr auto GCD(const M& m, const N& n)
{ return calcGCD(m, n); }
template <typename M, typename ...Rest>
constexpr auto GCD(const M& first, const Rest&... rest)
{ return calcGCD(first, GCD(rest...)); }
}
int main()
{
std::vector<int> vec={1,2,58,54,102,2,37,13,8};
std::cout<<"GCD from Iterator Template : ";
for(unsigned int i=0; i<vec.size()-3; ++i)
std::cout<<GCD(vec.begin()+i, vec.begin()+i+4)<<" ";
std::cout<<std::endl;
std::cout<<"GCD from non-iterator Templates: ";
std::cout<<math::GCD(1,2,58,54)<<" ";
std::cout<<math::GCD(2,58,54,102)<<" ";
std::cout<<math::GCD(58,54,102,2)<<" ";
std::cout<<math::GCD(54,102,2,37)<<" ";
std::cout<<math::GCD(102,2,37,13)<<" ";
std::cout<<math::GCD(2,37,13,8)<<" ";
return 0;
}
它按预期提供了所需的输出。但是,我还没有测试任何其他情况。
输出:
GCD from Iterator Template : 1 2 58 54 102 2
GCD from non-iterator Templates: 1 2 58 54 102 2
我的目标是在 C++ 中概括 std <algorithm>
header 中可用的 __gcd()
。它应该能够调用 std::vector
数组的一系列值。
通用模板 __gcd()
在直接传递参数时工作得很好。如下所示:
math::GCD(1,2,58,54);
然而,当我试图传递一个向量值的范围时(代码在下面给出),它显示了以下错误:
D:\Programming\C++\CPP Programs\My Test\My Test.cpp|33|error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and '__gnu_cxx::__normal_iterator<int*, std::vector<int> >')|
我不知道如何重载 operator<<
或在此模板/程序中包含重载函数。(假设错误是由于 operator<<
的重载已丢失)
namespace math
{
template <typename M, typename N>
constexpr auto GCD(const M& m, const N& n) {
return __gcd(m, n);
}
template <typename M, typename ...Rest>
constexpr auto GCD(const M& first, const Rest&... rest) {
return __gcd(first, GCD(rest...));
}
}
int main()
{
vector<int> vec={1,2,58,54,102,2,37,13,8};
for(auto i=0; i<vec.size()-3; ++i)
cout<<math::GCD(vec.begin()+i, vec.begin()+i+4)<<endl;
return 0;
}
谁能帮我重载 operator<<
或(如果不是这样)找出错误?
提前致谢。
我终于做到了。感谢@Incomputable 的最后评论。但是,我必须使用 math
名称将新模板(用于迭代器)与我们在问题中使用的两个模板分开。就像下面这样:
#include <iostream>
#include <vector>
template<typename T64> constexpr T64 calcGCD(T64 a, T64 b)
{
return (a==0 && b!=0) ? b: a;
while(b)
{
T64 t = a % b;
b = a;
a = t;
}
return a;
}
template <typename Iterator> constexpr auto GCD(Iterator first, Iterator last)
{
auto itrFirst = first;
auto itrEnd = last;
int Size = std::distance(itrFirst,itrEnd);
int Result = 0;
if(Size >=2 )
{
int A = *itrFirst;
std::advance (itrFirst,1);
int B = *itrFirst;
Result = calcGCD(A,B);
std::advance (itrFirst,1);
for(int i = 2; i<Size; ++i)
{
A = *itrFirst;
Result = calcGCD(Result,A);
std::advance (itrFirst,1);
}
}
else return *itrFirst;
return Result;
}
namespace math
{
template <typename M, typename N>
constexpr auto GCD(const M& m, const N& n)
{ return calcGCD(m, n); }
template <typename M, typename ...Rest>
constexpr auto GCD(const M& first, const Rest&... rest)
{ return calcGCD(first, GCD(rest...)); }
}
int main()
{
std::vector<int> vec={1,2,58,54,102,2,37,13,8};
std::cout<<"GCD from Iterator Template : ";
for(unsigned int i=0; i<vec.size()-3; ++i)
std::cout<<GCD(vec.begin()+i, vec.begin()+i+4)<<" ";
std::cout<<std::endl;
std::cout<<"GCD from non-iterator Templates: ";
std::cout<<math::GCD(1,2,58,54)<<" ";
std::cout<<math::GCD(2,58,54,102)<<" ";
std::cout<<math::GCD(58,54,102,2)<<" ";
std::cout<<math::GCD(54,102,2,37)<<" ";
std::cout<<math::GCD(102,2,37,13)<<" ";
std::cout<<math::GCD(2,37,13,8)<<" ";
return 0;
}
它按预期提供了所需的输出。但是,我还没有测试任何其他情况。
输出:
GCD from Iterator Template : 1 2 58 54 102 2
GCD from non-iterator Templates: 1 2 58 54 102 2