C/C++的题目:算术表达式求值

fiterby 2010-04-14 08:54:23
小米终于快小学毕业了,小米的小学毕业论文是解不含未知数的算术表达式。
老师给他的样例非常多,而且式子很长,老师还给小米 4 个规则:
1.a+b 代表a+2*b;
2.a-b 代表 a-3*b;
3.全部运算满足右结合性,如:a+b+c=a+2*(b+2*c);
4.小括号的优先级大于中括号。
小米不想把时间浪费在单调而又无趣的计算上,所以他请你帮他写一个程序,他的要
求很简单,就是他输入一组数据,就能立刻得到答案。
现给你一个算术表达式,对于每个式子输出一个数,表示该表达式的解。
★数据输入
输入只有一行,给你一个算术表达式,式子中只含有数字,‘+’、‘-’、‘(’、‘)’、‘[’、‘]’,长度不超过 10000,式子中的数均不为负,保证数据合法,输入的值以及结果都为 int型整数。
★数据输出
输出式子的运算结果!

输入示例 输出示例
(34+28+28)+[(7+8)-(9+10)] 74
...全文
496 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
fiterby 2010-04-24
  • 打赏
  • 举报
回复
谢谢啊,你还特地写了,但是我们有十个测试点。。。那个数据只是个范例而已。。。
mLee79 2010-04-15
  • 打赏
  • 举报
回复
偶在上面个帖子4楼的应该是符合要求地, 你把这个交上去, 然后跟老师一起探讨下编译原理/下推自动机/形式文法等等内容:
$ ( function x() { echo ------ $* ------- ; $* ; } ;\
x cat Xexpr.y ;x bison Xexpr.y -o Xexpr.c ; \
x gcc -o Xexpr Xexpr.c ; echo "(34+28+28)+[(7+8)-(9+10)]" | ./Xexpr ) | tee result
------ cat Xexpr.y -------
%{
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define YYPARSE_PARAM yyparam
#define YYLEX_PARAM yyparam

typedef struct yyparam_t yyparam_t;
struct yyparam_t
{
char* X_input;
int result;
};

int yylex( int *yylval_ , yyparam_t* param );

void yyerror( const char* msg )
{
fprintf( stderr , "[ERROR]%s\n" , msg );
}

%}
%pure_parser
%token XNUM

%right '+' '-'
%%
goal:
expr { ((yyparam_t*)YYPARSE_PARAM)->result = $$; }
;
expr:
XNUM
|
expr '+' expr { $$ = $1 + 2 * $3 ; }
|
expr '-' expr { $$ = $1 - 3 * $3 ; }
|
'(' expr ')' { $$ = $2 ; }
|
'[' expr ']' { $$ = $2 ; }
;
%%

int yylex( int *yylval_ , yyparam_t* param )
{
while( isspace( *param->X_input ) )
++param->X_input;

if( 0 == *param->X_input )
return 0;

if( !isdigit( *param->X_input ) )
return *param->X_input++;

*yylval_ = strtol( param->X_input , ¶m->X_input , 0 );
return XNUM;
}

int main()
{
yyparam_t param;
char line[1024+1] = "";
while( fgets( line , 1024 , stdin ) )
{
param.X_input = line;
if( 0 == yyparse( ¶m ) )
{
printf( "%d\n" , param.result );
}
}
return 0;
}
------ bison Xexpr.y -o Xexpr.c -------
------ gcc -o Xexpr Xexpr.c -------
74

o笨笨猪o 2010-04-15
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 fiterby 的回复:]
我还真想拒绝。。。但是这算平时成绩啊啊啊啊!大家都6分我就1分,那就亏打了。。。
[/Quote]
无语。。。。
你可以参考一下这个帖子:
http://topic.csdn.net/u/20100412/21/b39c50b9-caeb-406f-a12e-023e088c78c9.html
fiterby 2010-04-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 turntogo 的回复:]
到这里去看看吧,呵呵别笑我,这是我上传的资源,这是源代码呀:
http://d.download.csdn.net/down/315802/Turntogo
[/Quote]
谢谢啊,等我下课了再好好看看,到时候再给你评价~
星光伴月 2010-04-15
  • 打赏
  • 举报
回复
嗯,老师太黑了,也太狠了,还有点太过分了!
fiterby 2010-04-15
  • 打赏
  • 举报
回复
我还真想拒绝。。。但是这算平时成绩啊啊啊啊!大家都6分我就1分,那就亏打了。。。
o笨笨猪o 2010-04-15
  • 打赏
  • 举报
回复
这个涉及到编译技术的课程,如果没有学过,你可以拒绝做这次作业。
星光伴月 2010-04-15
  • 打赏
  • 举报
回复
到这里去看看吧,呵呵别笑我,这是我上传的资源,这是源代码呀:
http://d.download.csdn.net/down/315802/Turntogo
fiterby 2010-04-15
  • 打赏
  • 举报
回复
是一个学校的。
数据结构的作业。。。拿到我就傻了。。。
o笨笨猪o 2010-04-15
  • 打赏
  • 举报
回复
你这是作业还是什么?如果是新手的话,老师也不可能出这样难度的作业。
mLee79 2010-04-15
  • 打赏
  • 举报
回复
你们同一个学校的么:
http://topic.csdn.net/u/20100412/18/adc79bc4-7c01-4e2f-8fa0-6d44a99f651d.html
fiterby 2010-04-15
  • 打赏
  • 举报
回复
我有想过一些方法,就是不知道怎么才能实现。。。。
要把式子都变成逆波兰式么,然后再压到栈里?关键就来了。。。。怎么实现中缀式变成逆波兰式。。。?
o笨笨猪o 2010-04-15
  • 打赏
  • 举报
回复
其实这个问题没有那么复杂,将它抽象一下,其实就是求:
left + right
而且题目说明了不用考虑异常输入,所以就可以变得简单得多:
#include <iostream>
#include <string>
#include <locale>
#include <sstream>


class RightExpressionEvaluator {
public:
explicit RightExpressionEvaluator(std::istream& input) : input(input) {
}

int evaluate() {
return evaluateLeftOperand() + evaluateRightOperand();
}

private:
int evaluateLeftOperand() {
return readNextToken() ? parseLeftOperand() : 0;
}

int parseLeftOperand() {
if (isOpenBracket(token)) {
return evaluate();
}
else if (isDigit(token)) {
return readNextInteger();
}
return 0;
}

int evaluateRightOperand() {
return readNextToken() ? parseRightOperand() : 0;
}

int parseRightOperand() {
switch (token) {
case '+': return 2 * evaluate();
case '-': return -3 * evaluate();
}
return 0;
}

int readNextInteger() {
int result = 0;
input.unget();
input >> result;
return result;
}

bool readNextToken() {
return input.get(token).good();
}

bool isOpenBracket(char token) {
return token == '(' || token == '[';
}

bool isDigit(char token) {
return std::isdigit(token, std::locale());
}

private:
std::istream& input;
char token;
};


void testEvaluator(const std::string& expression) {
std::istringstream input(expression);
std::cout << "expression: " << expression << std::endl;
std::cout << "value : " << RightExpressionEvaluator(input).evaluate() << std::endl;
std::cout << std::endl;
}

int main() {
testEvaluator("2");
testEvaluator("2+2");
testEvaluator("2-2");
testEvaluator("2-(2+2)");
testEvaluator("2-[2+2]");
testEvaluator("(2-2)+(2+2)");
testEvaluator("[2-2]-(2+2)");
testEvaluator("(34+28+28)+[(7+8)-(9+10)]");
}
fiterby 2010-04-15
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 wanyouzhu 的回复:]
引用 9 楼 fiterby 的回复:
我还真想拒绝。。。但是这算平时成绩啊啊啊啊!大家都6分我就1分,那就亏打了。。。

无语。。。。
你可以参考一下这个帖子:
http://topic.csdn.net/u/20100412/21/b39c50b9-caeb-406f-a12e-023e088c78c9.html
[/Quote]
如果是(a+b+c)这样的式子要怎么处理?右结合性,也就是a+b+c=a+(b+c)
lcfan123 2010-04-14
  • 打赏
  • 举报
回复
做出这个需要时间
AlanBruce 2010-04-14
  • 打赏
  • 举报
回复
UP

纠结的说
1. C 语言中的指针和内存泄漏 5 2. C语言难点分析整理 10 3. C语言难点 18 4. C/C++实现冒泡排序算法 32 5. C++中指针和引用的区别 35 6. const char*, char const*, char*const的区别 36 7. C中可变参数函数实现 38 8. C程序内存中组成部分 41 9. C编程拾粹 42 10. C语言中实现数组的动态增长 44 11. C语言中的位运算 46 12. 浮点数的存储格式: 50 13. 位域 58 14. C语言函数二维数组传递方法 64 15. C语言复杂表达式的执行步骤 66 16. C语言字符串函数大全 68 17. C语言宏定义技巧 89 18. C语言实现动态数组 100 19. C语言笔试-运算符和表达式 104 20. C语言编程准则之稳定篇 107 21. C语言编程常见问题分析 108 22. C语言编程易犯毛病集合 112 23. C语言缺陷与陷阱(笔记) 119 24. C语言防止缓冲区溢出方法 126 25. C语言高效编程秘籍 128 26. C运算符优先级口诀 133 27. do/while(0)的妙用 134 28. exit()和return()的区别 140 29. exit子程序终止函数与return的差别 141 30. extern与static存储空间矛盾 145 31. PC-Lint与C\C++代码质量 147 32. spirntf函数使用大全 158 33. 二叉树的数据结构 167 34. 位运算应用口诀和实例 170 35. 内存对齐与ANSI C中struct内存布局 173 36. 冒泡和选择排序实现 180 37. 函数指针数组与返回数组指针的函数 186 38. 右左法则- 复杂指针解析 189 39. 回车和换行的区别 192 40. 堆和堆栈的区别 194 41. 堆和堆栈的区别 198 42. 如何写出专业的C头文件 202 43. 打造最快的Hash表 207 44. 指针与数组学习笔记 222 45. 数组不是指针 224 46. 标准C中字符串分割的方法 228 47. 汉诺塔源码 231 48. 洗牌算法 234 49. 深入理解C语言指针的奥秘 236 50. 游戏外挂的编写原理 254 51. 程序实例分析-为什么会陷入死循环 258 52. 空指针究竟指向了内存的哪个地方 260 53. 算术表达式的计算 265 54. 结构体对齐的具体含义 269 55. 连连看AI算法 274 56. 连连看寻路算法的思路 283 57. 重新认识:指向函数的指针 288 58. 链表的源码 291 59. 高质量的子程序 295 60. 高级C语言程序员测试必过的十六道最佳题目+答案详解 297 61. C语言常见错误 320 62. 超强的指针学习笔记 325 63. 程序员之路──关于代码风格 343 64. 指针、结构体、联合体的安全规范 346 65. C指针讲解 352 66. 关于指向指针的指针 368 67. C/C++ 误区一:void main() 373 68. C/C++ 误区二:fflush(stdin) 376 69. C/C++ 误区三:强制转换 malloc() 的返回值 380 70. C/C++ 误区四:char c = getchar(); 381 71. C/C++ 误区五:检查 new 的返回值 383 72. C 是 C++ 的子集吗? 384 73. C和C++的区别是什么? 387 74. 无条件循环 388 75. 产生随机数的方法 389 76. 顺序表及其操作 390 77. 单链表的实现及其操作 391 78. 双向链表 395 79. 程序员数据结构笔记 399 80. Hashtable和HashMap的区别 408 81. hash 表学习笔记 410 82. C程序设计常用算法源代码 412 83. C语言有头结点链表的经典实现 419 84. C语言惠通面试题 428 85. C语言常用宏定义 450

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧