课程实验报告题目:2016.4.6学生姓名:黄玲学生学号:201408070105专业班级:智能1401指导老师:骆嘉伟完成日期:2016.4.6一.需求分析1.本实验基本要求是用数组来实现线性表,再基于线性表的基本操作(插入、删除、修改等)来实现约瑟夫问题2.由键盘输入总人数n和出列报数m3.在DOS界面上显示依次出圈的人的编号和最后一个留下的人,在当前文件夹里生成一个文本文件,里面是相同的输出。
4.测试数据:输入:10,3输出:3 6 9 2 7 1 8 5 10 4//DOS3 6 9 2 7 1 8 5 10 4//TXT二.概要设计§抽象数据类型为实现上述程序的逻辑功能,应以整数存储用户的输入用线性表实现,线性表定义如下:ADT LISt数据对象:整数基本操作:AList(100);//构建一个最大人数为100的顺序表(数组)来存储人Next();//指向下一个人moveStart();//回到第一个人继续数数Length();//查看圈里还剩多少人currPos();//查看当前数到人的编号getValue();//查看当前编号的人是否还在圈内§程序的流程以书上的代码案例为参考,编写线性表的ADT在继承线性表的基础上编写顺序表(数组)的类文件编写主函数,创建类的对象,完成程序三.详细设计§物理数据类型将大小为n的数组赋好值,其值为他本身的编号,即数组下标。
§程序思路的具体步骤实现设一个标志点,在数组中移动,同时报数,当报到m时,当前人的值变为0,出圈,然后继续移动,重新数。
当数到值为0的人时自动跳过(已出圈),当数输入please input n and m://提示等待输入等待输入输出x x x x x//DOS界面上一列数字x x x x x//TXT上一列数字五.测试结果输入8 5 输出 5 2 8 7 1 4 6 3输入12 7 输出7 2 10 6 4 3 5 9 1 8 11 12六.实验心得通过实验,对c++类的使用熟悉了一遍,同时对线性表这一数据结构有了更深的理解。
同时,了解了一个问题要从多个方向求解。
譬如,这个约瑟夫环问题,实验的基本要求是用线性表解决,然而也可以用链表解决。
甚至一个公式。
七.附录●线性表实现◎List.h#ifndef List_H#define List_Hclass List{private:void operator = (const List&) {}List(const List&){}public:List(){}virtual ~List(){}virtual void change(int num) = 0;virtual void moveToStart() = 0;virtual void moveToEnd() = 0;virtual void prev() = 0;virtual void next() = 0;virtual int length() const=0;virtual int currPos() const=0;virtual void moveToPos(int pos) = 0;};#endif◎AList.h#ifndef ALIST_H#define ALIST_H#include <assert.h>#include "List.h"class Alist : public List{private:int maxSize;int listSize;int curr;int *listArray;public:Alist(int size=100){maxSize=size;listSize=0;curr=1;listArray=new int[maxSize];}~Alist(){delete [] listArray;}void clear(){delete [] listArray;listSize=0;curr=0;listArray=new int[maxSize];}void insert(const int it){assert(listSize<maxSize);for(int i=listSize;i>curr;i--)listArray[i]=listArray[i-1];listArray[curr]=it;listSize++;}void append(const int it){assert(listSize<maxSize);listArray[listSize++]=it;}int remove(){assert((curr>=0)&&(curr<listSize));int it=listArray[curr];for(int i=curr;i<listSize-1;i++)listArray[i]=listArray[i+1];listSize--;return it;}void change(int num){listArray[curr]=num;}void moveToStart(){curr=0;}void moveToEnd(){curr=listSize;}void prev(){if(curr!=0) curr--;}void next(){if(curr<listSize) curr++;}int length()const{return listSize;}int currPos()const{return curr;}void moveToPos(int pos){assert((pos>=0)&&(pos<=listSize));curr=pos;}const int getValue()const{assert((curr>=0)&&(curr<listSize));return listArray[curr];}};#endif◎main.cpp#include "AList.h"#include <iostream>#include<fstream>using namespace std;int main(){int n,m,turn=1;ofstream fout("joseph.txt",ios::out);cout<<"please input n and m:\n";cin>>n>>m;int remain=n;Alist joseph(n);for(int i=0;i<n;i++)joseph.append(i+1);joseph.moveToStart();while(remain>=1){while(joseph.getValue()==0){if(joseph.currPos()!=n-1)joseph.next(); else joseph.moveToStart();}while(turn!=m){if(joseph.currPos()!=n-1)joseph.next();else joseph.moveToStart();if(joseph.getValue()!=0)turn++;}turn=1;remain--;cout<<joseph.getValue()<<"";fout<<joseph.getValue()<<"";joseph.change(0);}return 0;}●循环链表实现约瑟夫环问题代码:#include<iostream.h>#include<stdio.h>#include<fstream>using namespace std;struct LNode{int data;LNode *next;};//n为总人数,m为出列者喊到的数void joseph(int n, int m){ofstream fout("joseph.txt",ios::out);if( n<=0 || m<=0){throw "Invalid argument(s)";}//建立循环链表LNode *p = new LNode;p->data = 1;p->next = p;LNode *curr = p;for(int i=2;i<=n;i++){LNode *q = new LNode;q->data = i;p->next = q;q->next = curr;p=p->next;}//把当前指针移动到第一个报数的人LNode *pre;int m1=m;while(n--){while(--m1){pre = curr;curr = curr->next;}m1 = m;cout<<curr->data<<"";fout<<curr->data<<"";pre->next = curr->next;delete curr;curr = pre->next;}}int main(){int n,m;cout<<"please input the number of people n and the m:";cin>>n>>m;joseph(n,m);return 0;}。