约瑟夫环问题(C++)

问题描述

首先,说明一下这个问题是研究生期间c++课的综合作业,本来有好多选择但最后还是选择了约瑟夫环问题。下面是约瑟夫环的问题描述以及设计要求:
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
要求实现下面功能:

1.要求在实现约瑟夫环的同时,应该满足以下要求:
2.完整的图形用户界面,可以配置程序的运行参数,如:n的值,k的值、m的值、执行动画的速度等;
3.算法支持多线程;
4.执行过程可以暂停/继续;
5.算法执行的结果(包括中间结果)可以持久化(以自定义数据格式保存到文件中;
6.可从文件中读取数据,并在此基础上继续执行;
7.实时图形化显示执行结果;
8.可在执行完成后,或暂停时,打印执行的当前结果。

设计思路

在不考虑实现上面8个功能的前提下,我们应该实现下面一个简单的约瑟夫环问题:
在基于控制台程序情况下,对给定的n,k,m,输出报数的序列。然后将程序移植到基于mfc的程序当中,将功能分为几大块,最后组合到一起。具体源代码已经上传。

约瑟夫问题

约瑟夫环问题看做一个不断变小的环的数据提取:
以n=4,k=1,m=2为例:

这样我们将每次取下来的数存放在一个容器中[2,4,3,1],然后在显示程序中,逐个放进去:

这样就完成了约瑟夫环问题。程序流程如下:

用户界面设计

通过创建MFC AppWizard 基于对话框工程HOMEWORK2,自动生成HOMEWORK2App以及HOMEWORK2Dlg两类,在资源视图中手动画出下面两个界面:
一个用于初始化,用户可以配置程序的运行参数,如:n的值,k的值、m的值、执行动画的速度。另一个用于显示算法执行的过程。
在这里插入图片描述在这里插入图片描述并修改它们的属性ID值分别为:IDD_HOMEWORK2_DIALOG,IDD_DIALOGSHOW。
通过类向导将对话框IDD_DIALOGSHOW与类CDialogShow关联。接下来将两个界面上的所有组件修改属性ID,以及添加相应的消息映射函数。

自定义控件

执行的结果不是直接画在IDD_DIALOGSHOW上的,而是在IDD_DIALOGSHOW添加一个静态文本(IDC_STATICTU),并添加变量,变量类型为CMystatic类,这里需要自己在类视图中自己添加(基类选择CStatic),并重载OnPaint()函数:
在这里插入图片描述其中OnPaint()用于初始化显示界面,即是在IDC_STATICTU中画一个圆桌(用圆表示),m个人(用空白方框表示),并创建线程用于算法执行。

创建线程函数

将约瑟夫环算法嵌入到线程函数中,可以实现在点击开始按钮后,创建IDD_DIALOGSHOW对话框的同时,初始化IDC_STATICTU,然后创建一个线程(因为在OnPaint()中添加了创建线程m_ThreadSpeed的语句),这样就开始了约瑟夫环算法。最后通过线程的挂起、唤醒、终结实现执行过程的暂停/继续,以及终结。对于控制动画的显示速度则是通过Sleep()函数来控制。为了方便将线程函数,显示程序定义为CMystatic的成员函数。

实现打印

通过mfc里面已有的打印对话框类CPringDialog类实现对当前执行结果的打印功能。通过在类视图中添加类CMyPrintDialog类(基类为CPringDialog类)。最后在IDD_DIALOGSHOW中终结按钮的消息映射函数中写入打印程序。

// 创建一个打印机设备句柄 
if((hdcprint=CreateDC(szDriver,szDevice,szOutput,NULL))!=0) {
	if(StartDoc(hdcprint,&di)>0) {//开始执行一个打印作业
		StartPage(hdcprint); //打印机走纸,开始打印
		SaveDC(hdcprint); //保存打印机设备句柄
		// 打印当前的结果,将list1里面的结果以字符串的形式打印出来
		TextOut(hdcprint,1000,800,"约瑟夫环打印结果为:",20);
		CString str;
		for(vector<int>::iterator it = list1.begin();it!=list1.end();it++){
			CString temp;
			temp.Format("%d",*it);
			str += "-->";
			str += temp;
		}
	}
	TextOut(hdcprint,1000,1000,str,str.GetLength()); 
	RestoreDC(hdcprint,-1); //恢复打印机设备句柄
	EndPage(hdcprint); //打印机停纸,停止打印
	EndDoc(hdcprint); //结束一个打印作业
	MessageBox("打印完毕!","提示",MB_ICONINFORMATION);
}

实现结果

由于时间紧迫,以及个人能力有限,所以做的界面比较ugly。只实现了老师要求的一些功能:
在这里插入图片描述
默认n=16, k=1, m=3, s=1000ms, 数据读入在data.txt,结果保存在result.txt。
在这里插入图片描述

总结

由于是第一次写,所以排版什么的比较丑陋。约瑟夫环问题也是自己做的第一个关于用户界面的问题了,由于自己的能力有限,所以只能做到这种程度,中间会有福多错误,希望大家批评指正,以后会努力学习。

  • 13
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值