1 扑克牌游戏
1.1 需求
扑克牌游戏游戏规则如下:
扑克牌为从1(A)到12(Q)各4张,总共48张,没有K和大小王,打牌有四个步骤:
- 洗牌打乱顺序
-
发牌将牌分为12列每列4张
- 玩牌从抽第一列第一张开始玩牌, 抽到的牌放到该牌对应数字的那一列的下面(比如第一列第一张是6就放到第六列后面,然后抽取第六列的最上方那张牌,把这张牌放到对应数字的列的下面)根据这样的规则不断的抽牌放牌,直到放了牌后该列上部没有可以抽的牌为止。
1.2 代码
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main(){
int poke[48]={0};
//赋值
for(int i=0;i<48;i++){
if(i<=11){
poke[i]=i+1;
}
else if(i<=23&&i>11){
poke[i]=i+1-12;
}
else if(i<=35&&i>23){
poke[i]=i+1-12*2;
}
else{
poke[i]=i+1-12*3;
}
}
//洗牌
int temp=0;
unsigned seed;
seed = time(0);
srand(seed);
for(int i=0;i<10000;i++){
swap(poke[i%48],poke[rand()%48]);
}
//打印牌
int column=12;
int row=4;
for(int i=0;i<row;i++){
for(int j=0;j<column;j++){
cout<<poke[12*i+j]<<" ";
}
cout<<endl;
cout<<endl;
}
//一维数组转二维
int two_poke[4][12]={0};
for(int i=0;i<4;i++){
for (int j=0;j<12;j++){
two_poke[i][j]=poke[12*i+j];
}
}
//玩牌
int up[12]={0},down[12]={0};
int temp1=0;
for (int i=0;i<12;i++){ //赋值
up[i]=0;
down[i]=4;
}
int valPlay=0;
int colPlay=0;
int t[4][12]={0};
t[0][0]=1;
while(down[0]<8){
valPlay=two_poke[up[colPlay]][colPlay];
//cout<<"val:"<<valPlay<<endl;
down[colPlay]+=1;
for(int i=0;i<12;i++){
//cout<<"down:"<<down[i];
}
//cout<<endl;
up[colPlay]+=1;
for(int i=0;i<12;i++){
//cout<<"up:"<<up[i];
}
//cout<<endl;
colPlay=valPlay-1;
t[up[colPlay]][colPlay]=valPlay;
}
//输出结果
for(int i=0;i<row;i++){
for(int j=0;j<column;j++){
cout<<t[i][j]<<" ";
}
cout<<endl;
cout<<endl;
}
return 0;
}
一次结果如下:
11 6 10 5 11 5 4 3 10 12 7 1
9 6 12 4 3 8 1 1 6 8 4 7
12 8 7 2 10 5 9 8 9 3 4 12
9 10 2 7 3 1 5 11 2 11 6 2
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 7 8 9 10 11 12
1 0 0 4 0 0 0 0 0 0 0 12
1 0 0 0 0 0 0 0 0 0 0 12
2 计算表达式
2.1 需求
输入表达式,计算值,通过栈
2.2 代码
main.cpp
#include <iostream>
#include <cstdlib>
#include <string>
#include "Stack.h"
#include <cmath>
//判断是不是操作码
bool isOperator(char op){
if(op == '+' || op == '-' || op == '*' || op == '/'|| op == '^'){
return true;
}
else{
return false;
}
}
//判断是不是数字
bool isdigit(char c){
if(c>='0'&&c<='9'){
return true;
}
else{
return false;
}
}
//判断优先级
int priority(char opCode){
if(opCode=='+'||opCode=='-'){
return 1;
}
else if(opCode=='*'||opCode=='/'){
return 2;
}
else{
return -1;
}
}
//输入与表达式的转换
string inputToexp(string input){
string exp = ""; //Empty string.
myStack<char> opStack;
int opEmpty = 0;
for (int i = 0; i<input.length(); i++){
if(isdigit(input[i])){
exp+=input[i];
}
else if(isOperator(input[i])){
exp+=' '; // 加一个空格
if(priority(input[i]) > priority(opStack.top()))//输入的符号优先级高于栈顶元素,入栈
opStack.push(input[i]);
else
{
while(!opEmpty && priority(opStack.top()) >= priority(input[i])){// 栈不空并且优先级高 ,一直出栈
exp+=opStack.pop(&opEmpty);
exp+=' ';
}
opStack.push(input[i]);//否则将下一个操作数压栈
}
}
}
while(!opEmpty){//返回输出表达式
exp+=' ';
exp+=opStack.pop(&opEmpty);
}
return exp;
}
//计算表达式
double expEvaluation(string exp)
{
myStack<double> output;
int empty = 0;
double final, n = 0.0;
string Temp = "";
for (int i = 0; i<exp.length(); i++){
if(isdigit(exp[i])){
Temp+=exp[i];
}
else if(exp[i] == ' '){
if(Temp.length() >= 1){
n = stod(Temp);
output.push(n);
Temp = "";
}
}
else if(isOperator(exp[i])){
double val1, val2, compute;
val2 = output.pop(&empty);
val1 = output.pop(&empty);
switch (exp[i]) { //根据符号计算
case '+':
compute = (val1 + val2); break;
case '-':
compute = (val1 - val2); break;
case '*':
compute = (val1 * val2); break;
case '/':
compute = (val1 / val2); break;
default:
break;
}
output.push(compute); //把计算结果重新压栈
}
}
final = output.pop(&empty); //最后就是答案.
return final;
}
int main() {
string input="";
getline(cin,input); //Get input stream.
string exp = inputToexp(input);
cout<<exp<<endl;
cout<<expEvaluation(exp)<<endl;
return 0; //Done.
}
stack.h
#include<iostream>
using namespace std;
template<class T>
struct node {
T data;
node<T> *nxt;
};
template<class T>
struct myStack {
node<T> *head;
myStack() {
head = NULL;
}
void push(T x) {
node<T> *n = new node<T>();
n->data = x;
n->nxt = head;
head = n;
}
T pop(int *empty) {
if (head == NULL) {
*empty = 1;
return 0;
}
*empty = 0;
node<T> *tmp = head;
head = head->nxt;
T x = tmp->data;
delete (tmp);
return x;
}
char top() {
if (head == NULL) {
return 0;
}
return head->data;
}
};
3 二叉树的建立与遍历
3.1 需求
二叉树的建立,二叉树的前序遍历,中序遍历,后序遍历
3.2 代码
#include<iostream>
#include<stack>
using namespace std;
typedef char elemType;
#define END '#'
typedef struct Node
{
Node* leftChild;
Node* rightChild;
elemType data;
}Node;
//购买节点
Node* addNode()
{
Node* tmpNode = new Node();
tmpNode->leftChild = NULL;
tmpNode->rightChild = NULL;
tmpNode->data = 0;
return tmpNode;
}
//利用前序遍历的结果创建链式结构二叉树
Node* createBinaryTree(const elemType *& str)
{
Node* p = NULL;
if (str != NULL && *str != END)
{
p = addNode();
p->data = *str;
p->leftChild = createBinaryTree(++str);
p->rightChild = createBinaryTree(++str);
}
return p;
}
//前序递归遍历二叉树
void preOrder(Node *binaryTree)
{
if (binaryTree != NULL)
{
cout << binaryTree->data<<" ";
preOrder(binaryTree->leftChild);
preOrder(binaryTree->rightChild);
}
}
//前序非递归遍历二叉树
void preNonrecursiveOrder(Node* binaryTree)
{
if (binaryTree == NULL)return;
stack<Node*> nodeStack;
nodeStack.push(binaryTree);
while (!nodeStack.empty())
{
Node* p = nodeStack.top();
nodeStack.pop();
cout << p->data << " ";
if (p->rightChild != NULL)
nodeStack.push(p->rightChild);
if (p->leftChild != NULL)
nodeStack.push(p->leftChild);
}
}
//中序递归遍历二叉树
void inOrder(Node* binaryTree)
{
if (binaryTree != NULL)
{
inOrder(binaryTree->leftChild);
cout << binaryTree->data<<" ";
inOrder(binaryTree->rightChild);
}
}
//后序递归遍历二叉树
void pastOrder(Node* binaryTree)
{
if (binaryTree != NULL)
{
pastOrder(binaryTree->leftChild);
pastOrder(binaryTree->rightChild);
cout << binaryTree->data << " ";
}
}
int main()
{
const char *str = "ABCD##E##F##GH##K##";
Node *myTree = createBinaryTree(str);
cout << "前序遍历的结果是: ";
preOrder(myTree);
cout << endl;
cout << "前序遍历非递归的结果是:";
preNonrecursiveOrder(myTree);
cout << endl;
cout << "中序遍历的结果是:";
inOrder(myTree);
cout << endl;
cout << "后序遍历的结果是: ";
pastOrder(myTree);
cout << endl;
return 0;
}
4 图的操作
4.1 需求
图的建立,图的遍历
4.2 代码
实现了图的深度优先遍历
#include <iostream>
using namespace std;
/* 定义一个节点 */
struct node {
char data;
struct node *next;
};
struct vnode {
struct node *head;
char data;
int visit;
};
class graph {
public:
vnode *vertex;
int n;
/* 初始化 */
graph( int n )
{
this->n = n;
vertex = new vnode[n];
for ( int i = 0; i < n; i++ )
{
vertex[i].head = NULL;
vertex[i].visit = 0;
}
}
/* 增加一条边 */
void addedge( char a, char b )
{
int flag = 0;
for ( int i = 0; i < n; i++ )
{
if ( vertex[i].data == a )
{
node *newnode = new node();
newnode->data = b;
newnode->next = vertex[i].head;
vertex[i].head = newnode;
flag += 1;
}
if ( vertex[i].data == b )
{
node *newnode = new node();
newnode->data = a;
newnode->next = vertex[i].head;
vertex[i].head = newnode;
flag += 1;
}
if ( flag == 2 )
{
break;
}
}
}
/* 打印图中顶点的邻接点 */
void printgraph()
{
node *newnode;
for ( int i = 0; i < n; i++ )
{
cout << "与" << vertex[i].data << "相邻的顶点是 : ";
newnode = vertex[i].head;
while ( newnode )
{
cout << newnode->data << " ";
newnode = newnode->next;
}
cout << "\n";
}
}
/* 是否被遍历过 */
bool isVisted( char data )
{
for ( int i = 0; i < n; i++ )
{
if ( vertex[i].data == data && vertex[i].visit == 0 )
{
return(false);
}
}
return(true);
}
/* 深度优先搜索 */
void DFS( char a )
{
node *newnode;
for ( int i = 0; i < n; i++ )
{
if ( vertex[i].data == a )
{
if ( vertex[i].visit == 0 )
{
vertex[i].visit = 1;
cout << vertex[i].data << " ";
newnode = vertex[i].head;
while ( newnode != NULL )
{
if ( !isVisted( newnode->data ) )
{
DFS( newnode->data );
}
newnode = newnode->next;
}
}
break;
}
}
}
};
int main()
{
cout << "输入顶点的个数 : ";
int n, c;
char x, y;
cin >> n;
graph gh( n );
for ( int i = 0; i < n; i++ )
{
cout << "顶点 " << i + 1 << " 的值 : ";
cin >> gh.vertex[i].data;
}
cout << "输入边的数量 :";
cin >> c;
for ( int i = 0; i < c; i++ )
{
cout << "输入两个顶点表示一条边 : ";
cin >> x >> y;
gh.addedge( x, y );
}
gh.printgraph();
char temp;
cout << "输入dfs的顶点 : ";
cin >> temp;
gh.DFS( temp );
return(0);
}
5 Dijkstra算法和Floyd算法
5.1 需求
实现该算法
5.2 Dijkstra代码
#include<stdio.h>
#define SIZE 110
#define INF 65535;
int Matrix[SIZE][SIZE]; //邻接矩阵存储
int Distance[SIZE]; //表示起点到i这个点的距离
int Visit[SIZE]; //节点是否被访问
int n;
// Dijkstra算法求最短路径
int Dijkstra(int source, int Dest){
int i,j;
// 起点为已访问状态
Visit[source]=1;
// 初始化Distance
for(i = 1 ; i <= n ; i ++){
Visit[i] = 0;
Distance[i] = Matrix[source][i]; //起点到其他点的距离
}
int temp=0;
// N 个顶点
for(i = 1 ; i <=n ; ++i){
int min = INF; //记录最小Distance[i]
int pos;
// 循环遍历所有顶点
for(j = 1 ; j <= n ; ++j){
//记录temp到与其连接点的最小距离的点
if(!Visit[j] && min > Matrix[temp][j]){
pos = j;
min = Matrix[temp][j];
}
}
Visit[pos] = 1;
// 更新temp
temp=pos;
// 更新Distance
for(j = 1 ; j <= n ; ++j){
//如果j节点没有被访问过&&j节点到起节点的最短路径>pos节点到起节点的最短路径+pos节点到j节点的路径
if(!Visit[j] && (Distance[j] > (Distance[pos] +Matrix[pos][j]))){
//更新j节点到起节点的最短路径
Distance[j] = Distance[pos] + Matrix[pos][j];
}
}
printf("第%d次的距离数组为:\n\n",i);
for(int k=1;k<=n;k++){
printf("%d ",Distance[k]);
}
printf("\n\n");
}
return Distance[Dest];
}
int main () {
//定义矩阵维数
n = 6;
//设一开始每个点都不可达
for(int i = 1 ; i <= n ; ++i){
for(int j = 1 ; j <= n ; ++j){
Matrix[j][j]=0;
Matrix[i][j] = INF;
}
}
//测试矩阵数据
Matrix[1][2] = 50;
Matrix[1][3] = 20;
Matrix[1][5] = 45;
Matrix[2][3] = 15;
Matrix[2][5] = 10;
Matrix[3][1] = 10;
Matrix[3][4] = 15;
Matrix[4][2] = 20;
Matrix[4][5] = 30;
Matrix[5][4] = 35;
Matrix[6][4] = 3;
int Ans = Dijkstra(6,5);
printf("最后两点之间的距离为:%d",Ans);
return 0;
}
5.3 Floyd 算法
#include<stdio.h>
#define SIZE 110
#define INF 65535;
int Matrix[SIZE][SIZE]; //邻接矩阵存储
int Path[SIZE][SIZE]; //路径矩阵
int n;
// floyd求最短路径
int floyd(int Source, int Dest){
int i,j,k;
// 枢轴 k
for(k=1; k<=n; k++){
// 起点i
for(i=1; i<=n; i++){
// 终点j
for(j=1; j<=n; j++){
// 更新距离和路径
if(Matrix[i][j]>(Matrix[i][k]+Matrix[k][j]) && i!=j){
Matrix[i][j]=Matrix[i][k]+Matrix[k][j];
Path[i][j]=Path[i][k];
}
}
}
}
return Matrix[Source][Dest];
}
int main () {
//定义矩阵维数
n = 6;
//设一开始每个点都不可达,路径矩阵设置为直达
for(int i = 1 ; i <= n ; ++i){
for(int j = 1 ; j <= n ; ++j){
Matrix[i][j] = INF;
Path[i][j]=j;
}
}
//测试数据
Matrix[1][2] = 50;
Matrix[1][3] = 20;
Matrix[1][5] = 45;
Matrix[2][3] = 15;
Matrix[2][5] = 10;
Matrix[3][1] = 10;
Matrix[3][4] = 15;
Matrix[4][2] = 20;
Matrix[4][5] = 30;
Matrix[5][4] = 35;
Matrix[6][4] = 3;
int ans = floyd(6,5);
printf("%d\n",ans);
// 打印路径
printf("%d", 6);
int k=Path[6][5];
while(k!=5){
printf("->%d", k);
k=Path[k][5];
}
printf("->%d", 5);
return 0;
}
6.排序
6.1 快速排序
#include <iostream>
using namespace std;
int partition(int *arr, int low, int high) {
int temp = arr[low];
while (low < high) {
while (low < high && arr[high] >= temp) {
high--;
}
swap(arr[high], arr[low]); // 交换
while (low < high && arr[low] <= temp) {
low++;
}
swap(arr[high], arr[low]); // 交换大小
}
return low;
}
void quickSort(int *arr, int low, int high) {
if (low < high) {
int tempLoc = partition(arr, low, high);
quickSort(arr, low, tempLoc - 1);
quickSort(arr, tempLoc + 1, high);
}
}
int main()
{
int Arr1[17] = {89,66,441,41,410,7,100,3,6,62,5,4,11,76,25,77,241}; //待排序元素
quickSort(Arr1,0,16);
for (int i = 0; i < 17; ++i){
cout<<Arr1[i]<<" ";
}
}
6.2 选择排序
#include <iostream>
using namespace std;
void bubbleSort(int *arr, int len) {
for (int i = 0; i < len - 1; ++i) {
for (int j = 0; j < len - 1 - i; ++j) {
if (arr[j] > arr[j + 1]) {
swap(arr[j], arr[j + 1]); // 最大值放后思想
}
}
}
}
int main()
{
int Arr[17] = {89,66,441,41,410,7,100,3,6,62,5,4,11,76,25,77,241}; //待排序元素
bubbleSort(Arr,17);
for (int i = 0; i < 17; ++i){
cout<<Arr[i]<<" ";
}
}