前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >编程轻松炫技:不费吹灰之力打印100个数字,面试考点应有尽有

编程轻松炫技:不费吹灰之力打印100个数字,面试考点应有尽有

作者头像
公众号guangcity
发布2024-01-10 16:19:05
1010
发布2024-01-10 16:19:05
举报
文章被收录于专栏:光城(guangcity)光城(guangcity)

给大家设定一个条件:不使用循环,请打印出1-100个数字

如果使用循环很简单了,那么你能想到多少种方法呢?

今天来给大家用一些C++的骚操作来写出这种代码,欢迎留言与转发~

这道题目其实非常简单,但却涵盖了很多面试考点,其中包括:

  • 模版特化、便特化,如何编写递归模版
  • CRTP
  • std::copy、std::iota、std::transform如何使用,各自算法实现
  • 类静态变量
  • 等等

1.递归

1-100可以拆为554,用三个函数去打印它,函数a cout一次,然后变量加1,函数b层层嵌套a重复5次,函数c层层嵌套b重复5次,最后在main函数中对c层层嵌套4次。

代码语言:javascript
复制
#include <iostream>

int a(int n) {
  std::cout << n++ << std::endl;
  return n;
}

int b(int n) { return a(a(a(a(a(n))))); }

int c(int n) { return b(b(b(b(b(n))))); }

int main() {
  c(c(c(c(1))));
  return 0;
}

2.模版重载

使用模版与特化来处理,当迭代100时只输出100,否则输出I,并且+1递归处理。

代码语言:javascript
复制
#include <iostream>
template <int I>
struct JustPrint : public JustPrint<I + 1> {
  JustPrint() : JustPrint<I + 1>() { std::cout << I << " "; }
};

template <>
struct JustPrint<100> {
  JustPrint<100>() { std::cout << 1 << " "; }
};

int main() { JustPrint<1> j; }

3.CRTP

方式3基于方式2,将其改造为crtp编程风格,是不是有点看不懂了,嘿嘿。

下面struct可以被替换为class,这里我用类来描述。其实就是两个类,第一个类Print为父类,打印每次的I,并调用子类,子类PrintDerived即成Print,并将自己传递给父类,子类是一个重载类,控制递归终止。

代码语言:javascript
复制
#include <iostream>

template <typename Derived, int I>
struct Print {
  Print() {
    std::cout << I << " ";
    Derived::next();
  }
};

template <int I>
struct PrintDerived : public Print<PrintDerived<I>, I> {
  static void next() { PrintDerived<I + 1>(); }
};
template <>
struct PrintDerived<100> : public Print<PrintDerived<100>, 100> {
  static void next() {}
};

int main() {
  PrintDerived<1> j;
  return 0;
}

4.类静态变量

创建一个Test数组,元素为100个,静态变量每次累加。

代码语言:javascript
复制
#include <iostream>
using namespace std;

class Test {
  static int i;

 public:
  Test() { cout << ++i << endl; }
};
int Test::i;
int main() {
  Test a[100];
  return 0;
}

5.使用算法库

使用std::for_each简单粗暴。

代码语言:javascript
复制
int main() {
  std::vector<int> l(100);
  std::iota(l.begin(), l.end(), 1);
  std::for_each(l.begin(), l.end(), [](int& n) { std::cout << n << std::endl; });
  return 0;
}

6.C++20 ranges

使用C++20的std::views,在std::copy时打印。

代码语言:javascript
复制
#include <iostream>
#include <iterator>
#include <ranges>
int main() {
  auto numbers = std::views::iota(1, 100 + 1);
  std::copy(numbers.begin(), numbers.end(), std::ostream_iterator<int>(std::cout, "\n"));
}

这个方式继续改造,还有一种实现,使用std::transform。

代码语言:javascript
复制
auto range = std::views::transform(std::ranges::iota_view{1, 101}, [](const auto& x) {
  std::cout << x << std::endl;
  return x;
});
std::vector<int> a(range.begin(), range.end());
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-01-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 光城 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.递归
  • 2.模版重载
  • 3.CRTP
  • 4.类静态变量
  • 5.使用算法库
  • 6.C++20 ranges
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档