本文是通过例子学习C++的第七篇,通过这个例子可以快速入门c++相关的语法。

1.问题描述

回顾一下约瑟夫环问题:n 个人围坐在一个圆桌周围,现在从第 s 个人开始报数,数到第 **m **个人,让他出局;然后从出局的下一个人重新开始报数,数到第 m 个人,再让他出局......,如此反复直到所有人全部出局为止。

上一篇我们通过数组、静态链表实现了约瑟夫环,具体参考:

通过例子进阶学习C++(六)你真的能写出约瑟夫环么

本文,我们进一步深入分析约瑟夫环问题,并通过c++模板库实现该问题求解,最后我们说明用模板库的优劣之处。

2.模板库项目搭建

本文我们用c++的模板库通过单向循环链表实现约瑟夫环问题,用c++模板库实现约瑟夫环。

首先我们在Visual Studio中“文件”--“新建”--”CMake项目“:

点击“下一步”:

点击“创建”,即可生成一个CMake的C++项目。

在解决方案上面,点击“右键”,“添加”--“新建文件夹”:

在文件夹中新建文件“circList.h”、“CMakeLists.txt”和“main.cpp”。

然后在整个项目的“CMakeLists.txt"中增加如下内容:

3.C++模板库通过循环链表实现约瑟夫环

用C++模板库实现约瑟夫环,主要包括这3个文件:“circList.h”、“CMakeLists.txt”和“main.cpp”。整个代码以《数据结构 用面向对象方法与c++语言描述》(第2版)上面的实现为基础。

用书本上面的例子,是无法直接运行的,耗费了一定的时间才修改好。

circList.h相关代码:

template<class T>
struct CircLinkNode {
T data;
CircLinkNode<T>* link;
CircLinkNode(CircLinkNode<T> *next = NULL):link(next){}
CircLinkNode(T d, CircLinkNode<T> *next = NULL):data(d),link(next){}
}; template<class T>
class CircList {
public:
CircList() {
first = last = NULL;
}
CircList(const T& x) {
first = new CircLinkNode<T>(x);
}
CircList(CircList<T>& L) {
T value;
CircLinkNode<T>* srcptr = L.getHead();
CircLinkNode<T>* destptr = first = new CircLinkNode<T>;
while (srcptr->link != NULL) {
value = srcptr->link->data;
destptr->link = new CircLinkNode<T>(value);
destptr = destptr->link;
srcptr = srcptr->link;
}
destptr->link = NULL;
}
~CircList() {
//makeEmpty();
}
void makeEmpty() {
CircLinkNode<T>* q;
while (first!=NULL && first->link != first) {
q = first->link;
first->link = q->link;
delete q;
}
}
int length() const {
CircLinkNode<T>* p = first->link;
int count = 0;
while (p != NULL) {
count++;
p = p->link;
}
return count;
}
CircLinkNode<T>* getHead()const {
return first;
}
void setHead(CircLinkNode<T>* p) {
first = p;
}
CircLinkNode<T>* Search(T x) {
CircLinkNode<T>* current = first->link;
while (current != first) {
if (current->data == x) break;
else current = current->link;
}
return current;
}
CircLinkNode<T>* Locate(int i) {
if (i < 0) return NULL;
CircLinkNode<T>* current = first;
int k = 0;
while (current->link != first && k < i) {
current = current->link;
k++;
}
return current;
}
T* getData(int i) {
if (i < 0) return NULL;
CircLinkNode<T>* current = Locate(i);
if (current == NULL) return NULL;
else return &current->data;
} void setData(int i, T& x) {
if (i < 0) return;
CircLinkNode<T>* current = Locate(i);
if (current == NULL) return;
else current->data = x;
} bool Insert(int i, T& x) {
CircLinkNode<T>* newNode = new CircLinkNode<T>(x);
if (newNode == NULL) {
cerr << "存储分配失败!" << endl;
exit(1);
} if (i == 1) {
first = last = newNode;
first->link = newNode;
}
else {
last->link = newNode;
last = newNode;
} newNode->link = first;
return true;
}
bool Remove(int i, CircLinkNode<T> * p, CircLinkNode<T>* pre) {
if (first == p) {
first = p->link;
}
if (last == p) {
last = pre;
}
delete p;
return true;
}
void output() {
CircLinkNode<T>* current = first->link;
cout << first->data << " "; while (current != last->link) {
cout << current->data <<" ";
current = current->link;
}
cout << endl;
}
private:
CircLinkNode<T>* first, * last;
};

CMakeLists.txt相关代码如下:

# CMakeList.txt: DataStructure 的 CMake 项目,在此处包括源代码并定义
# 项目特定的逻辑。
#
cmake_minimum_required (VERSION 3.8) # 将源代码添加到此项目的可执行文件。
add_executable (circList "main.cpp" "circList.h" ) # TODO: 如有需要,请添加测试并安装目标。

main.cpp相关代码如下:

#include<iostream>
#include "circList.h" using namespace std; template<class T>
void Josephus(CircList<T> &Js,int n,int m) {
CircLinkNode<T>* p = Js.getHead();
CircLinkNode<T>* pre = NULL; int i, j;
for (i = 0; i < n - 1; i++) {
for (j = 0; j < m-1; j++) {
pre = p;
p = p->link;
} cout << "出列的是:" << p->data << endl;
pre->link = p->link; Js.Remove(p->data,p,pre); p = pre->link; cout << "出列后的队列为:" << endl;
Js.output();
cout << "当前元素为:" << p->data << endl;
}
} int main() {
CircList<int> clist;
int i, n, m;
cout << "输入游戏者人数和报数间隔:"<<endl;
cin >> n >> m;
for (i = 1; i <= n; i++) {
clist.Insert(i,i);
} Josephus(clist, n, m);
}

程序运行后效果如下:

4.总结

本着Talk is cheap. Show me the code原则,代码实现不做过多解释。

通过该例子,可以学习:

  • 在Visual Studio中搭建CMake项目;
  • 在CMake项目中增加“可执行文件”;
  • 掌握struct定义;class定义;template class 、function定义;构造函数;析构函数;
  • 通过模板库实现约瑟夫环问题

本文从构思到完成,可谓是耗费了大量的心血。

如果您阅读本文后哪怕有一丢丢收获,请不要吝啬你手中关注点赞的权力,谢谢!

另外,如果需要相关代码,请留言,可以提供完整源代码

通过例子进阶学习C++(七)CMake项目通过模板库实现约瑟夫环的更多相关文章

  1. 通过例子进阶学习C++(五)计算2的1次方至2的64次方之和

    本文是通过例子学习C++的第五篇,通过这个例子可以快速入门c++相关的语法. 1.上篇回顾 在上一篇中,我们通过字符数组计算264次方: 通过例子进阶学习C++(四)计算2的64次方 带着这个问题:为 ...

  2. 通过例子进阶学习C++(六)你真的能写出约瑟夫环么

    本文是通过例子学习C++的第六篇,通过这个例子可以快速入门c++相关的语法. 1.问题描述 n 个人围坐在一个圆桌周围,现在从第 s 个人开始报数,数到第 m 个人,让他出局:然后从出局的下一个人重新 ...

  3. 我的QT5学习之路(三)——模板库、工具类和控件(下)

    一.前言 作为第三篇的最后一部分,我们来看一下Qt的控件,谈到控件,就会让人想到界面的美观性和易操作性,进而想到开发的便捷性.作为windows界面开发的MFC曾经是盛行了多少年,但是其弊端也随着其他 ...

  4. 通过例子进阶学习C++(四)计算2的64次方,不服写写看

    ​ 本文是通过例子学习C++的第四篇,通过这个例子可以快速入门c++相关的语法. 1.乍一看题目非常简单,简单思考一下,可以通过for循环实现: #include <iostream> u ...

  5. ruby -- 进阶学习(七)strong parameters之permitted.has_key

    简单例子: params = ActionController::Parameters.new(user: { name: 'Francesco', age: 22, role: 'admin' }) ...

  6. MYSQL进阶学习笔记七:MySQL触发器的创建,应用及管理!(视频序号:进阶_16,17)

    知识点八:MySQL触发器的应用(16,17) 触发器的定义: 什么是触发器: 触发器是一种特殊的存储过程,它在插入,删除或修改特定表中的数据是触发执行,他比数据库本身标准的功能有更精细和更复杂的数据 ...

  7. 爬虫技术 -- 进阶学习(七)简单爬虫抓取示例(附c#代码)

    这是我的第一个爬虫代码...算是一份测试版的代码.大牛大神别喷... 通过给定一个初始的地址startPiont然后对网页进行捕捉,然后通过正则表达式对网址进行匹配. List<string&g ...

  8. 陕西师范大学第七届程序设计竞赛网络同步赛D ZQ的睡前故事【约瑟夫环1-N数到第k个出队,输出出队顺序/ STL模拟】

    链接:https://www.nowcoder.com/acm/contest/121/D来源:牛客网 题目描述 ZQ是一个拥有n女朋友的万人迷,她的每一个女朋友每天晚上都会挨个给他打电话,要他讲了睡 ...

  9. STL学习系列一:STL(标准模板库)理论基础

    STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称.现然主要出现在C++中,但在被引入C++之前该技术就已经存在了很长的一段时间. STL的从广 ...

随机推荐

  1. LCA (最近公共祖先)倍增做法 —— O(nlogn)预处理 O(logn)(在线)查询

    pa[a][j] 表示 a 结点的 2^j倍祖先(j = 0时 为直接父亲,j = 1时为父亲的父亲……) 1.首先预处理出所有结点的深度值dep和父亲结点 void dfs(int u, int f ...

  2. 【React】react项目引入echarts插件 K线图

    参考npm文档:https://www.npmjs.com/package/echarts-for-react 由于npm上已经有针对react项目出的echarts插件,所以在这里直接安装 第一步: ...

  3. linux scull 代码read 方法

    read 的返回值由调用的应用程序解释: 如果这个值等于传递给 read 系统调用的 count 参数, 请求的字节数已经被传送. 这是最好的情况. 如果是正数, 但是小于 count, 只有部分数据 ...

  4. QQ三方登录

    申请了十天,最终通过了审核,能够上线了,事实上申请的第一天,站点的qq登录已经做好了,而且能够用測试帐号登录,但提交审核后,总是通只是,提示:您的站点审核未通过.原因是"未放置QQ登录but ...

  5. UVA 12563 "Jin Ge Jin Qu hao" (背包)

    传送门 debug了好一会,突然发现,输出错了,emmm......... 明天再写debug历程: (PS:ipad debug是真的繁琐) 题意: 题解: 尽管题干中给的 t 的范围很大,但是 t ...

  6. linux 位操作

    atomic_t 类型在进行整数算术时是不错的. 但是, 它无法工作的好, 当你需要以原子方 式操作单个位时. 为此, 内核提供了一套函数来原子地修改或测试单个位. 因为整个操作 在单步内发生, 没有 ...

  7. sci,ei,istp三大科技文献检索系统

    印刷版(SCI) 双月刊 ,500种 联机版(SciSearch) 周更新 ,600种 光盘版(带文摘)(SCICDE) 月更新 ,500种(同印刷版) 网络版(SCIExpanded) 周更新 ,6 ...

  8. html根据下拉框选中的值修改背景颜色

    错误的写法 <!doctype html><html><head><meta charset="utf-8"><title&g ...

  9. 树莓派4安装ftp服务端

    vsftpd是开源的轻量级的常用ftp服务器.   1,安装vsftpd服务器 (约400KB) sudo apt-get install vsftpd     2,启动ftp服务 sudo serv ...

  10. Visual Studio插件【一】:前端

    JQuery Code Snippets https://github.com/kspearrin/Visual-Studio-jQuery-Code-Snippets 简单用法 jq   +tab ...