自己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 首先看一下不包含括号的: ( ...
- 栈的应用实例——中缀表达式转换为后缀表达式
声明:本程序读入一个中缀表达式,将该中缀表达式转换为后缀表达式并输出后缀表达式. 注意:支持+.-.*./.(),并且输入时每输入完一个数字或符号都要加一个空格,特别注意的是在整个表达式输入完成时也要 ...
随机推荐
- docker 运行时常见错误
docker 运行时常见错误 (1) Cannot connect to the Docker daemon at unix:///var/run/docker.sock. [root@localho ...
- apscheduler(定时任务) 基于redis持久化配置操作
apscheduler(定时任务) 基于redis持久化配置操作 安装模块 pip install apscheduler 导入模块配置 ## 配置redis模块 from apscheduler.j ...
- nginx.service: control process exited, code=exited status=1
安装linux的宝塔面板,结果面板显示nginx和php已经运行了,但是机器系统上并没有运行.记录一次nginx报错,操作步骤看下代码: [root@localhost nginx]# systemc ...
- Memcached与Redis对比及其优劣分析
国外讨论 本文主要总结缓存Redis和Memcached的区别,总结之前先参考外国知乎上的一篇问答:<Is memcached a dinosaur in comparison to Redis ...
- apache httpclient 4 范例
下面是一个通过apache httpclient 4 实现http/https的普通访问和BasicAuth认证访问的例子.依赖的第三方库为: 下面是具体实现: package test; impor ...
- Python基础(函数)
为什么要用函数? 解决代码重用问题 统一维护 程序的组织结构清晰,可读性强函数:先定义后使用1.内置函数 built-in function eg:sum max len2.自定义函数:定义有参函数 ...
- springboot2.2.2集成6.5 Elasticsearch
1.0POM文件 <!-- spring-boot --> <dependency> <groupId>org.springframework.boot</g ...
- python atexit模块学习
python atexit模块 只定义了一个register模块用于注册程序退出时的回调函数,我们可以在这个函数中做一下资源清理的操作 注:如果程序是非正常crash,或者通过os._exit()退出 ...
- Docker私服搭建--Harbor
Docker私服搭建--Harbor Harbor概述 Harbor的安全机制 Harbor的镜像同步 Harbor的镜像同步机制 Harbor的多级部署 一.安装 1.1 docker安装 1.2 ...
- Spark 将DataFrame所有的列类型改为double
Spark 将DataFrame所有的列类型改为double 1.单列转化方法 2.循环转变 3.通过:_* 1.单列转化方法 import org.apache.spark.sql.types._ ...