C:算术表达式求值
代码:
// fgets2.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h> typedef enum{
TT_NUM,
TT_ADD,
TT_SUB,
TT_MUL,
TT_DIV,
TT_LP,
TT_RP,
TT_EOL
}TokenType; typedef struct{
TokenType type;
char text[];
}Token; static int pos=;
static char* line; static Token prevToken;
static int prevTokenExist; void getToken(Token *token){
char arr[];
int index=;
arr[index]='\0'; while(line[pos]!='\0'){
if(line[pos]=='+'){
if(strlen(arr)>){
strcpy(token->text,arr);
index=;
arr[index]='\0';
token->type=TT_NUM; return;
} token->text[]='+';
token->text[]='\0';
token->type=TT_ADD;
pos++;
return;
}else if(line[pos]=='-'){
if(strlen(arr)>){
strcpy(token->text,arr);
index=;
arr[index]='\0';
token->type=TT_NUM;
return;
} token->text[]='-';
token->text[]='\0';
token->type=TT_SUB;
pos++;
return;
}else if(line[pos]=='*'){
if(strlen(arr)>){
strcpy(token->text,arr);
index=;
arr[index]='\0';
token->type=TT_NUM;
return;
} token->text[]='*';
token->text[]='\0';
token->type=TT_MUL;
pos++;
return;
}else if(line[pos]=='/'){
if(strlen(arr)>){
strcpy(token->text,arr);
index=;
arr[index]='\0';
token->type=TT_NUM;
return;
} token->text[]='/';
token->text[]='\0';
token->type=TT_DIV;
pos++;
return;
}else if(line[pos]=='('){
if(strlen(arr)>){
strcpy(token->text,arr);
index=;
arr[index]='\0';
token->type=TT_NUM;
return;
} token->text[]='(';
token->text[]='\0';
token->type=TT_LP;
pos++;
return;
}else if(line[pos]==')'){
if(strlen(arr)>){
strcpy(token->text,arr);
index=;
arr[index]='\0';
token->type=TT_NUM;
return;
} token->text[]=')';
token->text[]='\0';
token->type=TT_RP;
pos++;
return;
}else if(line[pos]=='\n'){
if(strlen(arr)>){
strcpy(token->text,arr);
index=;
arr[index]='\0';
token->type=TT_NUM;
return;
} token->text[]='\0';
token->type=TT_EOL;
pos++;
return;
}else{
arr[index]=line[pos];
index++;
arr[index]='\0';
pos++;
}
} if(strlen(arr)>){
strcpy(token->text,arr);
index=;
arr[index]='\0';
token->type=TT_NUM;
return;
}
} void fetchToken(Token *token){
if(prevTokenExist){
*token=prevToken;
prevTokenExist=;
}else{
getToken(token);
}
} void returnToken(Token *token){
prevToken=*token;
prevTokenExist=;
} char* getTokenTypeDesc(Token *token){
char* arr;
arr = (char *)malloc(); if(token->type==){
strcpy(arr,"Num");
}else if(token->type==){
strcpy(arr,"Add");
}else if(token->type==){
strcpy(arr,"Sub");
}else if(token->type==){
strcpy(arr,"Mul");
}else if(token->type==){
strcpy(arr,"Div");
}else if(token->type==){
strcpy(arr,"LP");
}else if(token->type==){
strcpy(arr,"RP");
} return arr;
} double parse_expression(void); // 为了防止出现 “找不到标识符parse_expression” static double parse_primary_expression(){
Token token; fetchToken(&token);
if(token.type==TT_NUM){
return atof(token.text); // 字符串转double
}else if(token.type==TT_LP){
double value=parse_expression();
fetchToken(&token);
if(token.type!=TT_RP){
printf("missing ).");
exit();
}
return value;
}else{
returnToken(&token);
return ;
} return ;
} static double parse_term(){
double v1;
double v2;
Token token; v1=parse_primary_expression(); for(;;){
fetchToken(&token); if(token.type!=TT_MUL && token.type!=TT_DIV){
returnToken(&token);
break;
} v2=parse_primary_expression();
if(token.type==TT_MUL){
v1*=v2;
}else if(token.type==TT_DIV){
v1/=v2;
}else{
returnToken(&token);
}
} return v1;
} static double parse_expression(){
double v1;
double v2;
Token token; v1=parse_term(); for(;;){
fetchToken(&token); if(token.type!=TT_ADD && token.type!=TT_SUB){
returnToken(&token);
break;
} v2=parse_term();
if(token.type==TT_ADD){
v1+=v2;
}else if(token.type==TT_SUB){
v1-=v2;
}else{
returnToken(&token);
}
} return v1;
} double parse(){
prevTokenExist=;
return parse_expression();
} int _tmain(int argc, _TCHAR* argv[])
{
char buf[]; while(fgets(buf,,stdin)!=NULL){
pos=;
line=buf;
printf("=%f\n",parse());
}
return ;
}
输出:
+(+)*
=21.000000
(+)/-*(-)
=4.600000
*-*
=24.000000
--2020年6月6日--
C:算术表达式求值的更多相关文章
- 利用栈实现算术表达式求值(Java语言描述)
利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...
- OpenJudge计算概论-简单算术表达式求值
/*===================================== 简单算术表达式求值 总时间限制: 1000ms 内存限制: 65536kB 描述 2位正整数的简单算术运算(只考虑整数运 ...
- 【算法】E.W.Dijkstra算术表达式求值
算术表达式求值 我们要学习的一个栈的用例同时也是展示泛型的应用的一个经典例子,就是用来计算算术表达式的值,例如 ( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) ) 如果将4乘以5,把3 ...
- page80-栈用例-算术表达式求值
表达式由括号, 运算符和操作数(数字)组成.我们根据以下4中情况从左到右逐个将这些实体送入栈处理. (1)将操作数压入操作数栈: (2)将运算符压入运算符栈: (3)忽略左括号: (4)在遇到右括号时 ...
- Dijkstra的双栈算术表达式求值算法
这次来复习一下Dijkstra的双栈算术表达式求值算法,其实这就是一个计算器的实现,但是这里用到了不一样的算法,同时复习了栈. 主体思想就是将每次输入的字符和数字分别存储在两个栈中.每遇到一个单次结束 ...
- 算法手记(2)Dijkstra双栈算术表达式求值算法
这两天看到的内容是关于栈和队列,在栈的模块发现了Dijkstra双栈算术表达式求值算法,可以用来实现计算器类型的app. 编程语言系统一般都内置了对算术表达式的处理,但是他们是如何在内部实现的呢?为了 ...
- 栈的一个实例——Dijkstra的双栈算术表达式求值法
Dijkstra的双栈算术表达式求值法,即是计算算术表达式的值,如表达式(1 + ( (2+3) * (4*5) ) ). 该方法是 使用两个栈分别存储算术表达式的运算符与操作数 忽略左括号 遇到右括 ...
- [Java]算术表达式求值之三(中序表达式转二叉树方案 支持小数)
Entry类 这个类对表达式的合法性进行了粗筛: package com.hy; import java.io.BufferedReader; import java.io.IOException; ...
- java实现算术表达式求值
需要根据配置的表达式(例如:5+12*(3+5)/7.0)计算出相应的结果,因此使用java中的栈利用后缀表达式的方式实现该工具类. 后缀表达式就是将操作符放在操作数的后面展示的方式,例如:3+2 后 ...
- [Java]算术表达式求值之二(中序表达式转后序表达式方案,支持小数)
Inlet类,入口类,这个类的主要用途是验证用户输入的算术表达式: package com.hy; import java.io.BufferedReader; import java.io.IOEx ...
随机推荐
- SCHP代码中的问题
1.subprocess.CalledProcessError: Command ‘[‘where’, ‘cl’]’ returned non-zero exit status 1. 这个问题是因为电 ...
- 什么是XML? 什么是DTD?
XML XML称为Extensible Markup Language,意思是可扩展的标记语言.XML语法上和HTML比较相似,但HTML中的元素是固定的,而XML的标签是可以由用户自定义的. W3C ...
- Java—转换流、字符缓冲流
转换流 OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的字符编码表,将要写入流中的字符编码成字节.它的作用的就是,将字符串按照指定的编码表转成字节,在使用字节流将这些字节写 ...
- 链表(python)
一.链表和数组 在编写代码中,我们储存的数据是存储于内存当中,内存就像一块块并列排序的小方盒,每个小方盒都有自己地址,我们储存的数据就在这样一个个小方盒当中. 这些数据存放的结构有两种基本方式,数组和 ...
- python处理转载博客html
前景 在转载别人博客的时候通常我们会通过复制html然后放到编辑器里面, 但是通常html里有很多杂七杂八的东西, 比如script, svg这些标签导致排版出现问题 例如由lu标签引起的 由svg标 ...
- 双向BFS和启发式搜索的应用
题目链接 P5507 机关 题意简述 有12个旋钮,每个旋钮开始时处于状态 \(1\) ~ \(4\) ,每次操作可以往规定方向转动一个旋钮 (\(1\Rightarrow2\Rightarrow ...
- 详解Python Graphql
前言 很高兴现在接手的项目让我接触到了Python Graphql,百度上对其介绍相对较少也不够全面,几乎没有完整的中文文档,所以这边也借此机会学习一下Graphql. 什么是Graphql呢? Gr ...
- Linux下mv命令高级用法
mv 也是 Linux 下一个使用频率非常高的命令,但除了一些基本用法,你还知道它的哪些高级用法呢? 1. 基本用法 移动一个/多个文件: 移动一个/多个目录: 重命名文件/目录. 这些都是很基本的用 ...
- 深入理解 Java 内存模型 JMM 与 volatile
Java 内存模型(Java Memory Model,简称 JMM)是一种抽象的概念,并不真实存在,它描述的是一组规范或者规则,通过这种规范定义了程序中各个变量(包括实例字段.静态字段和构成数组对象 ...
- python re之search/match差别
search → find something anywhere in the string and return a match object. match → find something at ...