《C程序设计语言》练习题 5-10

编写程序 expr,计算从命令行输入的逆波兰表达式的值,其中每个运算符或操作数用一个单独的参数表示。例如,命令

expr 2 3 4 + *

计算表达式2x(3+4)的值

算法实现

getfloat.c:

// getfloat.c
#include<stdio.h>
#include<ctype.h>
int getfloat(char* str, double* store)
{
while (isspace(*str))
str++;
int ch, sign;
double power = 1.0;
ch = *str++;
sign = ch == '-' ? -1 : 1;
if (ch == '+' || ch == '-') {
ch == *str++;
}
for (*store == 0.0; isdigit(ch); ch = *str++) {
*store = *store*10.0 + ch - '0';
}
if (ch == '.') {
ch=*str++;
}
for (; isdigit(ch); ch = *str++) {
*store = *store*10.0 + ch - '0';
power *= 10.0;
}
if (ch == 0 || isspace(ch) || ch == EOF) {
//如果不能继续读取数字,那么跳出的原因必须是 ch==0 || isspace(ch) || ch==EOF
*store /= power;
*store *= sign;
return 1;
}
else {
return -1;
}
}

expr.c:

//expr.c
#include<stdio.h>
#include<ctype.h>
#define MAX_NUM 100
double stack[MAX_NUM];
extern int getfloat(char* str,double*);
int main(int argc, char* argv[])
{
if (argc < 2) {
printf("usage: expr num1 num2 operator ...\n");
return 1;
}
else {
int stackp = 0;
int ch = 0;
double num1, num2, ans;
while (--argc >= 1) {
ch = (*++argv)[0];
if (ch == '-'){
if (!isdigit(ch = (*argv)[1])) {
//是负号
if (stackp >= 2) {
num2 = stack[--stackp];
num1 = stack[--stackp];
stack[stackp++] = num1 - num2;
continue;
}
else {
printf("Error: at least two numbers are needed before operator '-'\n");
return -1;
}
}
}
if (isdigit(ch)) {
if (stackp < 0) {
printf("stack is underflowed!\n");
return -2;
}
else if (stackp >= MAX_NUM) {
printf("stack is overflowed!\n");
return -3;
}
else if (getfloat(*argv, &stack[stackp++]) == -1) {
printf("wrong argument to get number: %s\n", *argv);
return -4;
}
}
else if (ch == '+'||ch=='*'||ch=='/'||ch=='%') {
if (stackp >= 2) {
num2 = stack[--stackp];
num1 = stack[--stackp];
switch (ch) {
case '+':
ans = num1 + num2;
break;
case '*':
ans = num1*num2;
break;
case '/':
if (num2 == 0.0) {
printf("error zero divisor: %f / %f\n", num1, num2);
return -5;
}
ans = num1 / num2;
break;
case '%':
ans = (int)num1%(int)num2;
break;
}
stack[stackp++] = ans;
}
else {
printf("Error: at least two numbers are needed before operator '%c'\n",ch);
return -6;
}
}
else {
printf("wrong arguments for %c,usage: expr num1 num2 operator ...\n", ch);
return -7;
}
}
if (stackp == 1) {
printf("%.4f\n", stack[0]);
}
else {
printf("the format of input is wrong!\n");
}
}
return 0;
}

重温C语言(1)----计算算术表达式的值的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. 实现Linux下dc的功能,计算后缀表达式的值

    提交测试截图和码云练习项目链接,实现Linux下dc的功能,计算后缀表达式的值 -将运算符写在两个操作数之后的表达式称为"后缀表达式",如上面的中缀表达式可转换为后缀表达式1 2 ...

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

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

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

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

随机推荐

  1. mongodb 两台互为主从

    主机A [root@mysql_master zhxf]# cat docker-compose.yml version: '3' services: mongo_rs1: image: mongo: ...

  2. 【SpringBoot+Mybatis+thymeleaf报错】Error resolving template "XXX", template might not exist or might not be accessible by any of the configured

    解决方法一: 原因:在使用springboot的过程中,如果使用thymeleaf作为模板文件,则要求HTML格式必须为严格的html5格式,必须有结束标签,否则会报错. 在application.y ...

  3. scrapyd的安装

    .安装 pip3 install scrapyd 二.配置 安装完毕之后,需要新建一个配置文件/etc/scrapyd/scrapyd.conf,Scrapyd在运行的时候会读取此配置文件. 在Scr ...

  4. HLS:OpenCV和RTL代码转换关系

    OpenCV 图像处理是基于存储器帧缓存而构建的, 它总是假设视频帧数据存放在外部 DDR 存储器中. 由于处理器的小容量高速缓存性能的限制, 因此, OpenCV 访问局部图像性能较差. 并且, 从 ...

  5. OPENERP 拓展 res.partner 对象,添加QQ号

    公司最近在导入开业物品资料,根据同事的需求,需要在供应商资料中添加QQ号一项,根据前段时间自己摸索的经验,准备自己尝试通过继承完成这一需求. 模块名定义为rainsoft_partner 创建__in ...

  6. suse-Linux下安装Oracle11g服务器

    系统要求 Linux安装Oracle系统要求 系统要求 说明 内存 必须高于1G的物理内存 交换空间 一般为内存的2倍,例如:1G的内存可以设置swap 分区为3G大小 硬盘 5G以上 2.修改操作系 ...

  7. python爬虫的教程

    来源:http://cuiqingcai.com/1052.html 大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多.学习过程中我把一些学习的笔记总结下来,还记录了一 ...

  8. Spring中线程池的应用

    多线程并发处理起来通常比较麻烦,如果你使用spring容器来管理业务bean,事情就好办了多了.spring封装了Java的多线程的实现,你只需要关注于并发事物的流程以及一些并发负载量等特性,具体来说 ...

  9. getSqlMapClientTemplate().insert()方法的返回值问题

    insert方法的返回值     今天碰到一个问题,就是关于ibatis的insert方法的返回值的问题.在网上找了很多例子,自己也亲自试了一下. 最后得出结论:insert方法返回的是在表中插入记录 ...

  10. FPGA加速:面向数据中心和云服务的探索和实践

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由columneditor 发表于云+社区专栏 作者介绍:章恒--腾讯云FPGA专家,目前在腾讯架构平台部负责FPGA云的研发工作,探索 ...