【问题标题】:How to restructure this code without duplicating too much code?如何在不复制太多代码的情况下重构此代码?
【发布时间】:2021-08-18 21:14:06
【问题描述】:
class
{
public:
  void func(const int val, const bool flag)
  {
    if(flag)
    {
      while(!lower.empty() && val <= lower.top())
      {
        // do a bunch of stuff with lower
      }
    }
    else
    {
      while(!higher.empty() && val >= higher.top())
      {
        // do a bunch of stuff with higher, but it's the same stuff as would've done
        // for lower
      }
    }
  }
private:
  std::stack<int> lower;
  std::stack<int> higher;
}

我正在尝试找出一种更好的方法来编写子句,因为目前我在这两个子句中都有很多重复的代码。唯一的区别是一个子句在lower 上运行,另一个在higher 上运行,第一个子句中的&lt;= 在第二个子句中更改为&gt;= higher。

我可以将子句包装在一个辅助函数中并在每个子句中调用它(并将lower 和higher 作为参数传入),例如,

class
{
public:
  void func(const int val, const bool flag)
  {
    if(flag)
    {
      helper(lower, comparer);
    }
    else
    {
      helper(lower, comparer);
    }
  }

  void helper(std::stack<int> &st)
  {
    // do a bunch of stuff with st
  }
  
private:
  std::stack<int> lower;
  std::stack<int> higher;
}

我不确定这是否是个好主意,如果是,我不确定如何绕过&gt;= 与&lt;=。希望大家对我的设计提出建议!

【问题讨论】:

  • 提取一个获取栈的方法?
  • @DaveNewton 你能详细说明这意味着什么吗?是不是像我在第二个sn-p中描述的辅助函数?
  • 这应该没问题;事实上,它经常在标准库中完成。通常,您将参数设为模板参数。不确定这是否是计划,因为辅助函数目前只接受一个参数。 template&lt;typename ComparerType&gt; void Helper(std::stack&lt;int&gt;&amp; st, int val, ComparerType compare) { while(!st.empty() &amp;&amp; compare(val, st.top()) { ... } }Helper(lower, val, [](int a, int b) { return a &lt;= b; });
  • @fabian 代替 lambdas,可以使用std::less_equal 和std::greater_equal,例如:Helper(lower, val, std::less_equal{}); Helper(higher, val, std::greater_equal{});
  • @RemyLebeau 啊,我现在明白了。该注释中的Helper(lower, val, [](int a, int b) { return a &lt;= b; }) 部分实际上是显示函数的调用方式。

标签: c++ algorithm oop


【解决方案1】:

您可以执行以下操作:

class
{
public:
  void func(const int val, const bool flag)
  {
    std::stack<int> *st;
    bool (*compare)(int, int);

    if (flag)
    {
      st = &lower;
      compare = [](int a, int b){ return a <= b; };
    }
    else
    {
      st = &higher;
      compare = [](int a, int b){ return a >= b; };
    }

    while (!st->empty() && compare(val, st->top()))
    {
      // do a bunch of stuff with *st
    }
  }

private:
  std::stack<int> lower;
  std::stack<int> higher;
}

另外,使用助手当然也可以:

class
{
public:
  void func(const int val, const bool flag)
  {
    if (flag)
      func_helper(lower, val, std::less_equal{});
    else
      func_helper(higher, val, std::greater_equal{});
  }

private:
  std::stack<int> lower;
  std::stack<int> higher;

  template<typename Comparer>
  void func_helper(stack<int> &st, const int val, Comparer compare)
  {
    while (!st.empty() && compare(val, st.top()))
    {
      // do a bunch of stuff with st
    }
  }
}

【讨论】:

    【解决方案2】:

    这样的事情怎么样

    class
    {
    public:
      void func(const int val, const bool flag)
      {
        int sign = 1;
        std::stack<int>* higher_or_lower = &higher; 
        if(flag)
        {
          higher_or_lower = &lower;
          sign = -1;
        }
    
        while(!higher_or_lower->empty() && sign*val >= sign*higher_or_lower->top())
        {
          // do a bunch of stuff with higher_or_lower
        }
      }
      
    private:
      std::stack<int> lower;
      std::stack<int> higher;
    }
    

    higher_or_lower 涵盖两个堆栈,sign 负责处理小于与大于。

    【讨论】:

    • 这个标志的想法很有趣,但我想也许它对某人来说不太清楚?当然更短!
    【解决方案3】:

    或者更紧凑一点:

    class C
    {
    public:
        void func(const int val, const bool flag)
        {
            const std::stack<int>* st[] = {&lower, &higher};
            bool (*compare[])(int, int) = { [](int a, int b) { return a <= b; } ,  [](int a, int b) { return a >= b; } };
    
            while (!st[flag]->empty() && compare[flag](val, st[flag]->top()))
            {
                // do a bunch of stuff with *st
            }
        }
    
    private:
        std::stack<int> lower;
        std::stack<int> higher;
    };
    

    【讨论】:

      猜你喜欢
      • 2016-04-02
      • 1970-01-01
      • 1970-01-01
      • 2010-12-31
      • 2018-05-26
      • 1970-01-01
      • 1970-01-01
      • 2021-09-11
      • 1970-01-01
      相关资源
      最近更新 更多