我制定了一个可以递归使用的算法,它以非递归方式工作,但是,我不能以递归形式测试它,因为我无法从模板中创建一个n-1维变量。
为了帮助我写下变量名称及其含义:
v
:n维向量dims
:n具有每个维度的长向量(例如:如果它是一个类似int x[3][6][4]
的数组,那么dims
看起来像:{3,6,4})p
:尺寸的乘积,用于得到平面矢量的大小(例如:3 * 6 * 4)ret
:返回的平面向量sub_dims
:与没有第一个维度的dims
execpt相同(例如:{6,4})sub_p
:与p
相同,但没有第一个因素(例如:6 * 4)sub_ret
:n-1维向量的返回平面向量代码:
template <typename T>
vector<int> dim_flat(vector<T> v, vector<int> dims)
{
// creating variables and vectors
int n = dims.size();
int p = dims[0];
for (int i = 1; i < n; i++)
{
p *= dims[i];
}
int sub_p = p / dims[0];
vector<int> sub_dims;
sub_dims.assign(dims.begin() + 1, dims.end());
vector<int> ret(p);
// algorithm
if (n > 1)
{
for (int i = 0; i < dims[0]; i++)
{
vector<int> sub_ret = dim_flat(v[i], sub_dims);
for (int j = 0; j < sub_p; j++)
{
ret[i * sub_p + j] = sub_ret[j];
}
}
}
else
{
// case for the input is 1D
// not yet written
}
return ret;
}
使用此代码构建项目,但是如果我在main中调用它:
vector<int> ret = dim_flat(v, dims);
其中v
例如是4D向量和dims
是包含{3,3,3,3}的向量,然后在尝试构建时得到以下内容:
error C2784: 'std::vector<_Ty> dim_flat(std::vector<T>,std::vector<_Ty>)' : could not deduce template argument for 'std::vector<T>' from 'int'
为行
vector<int> sub_ret = dim_flat(v[i], sub_dims);
我有点(但不是真的)理解这个错误的意思,所以我期望同样的事情发生,它为此做了:
T x = v[i];
vector<int> sub_ret = dim_flat(x, sub_dims);
这是我不再理解错误的部分,因为我认为使用参数vector<T> v
我指定了输入,例如4D向量将被理解为T
的向量,其中T
是3D向量,由于其vector<T>
,因此也可以被索引。所以遵循这个逻辑,我认为如果我给递归第一个T
是一个3D向量,那么这个3D向量的深度现在将被理解为T'
的向量,其中T'
是2D矢量,依此类推。
显然,我的逻辑存在缺陷,或者我使用了错误的方法(或两者兼而有之),所以问题是:我该如何解决/解决这个问题?
编辑:
对于解决方案,请归功于Max66
代码可能可以更优化,但至少现在它可以工作
代码:
//// for integer only
// case input is 0-dimensional (simply a variable)
template <typename T>
vector<int> dim_flat (const T &v, const vector<int> &dims)
{
return vector<int>(1, v);
}
// case input is n-dimensional
template <typename T>
vector<int> dim_flat(const vector<T> &v, const vector<int> &dims)
{
// creating variables and vectors
int n = dims.size();
int p = dims[0];
for (int i = 1; i < n; i++)
{
p *= dims[i];
}
int sub_p = p / dims[0];
vector<int> sub_dims;
sub_dims.assign(dims.begin() + 1, dims.end());
vector<int> ret(p);
// algorithm
if (n > 1) // case n-dimensional
{
for (int i = 0; i < dims[0]; i++)
{
vector<int> sub_ret = dim_flat(v[i], sub_dims);
for (int j = 0; j < sub_p; j++)
{
ret[i * sub_p + j] = sub_ret[j];
}
}
}
else // case 1-dimensional
{
for (int i = 0; i < p; i++)
{
vector<int> sub_ret = dim_flat(v[i], sub_dims);
ret[i] = sub_ret[0];
}
}
return ret;
}
答案 0 :(得分:0)
简答:添加功能
std::vector<int> dim_flat (int v, std::vector<int> const &)
{ return {v}; }
如果您可以使用C ++ 11或更高版本,或
std::vector<int> dim_flat (int v, std::vector<int> const &)
{ return std::vector<int>(1, v); }
如果你必须使用C ++ 98
答案很长:如果我没错,问题在于,当您使用dim_flat()
致电std::vector<int>
时(T
为int
时),您有n == 1
,因此dim_flat()
未被调用(执行“输入1D的情况”)但是编译器不是那么聪明,没有必要要使用dim_flat()
(而不是int
)致电std::vector<T>
,请查找dim_flat(int, std::vector<int>)
但找不到。
因此,为了使编译器满意,您必须实现dim_flat(int, std::vector<int>)
。
可以是虚函数(返回空向量),但我建议你正确实现它。
一些话题:请避免使用无用的载体副本;在dim_flat()
中,v
和dims
仅被加入,未被修改;所以你可以接收它们作为const引用,如下所示
template <typename T>
std::vector<int> dim_flat(std::vector<T> const & v,
std::vector<int> const & dims)
P.s。:为什么不简单地写如下?
std::vector<int> dim_flat (std::vector<int> const & v)
{ return v; }
template <typename T>
std::vector<int> dim_flat(std::vector<std::vector<T>> const & v)
{
std::vector<int> ret;
for ( auto const & e : v )
{
auto s = dim_flat(e);
ret.reserve( ret.size() + s.size() );
ret.insert( ret.end(), s.cbegin(), s.cend() );
}
return ret;
}