代码:

// 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:算术表达式求值的更多相关文章

  1. 利用栈实现算术表达式求值(Java语言描述)

    利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...

  2. OpenJudge计算概论-简单算术表达式求值

    /*===================================== 简单算术表达式求值 总时间限制: 1000ms 内存限制: 65536kB 描述 2位正整数的简单算术运算(只考虑整数运 ...

  3. 【算法】E.W.Dijkstra算术表达式求值

    算术表达式求值 我们要学习的一个栈的用例同时也是展示泛型的应用的一个经典例子,就是用来计算算术表达式的值,例如 ( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) ) 如果将4乘以5,把3 ...

  4. page80-栈用例-算术表达式求值

    表达式由括号, 运算符和操作数(数字)组成.我们根据以下4中情况从左到右逐个将这些实体送入栈处理. (1)将操作数压入操作数栈: (2)将运算符压入运算符栈: (3)忽略左括号: (4)在遇到右括号时 ...

  5. Dijkstra的双栈算术表达式求值算法

    这次来复习一下Dijkstra的双栈算术表达式求值算法,其实这就是一个计算器的实现,但是这里用到了不一样的算法,同时复习了栈. 主体思想就是将每次输入的字符和数字分别存储在两个栈中.每遇到一个单次结束 ...

  6. 算法手记(2)Dijkstra双栈算术表达式求值算法

    这两天看到的内容是关于栈和队列,在栈的模块发现了Dijkstra双栈算术表达式求值算法,可以用来实现计算器类型的app. 编程语言系统一般都内置了对算术表达式的处理,但是他们是如何在内部实现的呢?为了 ...

  7. 栈的一个实例——Dijkstra的双栈算术表达式求值法

    Dijkstra的双栈算术表达式求值法,即是计算算术表达式的值,如表达式(1 + ( (2+3) * (4*5) ) ). 该方法是 使用两个栈分别存储算术表达式的运算符与操作数 忽略左括号 遇到右括 ...

  8. [Java]算术表达式求值之三(中序表达式转二叉树方案 支持小数)

    Entry类 这个类对表达式的合法性进行了粗筛: package com.hy; import java.io.BufferedReader; import java.io.IOException; ...

  9. java实现算术表达式求值

    需要根据配置的表达式(例如:5+12*(3+5)/7.0)计算出相应的结果,因此使用java中的栈利用后缀表达式的方式实现该工具类. 后缀表达式就是将操作符放在操作数的后面展示的方式,例如:3+2 后 ...

  10. [Java]算术表达式求值之二(中序表达式转后序表达式方案,支持小数)

    Inlet类,入口类,这个类的主要用途是验证用户输入的算术表达式: package com.hy; import java.io.BufferedReader; import java.io.IOEx ...

随机推荐

  1. Socket 模拟HTTP客户端请求

    import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import ja ...

  2. LeetCode 115.不同的子序列 详解

    题目详情 给定一个字符串 S 和一个字符串 T,计算在 S 的子序列中 T 出现的个数. 一个字符串的一个子序列是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串.(例如, ...

  3. SpringMVC大威天龙

    一 SpringMVC简介 SpringMVC是Spring提供的一个强大而灵活的Web框架 借助于注解 SpringMVC提供了几乎是POJO的开发模式 使得控制器的开发和测试更加简单 二 Spri ...

  4. Linux学习笔记 一 第二章 Linux系统安装

    Linux系统安装 一.首先安装VMware 虚拟机 下载网址:https://www.vmware.com/cn/products/workstation-pro/workstation-pro-e ...

  5. HahMap(jdk=1.8)源码解读

    简介:岁月磨平了人的棱角,让我们不敢轻易的去放手,即使它在你心中并不那么重要,你依旧害怕失去它,不是舍不得,是内心的迷茫. 一 : 创建HashMap HashMap<Object, Objec ...

  6. golang 递归自己,输出自己的源代码

    问题: [2min 大家自己想想] 一个程序P运行后能否输出自己的源代码?并且格式保持一致(换行.空格等) 思考: 这个问题的本质是一个递归问题,设有P运行后生成G 既P->G &&am ...

  7. 如何限制ip访问Oracle数据库

    一.概述 本文将给大家介绍如何限制某个ip或某个ip段才能访问Oracle数据库 通过sqlnet.ora 通过/etc/hosts.deny和/etc/hosts.allow 通过iptables ...

  8. HDFS的数据流读写数据 (面试开发重点)

    1 HDFS写数据流程 1.1 剖析文件写入 HDFS写数据流程,如图所示 1)客户端通过Distributed FileSystem模块向NameNode请求上传文件,NameNode检查目标文件是 ...

  9. centos7 nginx yum 配置

    [nginx] name=nginx repo baseurl=http://nginx.org/packages/centos/7/$basearch/ gpgcheck= enabled=

  10. double与Double

    1. double是基本数据类型,Double是原始数据类型(Java 类) 2. double创建引用,Double创建对象 3. double不可以为NULL,Double是类所以其对象是可以为N ...