自己yy的中缀表达式转后缀表达式(未验证完全正确)
目前自己测试的表达式都没有出过问题
思路是这样,先将后缀表达式的计算顺序搞出来。。当完全缩出来一个数的时候,如果后面还有要计算的,我们就把它放到后缀表达式的后面
先算后面的。。不断迭代。。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
char sign[]={'+','-','*','/','^','(',')'},opSt[1000007],s[1000007];
ll numSt[1000007];
int opTail,numTail;
bool is_sign(char x){
int i;
for(i=0;i<7;++i) if(x==sign[i]) return true;return false;
}
ll calc(ll a,ll b,char x){
int i;
for(i=0;i<5;++i){
if(x==sign[i]){
if(x=='+'){
return a+b;
}
else if(x=='-'){
return a-b;
}
else if(x=='*'){
return a*b;
}
else if(x=='/'){
return a/b;//这里是下取整,小心除以0
//除法的顺序
}
else if(x=='^'){
return a^b;
}
}
}
printf("unknown-op->err!\n");//很关键
}
void printStack(){
printf("numStack::\n");
for(int i=numTail-1;i>=0;--i) printf("%I64d\n",numSt[i]);
if(!numTail) printf("empty\n");
printf("opStack::\n");
for(int i=opTail-1;i>=0;--i) printf("%c\n",opSt[i]);
if(!opTail) printf("empty\n");
}
int prev_q[1000007],back_q[1000007],pt,bt,seg_cnt,temp[1000007],tmp_cnt;
bool is_res[1000007],is_char[1000007],IS_CHAR[1000007],TMP_CHAR[1000007];
int ans[1000007],cnt;
char str[1000007];int Next[1000007],Prev[1000007];
void printBackStr(){
printf("BackStr::\n");
for(int i=pt-1;i>=0;--i) printf("%d\n",prev_q[i]);
printf("=====\n");
for(int i=0;i<bt;++i) {
if(is_char[i]) printf("%c\n",back_q[i]);
else printf("%d\n",back_q[i]);
}
}
void printAns(){
int i;
printf("AnsStr:: cnt::%d\n",cnt);
for(i=0;i<cnt;++i) {
if(IS_CHAR[i]) printf("%c",ans[i]);
else printf("%d",ans[i]);
}
printf("|\n");
}
void init(){
opTail=0,numTail=0;
pt=0;bt=0;cnt=0;seg_cnt=0;
memset(is_res,0,sizeof(is_res));
memset(is_char,0,sizeof(is_char));
memset(IS_CHAR,0,sizeof(IS_CHAR));
memset(TMP_CHAR,0,sizeof(TMP_CHAR));
}
void pop_Stack(int x){ if(!x) back_q[bt++]=numSt[numTail-1];
while(numTail&&opTail&&opSt[opTail-1]!='('){
if(numTail-2<0) printf("popStack-err!\n");
if(!is_res[numTail-2]) prev_q[pt++]=numSt[numTail-2];
back_q[bt++]=opSt[opTail-1];is_char[bt-1]=true;
is_res[numTail-1]=false;is_res[numTail-2]=false;
ll b=numSt[--numTail],a=numSt[--numTail];
a=calc(a,b,opSt[--opTail]);
is_res[numTail]=true;
numSt[numTail++]=a;
}
if(numTail==1&&is_res[numTail-1]){
int i;
tmp_cnt=0;
seg_cnt++;
memset(TMP_CHAR,0,sizeof(TMP_CHAR));
for(i=0;i<cnt;++i) {
temp[tmp_cnt++]=ans[i];
if(IS_CHAR[i]) TMP_CHAR[tmp_cnt-1]=1;
}
memset(IS_CHAR,0,sizeof(IS_CHAR));
cnt=0;
for(i=pt-1;i>=0;--i) ans[cnt++]=prev_q[i];
for(i=0;i<bt;++i){
ans[cnt++]=back_q[i];
if(is_char[i]) IS_CHAR[cnt-1]=true;
}
if(seg_cnt>=2){
if(is_char[bt-1]){
cnt--;IS_CHAR[cnt]=0;//这里忘记修改IS_CHAR,可能输出了退格字符!!
for(i=0;i<tmp_cnt;++i) {
ans[cnt++]=temp[i];
if(TMP_CHAR[i]) IS_CHAR[cnt-1]=true;
}
ans[cnt++]=back_q[bt-1];IS_CHAR[cnt-1]=true;
}
else{
printf("segment->Exception\n");
for(i=0;i<tmp_cnt;++i) {
ans[cnt++]=temp[i];
if(TMP_CHAR[i]) IS_CHAR[cnt-1]=true;
}
}
}
//清空队列
pt=0;bt=0;
memset(is_char,0,sizeof(is_char));
}
} int main(){
while(~scanf("%s",s)){
int len=strlen(s);
int i,j;
init();
for(i=0;i<len;++i){
if(is_sign(s[i])){
opSt[opTail++]=s[i];
}
else{
ll base=0;int prev_pos=i;
while(i<len&&!is_sign(s[i])){
base=base*10+(s[i]-'0');
i++;
}
i--;
numSt[numTail++]=base;
if(i==len-1||s[i+1]=='+'||s[i+1]=='-'||s[i+1]=='^'||s[i+1]==')'){
if(i+1<len&&s[i+1]==')'){
//右边是右括号的情况
pop_Stack(0);
if(opTail&&opSt[opTail-1]=='(') --opTail;
if(i+2==len||i+2<len&&s[i+2]!='*'&&s[i+2]!='/'){//少了最后是括号的判断
pop_Stack(1);
}
i++;//去除右括号
}
else {
if(prev_pos>0&&s[prev_pos-1]!='('){
if(i==len-1){
pop_Stack(0);
}
else if(s[i+1]=='^'){
pop_Stack(0);
}
else if(s[i+1]=='+'||s[i+1]=='-'){
if(s[prev_pos-1]!='^'){
pop_Stack(0);
}
}
else {
printf("JUDGE ERR!\n");
}
}
}
}
}
}
printf("NORMAL_ANS::%I64d\n",numSt[0]);
int slen=0;
//这里按所有数字不超过10考虑
for(i=0;i<cnt;++i){
if(IS_CHAR[i]) str[slen++]=ans[i];
else str[slen++]=ans[i]+'0';
}
numTail=0,opTail=0;
for(i=0;i<slen;++i){
Next[i]=i+1;
Prev[i]=i-1;
}
Next[slen-1]=-1;
//将str写成了s,命名混淆
for(j=0;j!=-1;j=Next[j]){
if(!is_sign(str[j])){
int t=str[j]-'0';
printf("%d ",t);
}
else{
printf("%c ",str[j]);
}
}
printf("\n");
//在这里char类型自然溢出了。。如果结果太大的话
for(i=0;i!=-1;i=Next[i]){
if(is_sign(str[i])){
ll b=str[Prev[i]]-'0';
ll a=str[Prev[Prev[i]]]-'0';
a=calc(a,b,str[i]);
int NextPos=Next[i];
str[Prev[Prev[i]]]=a+'0';
Next[Prev[Prev[i]]]=NextPos;
if(NextPos!=-1)
Prev[NextPos]=Prev[Prev[i]];
// printf("a::%I64d b:%I64d Next:%d\n",a,b,NextPos);
for(j=0;j!=-1;j=Next[j]){
if(j==0&&Next[j]==-1) {printf("%I64d",numSt[0]);continue;}
if(!is_sign(str[j])){
ll t=str[j]-'0';
printf("%I64d ",t);
}
else{
printf("%c ",str[j]);
}
}
printf("\n");
}
}
printf("%I64d\n",numSt[0]);
}
return 0;
}
自己yy的中缀表达式转后缀表达式(未验证完全正确)的更多相关文章
- 利用stack结构,将中缀表达式转换为后缀表达式并求值的算法实现
#!/usr/bin/env python # -*- coding: utf-8 -*- # learn <<Problem Solving with Algorithms and Da ...
- RPN-逆波兰计算器-中缀表达式转后缀表达式-javascript
1.利用栈(Stack)来存储操作数和操作符: 2.包含中缀表达式转后缀表达式的函数,这个是难点,也是关键点: 2.1.将输入字符串转为数组: 2.2.对转换来的字符进行遍历:创建一个数组,用来给存储 ...
- 练习3.20 a 将中缀表达式转换为后缀表达式
//将中缀表达式转换为后缀表达式 int main() { ; ]={,,,,,,,}; char tmp; PtrToStack s; s = CreateStack( MaxSize ); ) { ...
- NYOJ--257--郁闷的C小加(一)(中缀表达式变后缀表达式 )
郁闷的C小加(一) 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 我们熟悉的表达式如a+b.a+b*(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说 ...
- .net表达式计算器(中缀表达式转后缀表达式,支持20多个数学函数,支持函数嵌套)
最近在网上查了一下表达工计算器的类库,发现Java版本的有一个比较成熟的叫W3EVal,好像是一个IBM工程师写的,.net就很少了(可能是我了解不够多),但投机取巧的实现思路有很多,比如: (1)将 ...
- hdu-1237 简单计算器---中缀表达式转后缀表达式
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1237 题目大意: 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. 思路 ...
- 中缀表达式得到后缀表达式(c++、python实现)
将中缀表达式转换为后缀表达式的算法思想如下: 从左往右开始扫描中缀表达式 遇到数字加入到后缀表达式 遇到运算符时: 1.若为‘(’,入栈 2.若为’)‘,把栈中的运算符依次加入后缀表达式,直到出现'( ...
- c语言,中缀表达式转后缀表达式并计算
//c语言中缀表达式计算 #include <stdio.h> #include <stdlib.h> #include <string.h> #include & ...
- ZH奶酪:Python 中缀表达式转换后缀表达式
实现一个可以处理加减乘数运算的中缀表达式转换后缀表达式的程序: 一个输入中缀表达式inOrder 一个输出池pool 一个缓存栈stack 从前至后逐字读取inOrder 首先看一下不包含括号的: ( ...
- 栈的应用实例——中缀表达式转换为后缀表达式
声明:本程序读入一个中缀表达式,将该中缀表达式转换为后缀表达式并输出后缀表达式. 注意:支持+.-.*./.(),并且输入时每输入完一个数字或符号都要加一个空格,特别注意的是在整个表达式输入完成时也要 ...
随机推荐
- 微信登录2-生成授权URL
一.准备工作 1.注册 微信开放平台:https://open.weixin.qq.com 2.邮箱激活 3.完善开发者资料 4.开发者资质认证 准备营业执照,1-2个工作日审批.300元 5.创建网 ...
- 前端知识(一)05 axios-谷粒学院
目录 一.axios的作用 二.axios实例 1.复制js资源 2.创建 axios.html 3.引入js 4.启动课程中心微服务 5.编写js 6.html渲染数据 7.跨域 8.使用生命周期函 ...
- Py迭代和迭代器,生成器,生产者和消费者模型
迭代器iter 1.迭代的含义: 每次生成的结果依赖于上一次.问路,先问第一个人,第一个人不知道他就说第二个人知道,然后去找第二个人.第二个人不知道就说第三个人知道,然后去找第三个人 2.递归的含义: ...
- ovsdb-client命令
ovsdb-server 的命令行接口. 查看有哪些数据库: ovsdb-client list-dbs [server] 查看数据库 schema: ovsdb-client get-schema ...
- Bitter.Core系列九:Bitter ORM NETCORE ORM 全网最粗暴简单易用高性能的 NETCore 之 WITH 子句支持
有时我们在聚合查询中,经常会有复杂的聚联查询.有时表的聚联查询SQL 子句比较复杂,DBA 会经常告诉们,能否通过WITH 子句优化.WITH 子句,是对SQL 聚联查询的优化.Bitter.Core ...
- 知乎社区核心业务 Golang 化实践 - 知乎 https://zhuanlan.zhihu.com/p/48039838
知乎社区核心业务 Golang 化实践 - 知乎 https://zhuanlan.zhihu.com/p/48039838
- Python基础(变量、字符编码、数据类型)
变量 变量名由字母.数字(不能为首字符).下划线组成,不能使用关键字 以下关键字不能声明为变量名 ['and', 'as', 'assert', 'break', 'class', 'continue ...
- vue-router实现路由懒加载( 动态加载路由 )
三种方式第一种:vue异步组件技术 ==== 异步加载,vue-router配置路由 , 使用vue的异步组件技术 , 可以实现按需加载 .但是,这种情况下一个组件生成一个js文件.第二种:路由懒加载 ...
- vue组件中data为什么必须是一个函数?
因为JavaScript的特性所导致,在component中,data必须以函数的形式存在,不可以是对象. 组建中的data写成一个函数,数据以函数返回值的形式定义,这样每次复用组件的时候,都会返回一 ...
- jQuery——开发插件
当我们编写的代码可以供其他人甚至我们自己重用的时候,可以通过将这些代码打包成一个新插件. ###**在插件中使用别名∗∗自定义的插件就应该始终都使用jQuery这个名字来调用jQuery方法,或者也可 ...