数据结构课程预习实验报告



项目1:计算机设计大赛赛事统计

【问题描述】

参加计算机设计大赛的n个学校编号为1-n,赛事分成m个项目,项目的编号为1~m.比赛获奖按照得分降序,取前三名,写一个统计程序产生各种成绩单和得分报表。

【基本要求】

1)每个比赛项目至少有10支参赛队;每个学校最多有6支队伍参赛;
2)能统计各学校的总分;
3)可以按照学校编号或名称查询,学校的总分、各项目的总分排序输出;
4)可以按学校编号查询学校某个项目的获奖情况;可以按项目编号查询取得前三名的学校;
5)数据存入文件并能随时查询

【设计要求】

1)输入数据形式和范围:可以输入学校的名称,赛事项目的名称。
2)输出形式:有中文提示,各学校分数为整数
3)界面要求:交互设计要合理,每个功能可以设立菜单,根据提示,完成相关功能的要求。
4)存储结构:学生自己根据系统功能要求自己设计,但是赛事相关数据要存储在文件中。
5)每个学校的每个参赛队伍只能参加一个赛事项目

【测试数据】

要求使用全部合法数据,整体非法数据,局部非法数据。进行程序测试,以保证程序的稳定。

【实现提示】

假设3<赛事项目数量<=10,学校名称长度不超过20个字符。每个赛事结束时,将其编号、名称输入,并依次输入参赛学校编号、学校名称和成绩。


代码部分

#include<iostream>
#include <fstream>
#include<string>
using namespace std;

struct team
{

    int score;//分数
    int join;//参加项目编号
    team* next;
};
struct team1
{
    int schoolid;
    int score;
    team1* next;
};
struct school
{
    int identifier;//学校编号
    string name;//名称
    int tnum;//队伍人数
    int sum;//学校总分
    
    team* teamlink;
    school* next;
};
struct project
{
    string name;
    int	num;//项目编号
    team1* s;
    project* next;
   
};
class CDC {

private:
    int pnum;//项目数
    int	snum;//参加比赛的学校数
    school* sch;//学校头指针
    project* pro;
public:
    CDC();
    void AddInformation();
    void AddNewSchool();
    void AddNewProject();
    void AddSchool(int n);
    void AddTeam();
    void AddProject(int n);
    void SchoolSum();
    void SortSum();
    void EachProjectSum();
    void TeamScore();
    void AwardProject();
    void Print();
    void SortTeam();

};
CDC::CDC() {
    pnum = 0;
    snum = 0;
    sch = new school;
    sch->next = NULL;
    pro = new project;
    pro->next = NULL;

}

void CDC::TeamScore() {
    project* p1 = pro->next;   
    while (p1 != NULL) {
        team1* q = p1->s;
        school* p2 = sch->next;
        while (p2 != NULL) {
            team* p3 = p2->teamlink->next;
            while (p3 != NULL) {
                if (p3->join == p1->num) {
                    team1* temp = new team1;
                    temp->schoolid = p2->identifier;
                    temp->score = p3->score;
                    q->next = temp;
                    q = temp;
                }
               
                p3 = p3->next;
            }

            p2 = p2->next;
        }
        q->next = NULL;
        p1 = p1->next;
    }
}
void CDC::AddProject(int n) {
    pnum = n;
    int count = 0;
    project* r = pro;
    while (count != pnum) {
        count++;
        cout << "请输入第" << count << "个项目的名称:";
        project* p = new project;
        cin >> p->name;
        p->num = count;
        p->s = new team1;
        p->s->next = NULL;
        r->next = p;
        r = p;
    }
    r->next = NULL;
}
void CDC::AddSchool(int n) {
    snum = n;
    int count = 0;
    school* r = sch;
    while (count != snum) {
        system("cls");
        count++;
        school* p = new school;
        cout << "请输入第" << count << "个学校的名称:" << endl;
        cin >> p->name;
        cout << "请输入学校的编号:" << endl;
        cin >> p->identifier;
        p->sum = 0;
        p->teamlink = new team;
        (p->teamlink)->next = NULL;
        r->next = p;
        r = p;
    }
    r->next = NULL;
}

void CDC::AddTeam() {
    school* p = sch->next;
    while (p != NULL) {
        system("cls");
        cout << "请输入编号为:" << p->identifier << "的学校参加比赛的队伍数量:";
        cin >> p->tnum;
        int count = 0;
        team* r = p->teamlink;
        while (count != p->tnum) {
            count++;
            team* q = new team;
            cout << "请输入第" << count << "支队伍参加的项目编号:";
            cin >> q->join;
            cout << "请输入所得分数:";
            cin >> q->score;
            r->next = q;
            r = q;
        }
        r->next = NULL;
        p = p->next;
    }
}
void CDC::SchoolSum() {
    school* p = sch->next;
    while (p != NULL) {
        team* p1 = p->teamlink->next;
        while (p1 != NULL) {
            p->sum += p1->score;
            p1 = p1->next;
        }
        p = p->next;
    }

}
void CDC::SortSum() {
    
    school* p, * q, * tail;	
    int num;
    for (int i = 0; i < snum - 1; i++) {
        num = snum - i - 1;//记录内层循环需要的次数,跟数组冒泡排序一样
        q = sch->next;
        p = q->next;
        tail = sch;//让tail始终指向q前一个结点,方便交换,也方便与进行下一步操作
        while (num--) {//内层循环 次数跟数组冒泡排序一样
            if (q->sum < p->sum) {
                q->next = p->next;
                p->next = q;
                tail->next = p;
            }
            tail = tail->next;
            q = tail->next;
            p = q->next;
        }
    }
    cout << "经总分排序后各学校的排名:"<<endl;
    int sort = 1;
    p = sch->next;
    while (p != NULL) {
        cout << "第" << sort << "名是:" << p->name << '\t' << " 总分为:" << p->sum << endl;
        sort++;
        p = p->next;
    }
}
void CDC::EachProjectSum() {
    string str;
    cout << "请输入您要查找学校的名称或编号:";
    cin >> str;
    school* p = sch->next;
    while (p != NULL) {
        if (atoi(str.c_str())==p->identifier||str == p->name) {
            int* ps = new int[pnum];
            for (int i = 0; i < pnum; i++) {
                ps[i] = 0;
            }
            team* s = p->teamlink->next;
            while (s != NULL) {
                ps[s->join - 1] += s->score;
                s = s->next;
            }
            for (int i = 0; i < pnum; i++) {
                cout << "项目" << i + 1 << "的总分为:" << ps[i] << endl;
            }
            break;
        }
        p = p->next;
    }    
}
void CDC::SortTeam() {
    TeamScore();
    project* pp = pro->next;
    while (pp != NULL) {
        int i, count = 0, num;
        team1* p, * q, * tail;
        p = pp->s;
        while (p->next != NULL) {
            count++;
            p = p->next;
        }
        for (i = 0; i < count - 1; i++) {
            num = count - i - 1;
            q = pp->s->next;
            p = q->next;
            tail = pp->s;
            while (num--) {
                if (q->score < p->score) {
                    q->next = p->next;
                    p->next = q;
                    tail->next = p;
                }
                tail = tail->next;
                q = tail->next;
                p = q->next; 
            }
        }
        pp = pp->next;

    }    
}
void CDC::Print() {
    SortTeam();
    int flag;
    cout << "请输入您要查询项目的编号:";
    cin >> flag;
    project* p = pro->next;
    while (p != NULL) {
        if (flag == p->num) {
            int count = 0;
            team1* q = p->s->next;
            while (q != NULL && count < 3) {
                count++;
                cout << "第"<<count<<"名是编号为:" << q->schoolid << "的学校" << '\t0' << "成绩为:" << q->score << endl;
                q = q->next;
            }            
        }
        p = p->next;
    }

}
void CDC::AwardProject() {
    SortTeam();
    int num,num1;
    cout << "请输入学校编号:";
    cin >> num;
    cout << "请输入项目编号:";
    cin >> num1;
    school* p1 = sch->next;
    while (p1 != NULL) {
        if (num == p1->identifier) {
            project* p2 = pro->next;
            while (p2 != NULL) {
                if (num1==p2->num) {
                    team1* p3 = p2->s->next;
                    int count = 0;
                    while (p3 != NULL && count < 3) {
                        if (num == p3->schoolid) {
                            cout << "恭喜获奖!" << endl;
                            return;
                        }
                        p3 = p3->next;
                    }
                }
                p2 = p2->next;
            }

        }
        p1 = p1->next;
    }
}
void CDC::AddNewSchool() {    
    school* temp = new school;
    cout << "请输入您要添加学校的编号:";
    cin >> temp->identifier;
    cout << "请输入您要添加学校的名称:" << endl;
    cin >> temp->name;
    school* p = sch->next;
    temp->next = p;
    sch->next = p;
    snum++;
    p = sch->next;
    cout << "请输入编号为:" << p->identifier << "的学校参加比赛的队伍数量:";
    cin >> p->tnum;
    int count = 0;
    team* r = p->teamlink;
    while (count != p->tnum) {
        count++;
        team* q = new team;
        cout << "请输入第" << count << "支队伍参加的项目编号:";
        cin >> q->join;
        cout << "请输入所得分数:";
        cin >> q->score;
        r->next = q;
        r = q;
    }
    r->next = NULL;
    cout << "输入成功!" << endl;
    cout << endl;
}
void CDC::AddNewProject() {
    pnum++;
    if (pnum > 10) {
        cout << "项目过多!不能添加!" << endl;
    }else{
        project* temp = new project;
        cout << "请输入新项目的名称:";
        cin >> temp->name;
        temp->num = pnum;
        project* p = pro->next;
        temp->next = p;
        pro->next = temp;
        cout << "输入成功!" << endl;
        cout << endl;
    }
   
    
}
void CDC::AddInformation() {
    system("cls");
    cout << "请输入您要添加的信息的编号:" << endl;
    cout << "1.学校" << endl;
    cout << "2.项目" << endl;
    int flag;
    cin >> flag;
    switch (flag)
    {
    case 1:
        AddNewSchool();
        break;
    case 2:
        AddNewProject();
        break;
    default:
        cout << "输入错误!";
        break;
    }
}
void menu() {
    cout << "欢迎使用计算机大赛赛事统计赛事查询系统" << endl;
    cout << "1.添加信息" << endl;
    cout << "2.查询各学校总分排名" << endl;
    cout << "3.查询学校各项目的总成绩" << endl;
    cout << "4.按学校编号查询学校某个项目的获奖情况" << endl;
    cout << "5.按项目编号查询取得前三名的学校" << endl;
    cout << "0.退出" << endl;
    cout << endl;
}

int main() {
    CDC	cdc;
    

    cout << "正在进行赛事的输入!" << endl;
    int schoolnum;
    int projectnum;
    cout << "请输入项目的个数:";
    cin >> projectnum;
    cdc.AddProject(projectnum);

    cout << "请输入参加比赛学校的数量:";
    cin >> schoolnum;
    
    cdc.AddSchool(schoolnum);
    cdc.AddTeam();
    cdc.SchoolSum();
    system("cls");
    while (true) {
        int flag;
        menu();
        cout << "请输入您要执行的选项:";
        cin >> flag;
        switch (flag)
        {
        case 0:
            cout << "欢迎您的下次使用!";
            return false;
        case 5:
            cdc.Print();
            break;
        case 4:
            cdc.AwardProject();
            break;
        case 3:
            cdc.EachProjectSum();
            break;
        case 2:
            cdc.SortSum();
            break;
        case 1:
            cdc.AddInformation();
            break;

        default:
            cout << "输入错误!";
            break;
        }
    }
    
}

测试部分
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


项目2:校园导游咨询

【问题描述】

设计一个校园导游程序,为来访的客人提供各种信息查询服务。

【基本要求】

(1) 设计你所在学校的校园平面图,所含景点不少于10个.以图中顶点表示校内各景点,存放景点名称、代号、简介 等信息;以边表示路径,存放路径长度等相关信息。
(2) 为来访客人提供图中任意景点相关信息的查询。
(3) 为来访客人提供图中任意景点的问路查询,即查询任意两个景点之间的一条最短的简单路径。

【测试数据】

以江苏科技大学长山校区为例。

【实现提示】

一般情况下,校园的道路是双向通行的,可设校园平面图是一个无向网.顶点和边均含有相关信息.


校园平面图
在这里插入图片描述
自定义的点位

0:北门 1:文理大楼 2:教学楼 3:西操场 4:文体中心 5:南门 6:西门 7:西苑食堂 8:宿舍 9:教学楼 10: 图书馆 11:东苑食堂 12:东门 13:东操场

Dijkstra算法思路:
1,定义一个S集合用于存放路径上的顶点, 定义一个U集合用于存放非路径中的顶点.

定义一个dist[]数组用于存放源点到各个顶点的权值。

path[]用于存储是哪个顶点到哪个顶点,如path[3]=0,表示到达顶点3的最短边是通过顶点0到顶点3.

现在以顶点v=0为源点.( 将顶点v加入S(路径顶点数组)数组,并从U集合中删除v顶点);

1.用源点v初始化dist[]数组 , 和path[]数组,(将v顶点到所有顶点的权值初始化dist[]数组,当顶点v到顶点 i有边的时候,那么就将path[i] = v;表示v->i有边).

2.在dist[]数组中找到权值最小的一条边,此时到顶点1的权值最小为4,将顶点1加入到S集合中,*********,此时加入顶点1后到每一个顶点的权值与没加入顶点时候到所有顶点权值的大小, 此时顶点1加入,就遍历1到各个顶点的距离和为加入1时候到各个顶点的距离大小,发现未加入顶点1,到顶点2的权值是6,加入顶点1后,到顶点2的权值是0->1>2=5, 所以5<6,需要更新dist[]数组。并且更新path[]数组,path[2]=1;表示现在顶点1到顶点2的全累加和更小。上面步骤循环操作. dist[]存放的是源点到各个顶点的最小权值,现在发现到顶点2的边权值最小,那么就去看比较之前到顶点2的权值和现在经过顶点1到顶点2的权值的大小.

dist[]数组方法: 现在将顶点1加入S,开始判断更小dist[]数组,去比较dist[2]和dist[1]+arc[i][j]因为arc[1][2]的权值为1,加上源点到1的权值,就是整个树到顶点2的权值和dist[]生成树到顶点2的权值作比较.

Dijskal算法得到的结果:

dist[]数组中存放这着到每个顶点的路径长度

path[]数组存放在从哪个顶点到哪个顶点,也就是路径.

代码部分

#define MAXVALUE  9999//∞
#define MAXVER	20//最大顶点数
struct ver                                          //顶点的结构体 
{
	char code;
	string name;
	string introduce;
};

class Graph                                                          
{
private:
	int numEdges;		            // 边数
	int numVertices;	            // 顶点数
	ver* VerList;				// 顶点表头结点
	int** Edges;					// 邻接矩阵保存边
	int* path;                      // 保存该结点的前一个结点
	int* dist;                      // 保存路径长度
public:
	Graph();										                 
	~Graph();										                 
	ver getValue(int i);						                     // 取顶点 i 的值
	int getWeight(int v1, int v2);					                 // 取边上权值
	int getVertexPos(char code);					                 // 给出顶点代码code在图中位置
	bool addVertex(char code, string name, string introduceduce);		     // 插入一个顶点vertex
	bool addEdge(int v1, int v2, int cost);		                 // 插入边(v1, v2), 权为cost
	void seek(int i);                                                // 输出顶点i的信息
	void Dijkstra(int v);                                        // Dijkstra求最短路径算法
	void printShortest(int v, int x);                                  // 输出两顶点间的最短路径和距离
	void search();                                                   // 景点信息查询 
	void shorest();                                                  // 查询两景点间最短距离
	void Map();	                                                     // 动态生成景点列表 
};

Graph::Graph()
{

	numVertices = 0;				                    // 初始化 顶点个数 
	numEdges = 0;										// 初始化 边数 

	VerList = new ver[MAXVER];				// 创建顶点表数组
	Edges = (int**) new int* [MAXVER];             // 创建邻接矩阵数组
	for (int i = 0; i < MAXVER; i++)
		Edges[i] = new int[MAXVER];
	for (int i = 0; i < MAXVER; i++)
		for (int j = 0; j < MAXVER; j++)
			Edges[i][j] = (i == j) ? 0 : MAXVALUE;		    // 邻接矩阵主对角线元素为0;顶点对间无边则权重无穷大

	addVertex('a', "北门", "北门是江苏科技大学最主要的大门");
	addVertex('b', "文理大楼", "文理大楼是江苏科技大学最显著的特征,是江科大里最高的楼");
	addVertex('c', "13、14号教学楼", "是学生上课的主要场所");
	addVertex('d', "西操场", "是大学生集中运动的主要场所");
	addVertex('e', "文体中心", "内有体育馆供人使用,目前是核酸的只要地点");
	addVertex('f', "南门", "学校大门之一");
	addVertex('g', "西门", "学校大门之一");
	addVertex('h', "西苑食堂", "学校食堂之一");
	addVertex('i', "宿舍", "学生休息的地点");
	addVertex('j', "16号楼", "学生上课的主要地点");
	addVertex('k', "图书馆", "学生学习的主要地点");
	addVertex('l', "东苑食堂", "学校食堂之一");
	addVertex('n', "东门", "学校大门之一");
	addVertex('m', "东操场", "学校操场");

	addEdge(0, 1, 400);
	addEdge(0, 6, 600);
	addEdge(1, 2, 150);
	addEdge(2, 3, 200);
	addEdge(2, 6, 300);
	addEdge(2, 9, 350);
	addEdge(3, 4, 200);
	addEdge(3, 7, 450);
	addEdge(4, 5, 400);
	addEdge(5, 13, 500);
	addEdge(6, 7, 400);
	addEdge(6, 8, 550);
	addEdge(7, 8, 300);
	addEdge(9, 10, 500);
	addEdge(10, 11, 300);
	addEdge(10, 12, 450);
	addEdge(11, 12, 400);
	addEdge(11, 13, 300);
};

Graph::~Graph()
{
	delete[] VerList;
	delete[] Edges;
	delete[] path;
	delete[] dist;
};

// 取顶点 i 的值
ver Graph::getValue(int i)
{
	return VerList[i];
};

// 取边上权值
int Graph::getWeight(int v1, int v2)
{
	return Edges[v1][v2];
};

// 给出顶点代码code在图中位置
int Graph::getVertexPos(char code)
{
	for (int i = 0; i < numVertices; i++)
		if (VerList[i].code == code)
			return i;
	return -1;
};

// 插入一个顶点vertex
bool Graph::addVertex(char code, string name, string introduce)
{
	if (numVertices == MAXVER)
		return false;
	VerList[numVertices].code = code;
	VerList[numVertices].name = name;
	VerList[numVertices].introduce = introduce;
	numVertices++;
	return true;
};

// 插入边(v1, v2), 权为cost
bool Graph::addEdge(int v1, int v2, int weight)
{
	if (v1 > -1 && v1<numVertices && v2>-1 && v2 < numVertices)
	{
		Edges[v1][v2] = Edges[v2][v1] = weight;//无向
		numEdges++;
		return true;
	}
	else
		return false;
};

// 输出顶点i的信息
void Graph::seek(int i)
{
	cout << "景点代号:" << VerList[i].code << endl;
	cout << "景点名称:" << VerList[i].name << endl;
	cout << "景点简介:" << VerList[i].introduce << endl;
	cout <<  endl;
};

//查询两景点之间的最短路径和距离
void Graph::Dijkstra(int v)
{
	int n = numVertices;
	dist = new int[n];
	path = new int[n];
	bool* S = new bool[n];                                    //最短路径顶点集 
	int i, j, k, w, min;
	for (i = 0; i < n; i++)
	{
		dist[i] = getWeight(v, i);                              //数组初始化 
		S[i] = false;
		if (i != v && dist[i] < MAXVALUE)
			path[i] = v;
		else
			path[i] = -1;
	}
	S[v] = true;                                               //顶点v加入顶点集合 
	dist[v] = 0;
	for (i = 0; i < n - 1; i++)
	{
		min = MAXVALUE;
		int u = v;                                             //选不在S中具有最短路径的顶点u 
		for (j = 0; j < n; j++)
			if (S[j] == false && dist[j] < min)
			{
				u = j;
				min = dist[j];
			}
		S[u] = true;                                           //顶点u加入集合S 
		for (k = 0; k < n; k++)                                     //修改 
		{
			w = getWeight(u, k);
			if (S[k] == false && w < MAXVALUE && dist[u] + w < dist[k])   //顶点k未加入S,且绕过u可以缩短路径 
			{
				dist[k] = dist[u] + w;
				path[k] = u;                                   //修改到k的最短路径 
			}
		}
	}
};

//输出两景点之间的最短路径和距离
void Graph::printShortest(int v, int x)
{
	int j, k, n;
	n = numVertices;
	int* d = new int[n];
	{
		j = x;
		k = 0;
		while (j != v)
		{
			d[k++] = j;
			j = path[j];
		}
		cout << getValue(v).name << "到" << getValue(x).name << "的最短路径为:" << endl << getValue(v).name;
		while (k > 0)
		{
			cout << "-->" << getValue(d[--k]).name;
		}
		cout << endl << "最短路径长度为:" << dist[x] << endl;

	}
	delete[] d;
};

//景点信息查询 
void Graph::search()
{	
	int i;
	char code;
	while (1)
	{
		system("cls");
		Map();
		cout << "请输入要查询的景点编号(输入#退出):";
		cin >> code;
		if (code == '#')
			break;
		i = getVertexPos(code);
		if (i == -1)
		{
			cout << "输入错误,请重新输入" << endl;
		}
		else
		{
			seek(i);
			cout << "按回车键继续";
			int n1 = getchar();
			int n2 = getchar();
		}
	}
};
//查询两景点间最短距离
void Graph::shorest()
{
	system("cls");
	Map();
	int v1, v2;
	char code1, code2;
	cout << "编号如上图,请输入您要查询的两个景点的编号:" << endl;
	cout << "起始景点:";
	cin >> code1;
	cout << "终止景点:";
	cin >> code2;
	while (1)
	{
		v1 = getVertexPos(code1);
		v2 = getVertexPos(code2);
		if (v1 == -1 || v2 == -1)
		{
			cout << "输入错误,请重新输入" << endl;
			cout << "起始景点:";
			cin >> code1;
			cout << "终止景点:";
			cin >> code2;
		}
		else
		{
			Dijkstra(v1);
			printShortest(v1, v2);
			break;
		}
	}
	cout << "按回车键继续";
	int n1 = getchar();
	int n2 = getchar();
};


//动态生成景点列表 
void Graph::Map()
{
	cout << "   景点编号如下:                      " << endl;
	for (int i = 1; i <= numVertices; i++)
	{
		cout << VerList[i - 1].code << std::left << setw(15) << VerList[i - 1].name;
		if (i % 3 == 0)
			cout << endl;
	}
	cout << endl;
};

参考文献
链接: Dijkstra算法(最短路径)
链接: 迪杰斯特拉(Dijkstra)算法解决最短路径问题


项目3:算术表达式求解

【问题描述】

设计一个简单的算术表达式计算器。

【基本要求】

实现标准整数类型的四则运算表达式的求值(包含括号,可多层嵌入).

【测试数据】

(30+270)/3-123
5+(9*(62-37)+15)*6
要求自行设计非法表达式,进行程序测试,以保证程序的稳定运行。

【实现提示】

可以设计以下辅助函数
status isNumber(char ReadInChar); //视ReadInchar 是否是数字而返回 TRUE 或 FALSE 。
int TurnToInteger(char IntChar); // 将字符’0’.’9’ 转换为整数 9


问题分析

要解决计算器问题:

  • 首先最关键的是判断表达式是否正确。
  • 其次是表达式中符号的优先级问题
  • 根据符号的优先级将其按顺序入栈,并根据一定的方法计算

流程框架

在这里插入图片描述


代码部分

bool isNumber(char c) {
	if ((c >= '0' && c <= '9') || c == '.')
		return true;
	return false;
}


bool check(string str) {
	int length = str.length();
	int l = 0;
	int r = 0;
	for (int i = 0; i < str.length(); i++) {
		char c = str[i];
		//非法符号
		if (!(c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')' || isNumber(c))) {
			return false;
		}		
		if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')
		{
			//排除两个运算符同时出现的情况
			if (i == 0 || i == length - 1 || str[i - 1] == '+' || str[i - 1] == '-' || str[i - 1] == '*' || str[i - 1] == '/' || str[i - 1] == '(' || str[i + 1] == '+' || str[i + 1] == '-' || str[i + 1] == '*' || str[i + 1] == '/' || str[i + 1] == ')')
			{
				return false;
			}
		}
		if (str[i] == '(')
			l++;
		if (str[i] == ')')
			r++;

	}
	if (l != r)
		return false;
	return true;
}

int get_priority(char c) {
	switch (c)
	{
	case '*':
	case '/':
		return 2;
	case '+':
	case '-':
		return 1;

	case '(':
	case ')':
		return 0;
	default:
		return -2;
	}
}

bool priority(char a, char b)
{
	//优先级判断如果a>b,则返回true) 
	if (get_priority(a) > get_priority(b)) {
		return true;
	}
	return false;
}
double figure(double a, double b, char c)//进行符号计算 
{
	switch (c)
	{
	case'+':
		return a + b;
	case'-':
		return a - b;
	case'*':
		return a * b;
	case'/':
		return a / b;
		return 0;
	}
}
double cal(string s)
{
	stack<char> op;
	stack<double> num;
	int size = s.length();
	string keepnum = "";
	for (int i = 0; i < size; i++)
	{
		if (s[i] != '+' && s[i] != '-' && s[i] != '*' && s[i] != '/' && s[i] != '(' && s[i] != ')')
		{
			keepnum += s[i];
			//如果ch是最后一位了则直接入栈
			if (i == size - 1) {
				num.push(double(std::stoi(keepnum)));//将常量压入常量栈
			}
			else {
				//判断下一个字符是不是数字,如果是继续扫描
				for (; s[i + 1] != '+' && s[i + 1] != '-' && s[i + 1] != '*' && s[i + 1] != '/' && s[i + 1] != '(' && s[i + 1] != ')' && i + 1 < size; i++)
				{
					keepnum += s[i + 1];
				}
				double d = atof(const_cast<const char*>(keepnum.c_str()));
				num.push(d);
				keepnum = "";//这里一定要清空keepnum
			}
		}
		if (s[i] == '(')
		{
			op.push(s[i]);//左括号优先级最高直接压入运算符栈
			continue;
		}
		if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/')
		{
			if (op.empty())//当栈为空时直接入栈,不为空时比较优先级
			{
				op.push(s[i]);
				continue;
			}
			char temp = op.top();

			if (priority(s[i], temp))
				op.push(s[i]);
			else 				//出栈
			{
				char c = op.top();
				op.pop();
				double a = num.top();
				num.pop();
				double b = num.top();
				num.pop();
				num.push(figure(b, a, c));
				op.push(s[i]);
			}
		}
		if (s[i] == ')')
		{
			while (op.top() != '(')
			{
				char s = op.top();
				op.pop();
				double a = num.top();
				num.pop();
				double b = num.top();
				num.pop();
				num.push(figure(b, a, s));
			}
			op.pop();
		}
		while (i == size - 1 && !op.empty())
		{
			char s = op.top();
			op.pop();
			double a = num.top();
			num.pop();
			double b = num.top();
			num.pop();
			num.push(figure(b, a, s));
		}
	}
	return num.top();
}


数据测试
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值