C++ 使用静态变量的递归函数

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

所以这个函数似乎需要使用静态函数,我意识到的问题是,在递归函数结束之前,没有办法重置静态变量。有没有一种我没有看到的方法,或者有没有一种不使用静态变量的好方法

这个函数的目标是首先用奇数变量填充数组,因此假设您将其称为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 (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)
{

如果(sizeif
size
为奇数,则写入第一个元素。如果为偶数,则写入最后一个元素。在任何一种情况下,递归“聚焦”剩余子数组:

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