使用C++实现Range序列生成器

举报
王瑞专家 发表于 2023/11/07 09:34:55 2023/11/07
【摘要】 在C++编程中,经常需要迭代一系列数字或其他可迭代对象。通常,这需要编写复杂的循环结构,但有一种精妙的方法可以使这一过程变得更加简单和可读。如果你使用过Python语言那么一定对Range语句非常的数据,我们可以使用C++来实现一个简单的Range封装,如下代码定义了一个名为Range的命名空间,其中包含一个RangeImpl类和相关的函数,用于生成指定范围内的数值序列。这序列生成器支持指定...

在C++编程中,经常需要迭代一系列数字或其他可迭代对象。通常,这需要编写复杂的循环结构,但有一种精妙的方法可以使这一过程变得更加简单和可读。如果你使用过Python语言那么一定对Range语句非常的数据,我们可以使用C++来实现一个简单的Range封装,如下代码定义了一个名为Range的命名空间,其中包含一个RangeImpl类和相关的函数,用于生成指定范围内的数值序列。这序列生成器支持指定开始值、结束值和可选步长,确保生成的序列满足指定的条件。此代码简化了迭代数值序列的过程,提高了代码的可读性和可维护性,适用于处理不同数据类型的序列。

首先读者需要新建一个Range.hpp头文件,并包含这个生成器代码。

namespace Range
{
  template<typename value_t>
  class RangeImpl
  {
    class Iterator;
  public:
    RangeImpl(value_t begin, value_t end, value_t step = 1) :m_begin(begin), m_end(end), m_step(step)
    {
      if (step>0 && m_begin >= m_end)
        throw std::logic_error("end must greater than begin.");
      else if (step<0 && m_begin <= m_end)
        throw std::logic_error("end must less than begin.");

      m_step_end = (m_end - m_begin) / m_step;
      if (m_begin + m_step_end*m_step != m_end)
      {
        m_step_end++;
      }
    }

    Iterator begin()
    {
      return Iterator(0, *this);
    }

    Iterator end()
    {
      return Iterator(m_step_end, *this);
    }

    value_t operator[](int s)
    {
      return m_begin + s*m_step;
    }

    int size()
    {
      return m_step_end;
    }

  private:
    value_t m_begin;
    value_t m_end;
    value_t m_step;
    int m_step_end;

    class Iterator
    {
    public:
      Iterator(int start, RangeImpl& range) : m_current_step(start), m_range(range)
      {
        m_current_value = m_range.m_begin + m_current_step*m_range.m_step;
      }

      value_t operator*() { return m_current_value; }

      const Iterator* operator++()
      {
        m_current_value += m_range.m_step;
        m_current_step++;
        return this;
      }

      bool operator==(const Iterator& other)
      {
        return m_current_step == other.m_current_step;
      }

      bool operator!=(const Iterator& other)
      {
        return m_current_step != other.m_current_step;
      }

      const Iterator* operator--()
      {
        m_current_value -= m_range.m_step;
        m_current_step--;
        return this;
      }

    private:
      value_t m_current_value;
      int m_current_step;
      RangeImpl& m_range;
    };
  };

  template<typename T, typename V>
  auto Range(T begin, T end, V stepsize)->RangeImpl<decltype(begin + end + stepsize)>
  {
    return RangeImpl<decltype(begin + end + stepsize)>(begin, end, stepsize);
  }

  template<typename T>
  RangeImpl<T> Range(T begin, T end)
  {
    return RangeImpl<T>(begin, end, 1);
  }

  template<typename T>
  RangeImpl<T> Range(T end)
  {
    return RangeImpl<T>(T(), end, 1);
  }
}

当需要使用这个特殊的语句时,只需要直接引入到项目中,如下代码所示展示了如何在不同的情况下创建和迭代不同类型的数值序列,包括整数、浮点数和字符序列。以下是对每个循环的简要描述:

  • 第一个循环使用Range::Range(15)创建一个整数序列,范围从0到14。
  • 第二个循环使用Range::Range(2, 6)创建一个整数序列,范围从2到5。
  • 第三个循环使用Range::Range(10.5, 15.5)创建一个浮点数序列,范围从10.5到15.5。
  • 第四个循环使用Range::Range(35, 27, -1)创建一个递减的整数序列,范围从35到27。
  • 第五个循环使用Range::Range(2, 8, 0.5)创建一个浮点数序列,范围从2到8,步长为0.5。
  • 第六个循环使用Range::Range(8, 7, -0.1)创建一个浮点数序列,范围从8到7,步长为-0.1。
  • 最后一个循循环使用Range::Range(‘a’, ‘z’)创建一个字符序列,范围从’a’到’z’。

这个示例程序演示了如何使用 Range 序列生成器轻松生成不同类型的序列,无需编写复杂的循环结构,从而简化了代码编写过程。每个循环迭代并输出相应的序列元素,使读者能够更轻松地处理不同类型的数据。

#include <iostream>
#include "Range.hpp"

using namespace std;

int main(int argc, char* argv[])
{
  for (int i : Range::Range(15))
  {
    std::cout << i << std::endl;
  }

  for (int i : Range::Range(2, 6))
  {
    std::cout << i << std::endl;
  }

  for (float i : Range::Range(10.5, 15.5))
  {
    std::cout << i << std::endl;
  }

  for (int i : Range::Range(35, 27, -1))
  {
    std::cout << i << std::endl;
  }

  for (float i : Range::Range(2, 8, 0.5))
  {
    std::cout << i << std::endl;
  }

  for (auto i : Range::Range(8, 7, -0.1))
  {
    std::cout << i << std::endl;
  }

  for (auto i : Range::Range('a', 'z'))
  {
    std::cout << i << std::endl;
  }
  
  std::system("pause");
  return 0;
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。