C++ 使用静态变量的递归函数
所以这个函数似乎需要使用静态函数,我意识到的问题是,在递归函数结束之前,没有办法重置静态变量。有没有一种我没有看到的方法,或者有没有一种不使用静态变量的好方法 这个函数的目标是首先用奇数变量填充数组,因此假设您将其称为fillAryOddFirst(ary,13),那么数组将按照以下顺序填充 [13,11,9,7,5,3,1,2,4,6,8,12]C++ 使用静态变量的递归函数,c++,function,recursion,static,C++,Function,Recursion,Static,所以这个函数似乎需要使用静态函数,我意识到的问题是,在递归函数结束之前,没有办法重置静态变量。有没有一种我没有看到的方法,或者有没有一种不使用静态变量的好方法 这个函数的目标是首先用奇数变量填充数组,因此假设您将其称为fillAryOddFirst(ary,13),那么数组将按照以下顺序填充 [13,11,9,7,5,3,1,2,4,6,8,12] void fillAryOddFirst(int ary[], int size) { static int pos; if (si
void fillAryOddFirst(int ary[], int size) {
static int pos;
if (size <= 0) {
return;
}
if(size % 2 != 0){
ary[pos] = size;
pos++;
}
fillAryOddFirst(ary, size-1);
if(size % 2 == 0 ){
ary[pos] = size;
pos++;
}
return;
}
void fillAryOddFirst(int-ary[],int-size){
静态int-pos;
如果(sizeNo,则无法重置本地静态
变量
如果您希望能够重置它,您唯一的选择是将其设置为全局变量,即将其声明移到函数之外
另一种可能性是将其作为通过引用传递的参数:
void fillAryOddFirst(int ary[], int size, int &pos)
{
if (size <= 0)
{
return;
}
if (size % 2 != 0)
{
ary[pos] = size;
pos++;
}
fillAryOddFirst(ary, size - 1, pos);
if(size % 2 == 0 )
{
ary[pos] = size;
pos++;
}
}
void fillAryOddFirst(int ary[], int size)
{
int pos = 0;
fillAryOddFirst(ary, size, pos);
}
void fillAryOddFirst(int-ary[],int-size,int&pos)
{
如果(sizeifsize
为奇数,则写入第一个元素。如果为偶数,则写入最后一个元素。在任何一种情况下,递归“聚焦”剩余子数组:
void fillAryOddFirst(int ary[], int size) {
if(size > 0) {
if(size % 2 == 1) {
// +---+---|...|---+
// | s | ? |???| ? |
// +---+---|...|---+
// ^ ary ^ ary + size
// ^ ary + 1 ^ (ary + 1) + (size - 1)
// \-----------/ focus on this range
ary[0] = size;
fillAryOddFirst(ary + 1, size - 1);
} else /*if(size % 2 == 0)*/ {
// +---|...|---+---+
// | ? |???| ? | s |
// +---|...|---+---+
// ^ ary ^ ary + size
// | ^ ary + (size - 1)
// \-----------/ focus on this range
ary[size - 1] = size;
fillAryOddFirst(ary, size - 1);
}
}
}
以循环的形式编写,这将是
void fillAryOddFirst(int ary[], int size) {
for(; size > 0; size--) {
if(size % 2 == 1) *ary++ = size;
else ary[size - 1] = size;
}
}
也就是说,您正在迭代size
到1
,并将赔率放在开头,将偶数放在结尾
“…是否有一种不使用静态变量的好方法。”
是的。将函数包装在类中
在类中,“static int pos”函数变量可以成为包装器的简单数据属性
下面是几个代码示例
1) 第一是证明你的问题是可重复的
2) 一个名为class FillAryOddFirstClass_t的简单类包装器。该函数与原始函数非常相似,但pos不是静态的
3) 一个简单的函子包装器,称为类FillAryOddFirstFunctor\u t。函子有一个更简单的调用
< P> 4)因为您已经将此帖子声明为C++问题,所以项目4使用向量而不是数组——但是注意,代码使用相同的类来运行递归,作为项目2,FiLyRoordOrdFistCaseLtt,它期望数组!矢量数据驻留在动态内存中,并指定“& IVEC(0)”(而不是一元)。,传递的地址是堆中矢量数据的起始元素
5) 这是带有附加项的第2项。类FillAryOddFirstClass2\t内部由2个报表函数构成。报表函数生成字符串以显示递归/解递归执行的进度
你到底想做什么?有各种各样的方法来解决这个问题-大多数都不需要递归或静态变量。问题的约束条件是什么?很遗憾,对于学校作业来说,我必须递归地解决这个问题。除了递归,问题的约束条件是什么?你需要我们吗e那个静态变量?你能给函数传递更多的参数吗?不,这个静态变量不是必需的。唯一的限制是用数字1填充数组,奇数先是从大到小,然后是从小到大,当然这必须递归完成。”…有没有一种不使用静态变量的好方法?“-是。”pos"可以成为这个递归函数的类包装器的数据属性。我真的回到这里是想说,我是按照你刚才发布lol的方式计算出来的。谢谢你!我觉得应该也有一种方法来传递值,但是既然你已经有了这个很好的答案,我就不想再计算了W
#include <iostream>
using std::cout, std::endl; // c++17
#include <iomanip>
using std::setw;
#include <string>
using std::string, std::to_string;
#include <vector>
using std::vector;
// original - with static
void fillAryOddFirst ( int ary[], int size )
{
static int pos; // <<<<<<<<<<<<<<< static
if (size <= 0) { return; }
if(size % 2 != 0) { ary[pos] = size; pos++; }
fillAryOddFirst(ary, size-1);
if(size % 2 == 0 ) { ary[pos] = size; pos++; }
return;
}
// class wrapper
class FillAryOddFirstClass_t // UDT - user defined type
{
int pos; // <<<<<<<<<<<<<<< not static, a simple attribute
public:
FillAryOddFirstClass_t() : pos (0) { }
~FillAryOddFirstClass_t() = default;
void fillAryOddFirst ( int ary[], int indx )
{
if (indx <= 0) { return; }
if(indx % 2 != 0) { ary[pos] = indx; pos++; }
fillAryOddFirst(ary, indx-1);
if(indx % 2 == 0 ) { ary[pos] = indx; pos++; }
return;
}
};
// Functor wrapper
class FillAryOddFirstFunctor_t // UDT (user defined type)
{
int pos; // <<<<<<<<<<<<<<< not static
public:
// default ctor and dtor do nothing, cost nothing
void operator()( int ary[], int indx) // functor entry
{
pos = 0; // init
fillAryOddFirst(ary, indx);
return;
}
private:
void fillAryOddFirst( int ary[], int indx)
{
if (indx <= 0) { return; }
if(indx % 2 != 0) { ary[pos] = indx; pos++; }
fillAryOddFirst(ary, indx-1);
if(indx % 2 == 0 ) { ary[pos] = indx; pos++; }
return;
}
};
// class wrapper, with cout progress indicator
class FillAryOddFirstClass2_t // UDT
{
int pos; // <<<<<<<<<<<<<<< no static
size_t sz = 10;
public:
FillAryOddFirstClass2_t() : pos (0) { }
~FillAryOddFirstClass2_t() = default;
void fillAryOddFirst ( size_t rLvl, int ary[], int indx )
{
if (indx <= 0) {
cout << "\n\n" << setw(11) << " " << "recurse end - decurse begins\n";
return;
}
if(indx % 2 != 0) { ary[pos] = indx; pos++; }
cout << rprtR (rLvl, ary); // recurse report
fillAryOddFirst (rLvl+1, ary, indx-1);
cout << rprtD (rLvl, ary); // decurse report
if(indx % 2 == 0 ) { ary[pos] = indx; pos++; }
return;
}
// report recurse
string rprtR ( size_t rLvl, int ary[])
{
std::stringstream ssOut;
ssOut << "\n " << setw(4) << rLvl
<< " " << show(ary) << ' ';
return ssOut.str();
}
// report decurse
string rprtD ( size_t rLvl, int ary[])
{
std::stringstream ssOut;
ssOut << "\n " << setw(4) << rLvl
<< " " << show(ary) << '_';
return ssOut.str();
}
string show(int ary[])
{
std::stringstream ssOut;
for (uint i=0; i<(sz-1); ++i)
if (ary[i])
ssOut << " " << ary[i];
return ssOut.str();
}
}; // class FillAryOddFirstClass2_t
int main()
{
const size_t sz = 9;
{
cout << "\n\n Test1: original (function with static int pos) \n";
int ary[sz]; // automatic memory array
init(&ary[0], sz); // function to fill ary with 0's
show(&ary[0], sz);
// this function uses static int pos
fillAryOddFirst (&ary[0], sz);
show(&ary[0], sz);
}
{
cout << "\n\n Test2: class wrapper (no static)\n";
int ary[sz];
init(&ary[0], sz);
show(&ary[0], sz);
{
FillAryOddFirstClass_t faofObj;
faofObj.fillAryOddFirst(&ary[0], sz);
}
show(&ary[0], sz);
}
{
cout << "\n\n Test3: Functor Wrapper (no static)\n";
int ary[sz]; init(&ary[0], sz);
show(&ary[0], sz);
// no static int pos
FillAryOddFirstFunctor_t()(&ary[0], sz);
show(&ary[0], sz);
}
{
cout << "\n\n Test4: class, uses vector, not array (no static)\n";
vector<int> iVec;
for (uint i=0; i<sz; ++i) iVec.push_back(0); // vector grows
show(&iVec[0], sz);
{
FillAryOddFirstClass_t faof;
faof.fillAryOddFirst(&iVec[0], sz);
}
show(&iVec[0], sz);
}
{
cout << "\n\n Test5: class2 (no static) with graphic\n";
vector<int> iVec;
for (uint i=0; i<sz; ++i) iVec.push_back(0); // vector grows
show(&iVec[0], sz);
{
cout << "\n rlvl";
FillAryOddFirstClass2_t faof2;
faof2.fillAryOddFirst(1, &iVec[0], sz);
cout << "\n rlvl";
}
cout << "\n\n ";
show(&iVec[0], sz);
}
cout << endl;
return 0;
}
Test1: original (function with static int pos)
0 0 0 0 0 0 0 0 0
9 7 5 3 1 2 4 6 8
Test2: class wrapper (no static)
0 0 0 0 0 0 0 0 0
9 7 5 3 1 2 4 6 8
Test3: Functor Wrapper (no static)
0 0 0 0 0 0 0 0 0
9 7 5 3 1 2 4 6 8
Test4: class, uses vector, not array (no static)
0 0 0 0 0 0 0 0 0
9 7 5 3 1 2 4 6 8
Test5: class2 (no static) with graphic
0 0 0 0 0 0 0 0 0
rlvl
1 9
2 9
3 9 7
4 9 7
5 9 7 5
6 9 7 5
7 9 7 5 3
8 9 7 5 3
9 9 7 5 3 1
recurse end - decurse begins
9 9 7 5 3 1_
8 9 7 5 3 1_
7 9 7 5 3 1 2_
6 9 7 5 3 1 2_
5 9 7 5 3 1 2 4_
4 9 7 5 3 1 2 4_
3 9 7 5 3 1 2 4 6_
2 9 7 5 3 1 2 4 6_
1 9 7 5 3 1 2 4 6 8_
rlvl
9 7 5 3 1 2 4 6 8