【笔记】数据结构04

news2024/9/20 16:53:29

文章目录

  • 稀疏矩阵压缩存储三元组表示
      • 稀疏矩阵转三元组
  • 栈的应用
    • 前缀表达式
      • 前缀表达式求值
    • 中缀表达式
    • 后缀表达式


稀疏矩阵内容参考
强连通文章

稀疏矩阵压缩存储三元组表示

将非零元素所在的行、列以及它的值构成一个三元组(i,j,v),然后再按某种规律存储这些三元组

【行下标,列下标,值】
【i,j,v】
除了记录非零元素的10字节,还需要1字节空间用于记录矩阵的行数,列数及非零元素个数
在这里插入图片描述

typedef struct{
	ElemType val;//元素值
	int i,//元素所在行
		j;//元素所在列
}TriMat;

在这里插入图片描述

稀疏矩阵转三元组

//统计非0元个数
int countValNot0(ElemType A[][MaxSize],int m,int n){
	int count=0;
	for(int i=0;i<m;++i){
		for(int j=0;j<n;++j){
			if(A[i][j] != 0){
				count++;
			}
		}
	}
	return count;
}
//稀疏矩阵转三元组表示
TriMat* matToTriMat(ElemType A[][MaxSize],int m,int n){
	//统计非0元个数
	int count = countValNot0(A,m,n);
	//申请存储空间
	TriMat *trimat = (TriMat*)malloc(sizeof(TriMat)*(count+1));

	//用三元组存储洗漱矩阵
	//下标0:记录非0元个数,原矩阵总行数,总列数
	triMat[0].val = count;
	triMat[0].i = m;
	triMat[0].j = n;

	int index = 1;
	for(int i=0;i<m;i++){
		for(int j=0;j<n;++j){
			if(A[i][j]!=0){
				triMat[index].val = A[i][j];
				triMat[index].j= j;
				triMat[index].i = i;
			}
		}
	}
	reuurn triMat;
}

表达式笔记参考
Begin to change
一只平平无奇

栈的应用

  1. 递归调用
  2. 子程序调用
  3. 表达式求值

前缀表达式

前缀表达式求值

1.从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,
2.弹出栈顶的两个数(先弹出左操作数,后弹出右操作数),用运算符对它们做相应的计算(栈顶元素 op 次顶元素),
3.并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果

//两数的四则运算
double value(double op1,double op2,char ch){
    switch (ch) {
        case '+': return op1+op2;break;
        case '-': return op1-op2;break;
        case '*': return op1*op2;break;
        case '/': return (op1*1.0)/op2;break;
    }
}
//前缀表达式求值
double calculate(char* str){
	stack<char> s;
	//将表达式倒序;
	int i = 0;
	while(str[i]!='\0'){
		s.push(str[i]);
		++i;
	}
	stack<double> result;
	while(!s.empty()){
		char temp = s.top();
		s.pop();
		if(result.empty()||temp>='0'&&temp<='9'){
			result.push(temp-'0');
		}else{
			
		}
	}
}

中缀表达式

(1) 先计算括号内,后计算括号外;

(2) 在无括号或同层括号内,先乘除运算,后加减运算,即乘除运算的优先级高于加减运算的优先级;

(3) 同一优先级运算,从左向右依次进行。

  1. 设置两个栈,一个数字栈numStack,用于存储表达式中涉及到的数字,operatorStack用于存储表达式中涉及到的运算符
  2. 逐个字符分析表达式,直到全部字符都已分析完
    • 若当前字符为数字,则判断是否后续字符也为数字,若为数字则进行拼接,直到下一个数字为运算符为止,此时将拼接好的多位数字压入数字栈中。(如果已经是最后一个字符则直接压入栈)
    • 若当前字符为算数运算符
      1. 如果运算符栈为空则直接压入栈中
      2. 运算符不为空,则对运算符优先级进行判断
        1. 如果当前运算符优先级大于等于栈顶运算符则直接压入栈中
        2. 如果优先级低于栈顶运算符,则,从数字栈中取出两个数据,将当前栈顶运算符弹出进行运算,将结果压入数字栈中,将当前运算符压入运算符栈中。
  3. 此时数字与运算符都已经压入栈中,此时运算符栈中均为优先级相同的运算符,需要进行收尾操作,如果运算符栈不为空,则依次从数字栈中弹出两个数据,与当前栈顶的运算符进行运算。将结果压入数字栈中。最后数字栈中的数字就是所要求解的结果
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#define maximum 100000
 
typedef struct//数字栈 
{
    float data[maximum];
    int top;
}number;
 
typedef struct//字符栈 
{
    char data[maximum];
    int top;
}sign;
 
void InitNumber(number *stack);//初始化数字栈 
void GetTopNumber(number stack, float *e);//获取栈顶元素 
void PushNumber(number *stack, float e);//进栈 
void PopNumber(number *stack, float *e);//出栈 
 
void InitSign(sign *stack);
void GetTopSign(sign stack, char *e);
void PushSign(sign *stack, char e);
void PopSign(sign *stack, char *e);
 
void Calculate(number *stack, char e);
 
number Num;
sign sig;
char expression[maximum];
	
int main()
{
    gets(expression);
    int length;
    length=strlen(expression);
    int i;
    float en,n;
    char es;
    InitNumber(&Num);
    InitSign(&sig);
    for (i=0;i<length;i++)
    {
        if(expression[i]>='0'&&expression[i]<='9')
        {
            n=expression[i]-'0';//字符型转换为整型 
            while (expression[i+1]!='\0')
            {
                if (expression[i+1]>='0'&&expression[i+1]<='9') 
                {
                    n=n*10+expression[i+1]-'0';
                    ++i;
                }
                else break;
            }
            PushNumber(&Num,n);
        }
        else if (expression[i]=='+'||expression[i]=='-'||expression[i]=='*'||expression[i]=='/'||expression[i]=='^'||expression[i]=='('||expression[i]==')')
        {
            switch (expression[i])
            {
            case '+':
                if(sig.data[sig.top-1]!='+'&&sig.data[sig.top-1]!='-'&&sig.data[sig.top-1]!='*'&&sig.data[sig.top-1]!='/'&&sig.data[sig.top-1]!='^')
                //与栈顶元素的优先级相比较, 高于时入栈,此处判断是否入栈。 
                    PushSign(&sig,'+');
                else
                {
                    while (sig.top>0&&sig.data[sig.top-1]!='(')//如果栈不为空切不为左括号,则出栈 
                    {
                        PopSign(&sig,&es);
                        Calculate(&Num,es);
                    }
                    PushSign(&sig,'+');
                }
                break;
            case '-':
                if(sig.data[sig.top-1]!='+'&&sig.data[sig.top-1]!='-'&&sig.data[sig.top-1]!='*'&&sig.data[sig.top-1]!='/'&&sig.data[sig.top-1]!='^')
                    PushSign(&sig,'-');
                else
                {
                    while (sig.top>0&&sig.data[sig.top-1]!='(')
                    {
                        PopSign(&sig,&es);
                        Calculate(&Num,es);
                    }
                    PushSign(&sig,'-');
                }
                break;
            case '*':
                if(sig.data[sig.top-1]!='*'&&sig.data[sig.top-1]!='/'&&sig.data[sig.top-1]!='^')
                    PushSign(&sig,'*');
                else
                {
                    while (sig.top>0&&sig.data[sig.top-1]!='(')
                    {
                        PopSign(&sig,&es);
                        Calculate(&Num,es);
                    }
                    PushSign(&sig,'*');
                }
                break;
            case '/':
                if(sig.data[sig.top-1]!='*'&&sig.data[sig.top-1]!='/'&&sig.data[sig.top-1]!='^')
                    PushSign(&sig,'/');
                else
                {
                    while (sig.top>0&&sig.data[sig.top-1]!='(')
                    {
                        PopSign(&sig,&es);
                        Calculate(&Num,es);
                    }
                    PushSign(&sig,'/');
                }
                break;
            case '^':
                if(sig.data[sig.top-1]!='^')
                    PushSign(&sig,'^');
                else
                {
                    while (sig.top>0&&sig.data[sig.top-1]!='(')
                    {
                        PopSign(&sig,&es);
                        Calculate(&Num,es);
                    }
                    PushSign(&sig,'^');
                }
            case '(':
                PushSign(&sig,'(');
                break;
            case ')':
                while (sig.data[sig.top-1]!='(')
                {
                    PopSign(&sig,&es);
                    Calculate(&Num,es);
                }
                PopSign(&sig,&es);
            }
        }
    }
    while (sig.top>0)
    {
        PopSign(&sig,&es);
        Calculate(&Num,es);
    }
    GetTopNumber(Num,&en);
    printf("%.0f\n",en);
    return 0;
}
 
void InitNumber(number *stack)
{
    stack->top=0;
}
 
void GetTopNumber(number stack, float *e)
{
    if(stack.top==0) return;
    else *e=stack.data[stack.top-1];
}
 
void PushNumber(number *stack, float e)
{
    if(stack->top>=maximum) return;
    else stack->data[stack->top++]=e;
}
 
void PopNumber(number *stack, float *e)
{
    if(stack->top==0) return;
    else *e=stack->data[--stack->top];
}
 
void InitSign(sign *stack)
{
    stack->top=0;
}
 
void GetTopSign(sign stack, char *e)
{
    if(stack.top==0) return;
    else *e=stack.data[stack.top-1];
}
 
void PushSign(sign *stack, char e)
{
    if(stack->top>=maximum) return;//栈满 
    else 
	{
		stack->data[stack->top]=e;
		stack->top++;
	}
}
 
void PopSign(sign *stack, char *e)
{
    if(stack->top==0) return;
    else *e=stack->data[--stack->top];
}
 
void Calculate(number *stack, char e)// 计算结果 
{
    float num1,num2,result;
    PopNumber(stack, &num2);
    PopNumber(stack, &num1);
    switch (e)
    {
        case '+':
            result=num1+num2;
            PushNumber(stack,result);
            break;
        case '-':
            result=num1-num2;
            PushNumber(stack,result);
            break;
        case '*':
            result=num1*num2;
            PushNumber(stack,result);
            break;
        case '/':
            if (num2==0) printf("表达式错误!");
            else
            {
                result=num1/num2;
                PushNumber(stack,result);
                break;
            }
        case '^':
            result=pow(num1,num2);
            PushNumber(stack,result);
            break;
    }
}

后缀表达式

//规定优先级
int level(char s){
	if(s=='+'||s=='-')
		return 1;
	else if(s=='*'||s=='/')
		return 2;
	return 3;
}
//四则运算
double value(double op1,double op2,char ch){
	switch(ch){
		case '+':return op1+op2;break;
		case '-':return op1-op2;break;
		case '*':return op1*op2;break;
		
	}
}
//中缀表达式求职
double calculate_infix(char* str){
	//数字栈
	stack<double> number_stack;
	//符号栈
	stack<char> symbol_stack;
	for(int i=0;str[i]!='\0'++i){
		//如果扫描到数字
		if(number_stack.empty()||str[i]>='0'&&str[i]<='9'){number_stack.push(str[i]-'0');}
		//------------------------如果扫描到运算符-------------------
		else if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/'){
					   
		//如果当前运算符的优先级>栈顶符号优先级,则直接进栈
		if(symbol_stack.empty()||level(str[i])>level(symbol_stack.top()))
			symbol_stack.push(str[i]);
			//如果当前运算符的优先级<=栈顶符号的优先级
		else{
		  //依次弹出优先级高于或等于当前符号的所有符号,并同时弹出数字栈中的两个数字作为操作数。注意先后顺序。
		  	while(!symbol_stack.empty()&&level(symbol_stack.top())>=level(str[i])){
				double op2 = number_stack.top();
				number_stack.pop();
				double op1 = number_stack.top();
				number_stack.pop();
				//将计算结果压入数字栈
				number_stack.push(value(op1,op2,symbol_stack.top()));
				//符号出栈
				symbol_stack.pop();
			}
			symbol_stack.push(str[i]);
			//最后把当前符号入栈
		}
			
		}
		//-----------------如果扫描到界限符-------------------
		else{
			if(str[i]=='(')
                symbol_stack.push(str[i]);
            else {
				 //遇到右括号')'依次弹出符号栈内运算符,和数字栈内的两个运算符,做计算,直到遇到左括号'('为止
				  while(symbol_stack.top()!='('){
                    double op2=number_stack.top();
                    number_stack.pop();
                    double op1=number_stack.top();
                    number_stack.pop();
                    //将计算结果压入数字栈
                    number_stack.push(value(op1,op2,symbol_stack.top()));
                    //符号出栈
                    symbol_stack.pop();
                }
                symbol_stack.pop();
			}
		}
	}
	 //将符号栈所有运算符出栈,与数字栈剩余数字做运算
    while(!symbol_stack.empty()){
        double op2=number_stack.top();
        number_stack.pop();
        double op1=number_stack.top();
        number_stack.pop();
        //将计算结果压入数字栈
        number_stack.push(value(op1,op2,symbol_stack.top()));
        //符号出栈
        symbol_stack.pop();
    }
    return number_stack.top();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2095583.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

推荐 3 个好用的桌面管理工具,实用强大,不要错过

BitDock BitDock是一款运行在Windows系统中的桌面停靠栏工具&#xff0c;也被称为比特工具栏。这款软件模仿了Mac系统的Dock栏设计&#xff0c;旨在为用户提供一个简洁、高效且极具美感的桌面环境。BitDock不仅具有个性化的外观&#xff0c;还内置了多种实用功能&#xff0c;如…

Java后端 - 常见BUG及其处理策略(持续更新中~)

Bug 收集与总结 本文记录的是 本人SpringBoot 后端项目使用和运行代码时所遇到的各种问题&#xff0c;全部都已解决&#xff0c;欢迎在评论区补充你遇到的 Bug 哦&#xff01;仅以本文记录学习社区项目时&#xff0c;所遇到的奇奇怪怪的 bug&#xff0c;以及一些很愚蠢的错误&…

从马斯洛需求层次理论谈职场激励

马斯洛需求层次理论是一个广为人知的心理学概念&#xff0c;它是由美国心理学家亚伯拉罕马斯洛&#xff08;Abraham Maslow&#xff09;于1943年提出&#xff0c;常被描述为一个5层的金字塔模型&#xff0c;反映了人类不同需求层级和依赖关系。马斯洛认为人类只有在低层级需求得…

在 VS Code 中使用 Git 源代码管理【Mac 版】

文章目录 一、Git 使用文档二、使用示例1、复制远程仓库地址2、查看当前所在的分支2.1、界面查看2.2、终端查看 3、修改/新增文件4、显示增改的详细内容5、添加暂存区6、查看/取消暂存的更改7、提交本地代码库8、待提交文件9、推送到远程仓库10、验证11、查看推送记录11.1、关于…

六. 部署分类器-trt-engine-explorer

目录 前言0. 简述1. 案例运行2. 补充说明3. engine分析结语下载链接参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习课程第六章—部署分类器&#xff0c;一起来学习 trt-engine…

Linux日志-secure日志

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 Linux进阶部分又分了很多小的部分,我们刚讲完了Linux基础软件&#xff0c;下面是Linux日志。Linux 系统中的日志是记录系统活…

18041 分期还款(加强版)

### 自查思路 1. 检查输入数据的处理是否正确。 2. 检查判断条件 p < d * r 是否正确。 3. 确认公式计算和输出格式是否正确。 ### 伪代码 1. 读取输入的贷款金额、每月还款额和月利率。 2. 判断是否可以还清贷款&#xff1a; - 如果每月还款额小于贷款金额乘以月利率&a…

深度学习与大模型第2课:机器学习实战

文章目录 深度学习与大模型第2课&#xff1a;机器学习实战1. Iris鸢尾花数据集分类1.1 数据预处理1.2 模型训练与评估 2. 美国加州房价预测2.1 数据预处理2.2 模型训练与调优 3. 房价数据的回归分析3.1 数据预处理与建模 4. 时尚衣物识别:MNIST 数据集分类4.1 数据读取与可视化…

跑Boundary-Aware Feature Propagation遇到的问题

跑Boundary-Aware Feature Propagation遇到的坑 1、运行不报错&#xff0c;也不显示结果 从train.py代码第一行import开始添加&#xff0c;print&#xff08;“check1”&#xff09;&#xff0c;发现问题torch.encoding无法导入&#xff0c;反复地参考github源代码https://gith…

Axure RP9安装教程(Pro版)

[Axure RP 9.0下载链接]: https://ga90eobypbb.feishu.cn/docx/WKvldvZkMoKPnIx3Yl2cJhOBnqe 1.找到下载好的安装包&#xff0c;右键解压到“Axure RP 9.0”文件夹 2.双击打开解压出来的文件夹&#xff0c;选中”AxureRP-安装程序.exe“右键以管理员身份运行 3.点击"Nex…

测试小白入门-03测试理论知识看这一篇就够了

文章目录 前言一、软件开发过程模型瀑布开发模型&#xff08;熟悉&#xff09;快速原型模型&#xff08;理解&#xff09;螺旋模型(了解) 二、测试模型测试V模型&#xff08;代表性&#xff09;测试W模型&#xff08;中大型企业&#xff09;测试H模型&#xff08;了解&#xff…

38集 ESP32 离线刷机教程

38集 ESP32 离线刷机教程 打开离线刷机工具 e:\technology\ESP32\esp32s3Qorvo\esp32-s3_rtc\ESP离线刷机\flash_download_tool_3.9.7_1\flash_download_tool_3.9.7\flash_download_tool_3.9.7.exe 设置如下&#xff1a; 要知道如何设置&#xff0c;需要知道esp32s3 工程的me…

【C++ Primer Plus习题】8.5

问题: 解答: #include <iostream> using namespace std;template <typename T> T max5(T arr[5]) {T max 0;for (int i 0; i < 5; i){if (arr[i] > max){max arr[i];}}return max; }int main() {int max 0;double max1 0.0;int a1[5] { 21,34,12,42,9…

【综合小项目】—— 爬取数据、数据处理、建立模型训练、自定义数据进行测试

文章目录 一、项目内容二、各步骤的代码实现1、爬取数据2、数据处理3、建立模型训练4、自定义数据进行预测 一、项目内容 1、爬取数据 本次项目的数据是某购物平台中某个产品的优质评价内容和差评内容采用爬虫的 selenium 方法进行爬取数据内容&#xff0c;并将爬取的内容分别…

C_11_位段,共同体,枚举

位段 位段也称 位域 ​ 1 字节 8 位域 概述&#xff1a; 特殊的结构体 大小按位分配 示例1&#xff1a; struct packed_data {unsigned int a : 2; // 占2 位unsigned int a : 4; // 占4 位unsigned int a : 6; // 占6 位unsigned int i; // 占4字节 32位 1b8位 } data…

打字练习神器与基础打字指法

先奉上链接&#xff1a;Learn Touch Typing Free - TypingClub 最近观察到一位计算机的学长打字哒哒哒哒停不下来&#xff0c;研究了一下发现是自己的指法有问题&#xff0c;只能从头开始学起啦。如果刚学打字的朋友们一定要学习指法&#xff0c;打好基础&#xff01; 基础指法…

基于微信小程序的挂号管理系统-小程序端

微信小程序端系统功能实现 登录功能 系统登录功能中&#xff0c;用户只需在登录界面输入正确的用户名和密码&#xff0c;即可快速进入系统。登录功能还采用了先进的加密技术&#xff0c;保障用户信息的安全性&#xff0c;让用户能够放心使用。 注册功能 系统注册功中&#xf…

js数据类型转换-----统一转成字符串String()

String&#xff08;&#xff09; 所有类型都可以转成字符串 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"…

告别无序 10款科研项目管理工具为您的科研之路加速

国内外主流的10 款科研单位科研项目管理系统对比&#xff1a;PingCode、Worktile、Wizard、ShowDoc、Asana、ClickUp、Notion、Wrike、Basecamp、智方科研管理系统。 在选择科研项目管理系统时&#xff0c;许多科研单位都面临着如何找到能够真正满足特定需求的系统这一挑战。市…

HALCON 深度学习异常检测实例

首先你需要下载软件&#xff0c;halcon 20的版本和 Deep Learning Tool 工具 注意了&#xff0c;下载的halcon 必须要专业版的电脑系统&#xff0c;win10或者win11 都可以但是版本必须是专业版的不能是家庭版的 详情可看我另一篇文章 halcon 深度学习软件工具安装以及用法…