目前自己测试的表达式都没有出过问题

思路是这样,先将后缀表达式的计算顺序搞出来。。当完全缩出来一个数的时候,如果后面还有要计算的,我们就把它放到后缀表达式的后面

先算后面的。。不断迭代。。

#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的中缀表达式转后缀表达式(未验证完全正确)的更多相关文章

  1. 利用stack结构,将中缀表达式转换为后缀表达式并求值的算法实现

    #!/usr/bin/env python # -*- coding: utf-8 -*- # learn <<Problem Solving with Algorithms and Da ...

  2. RPN-逆波兰计算器-中缀表达式转后缀表达式-javascript

    1.利用栈(Stack)来存储操作数和操作符: 2.包含中缀表达式转后缀表达式的函数,这个是难点,也是关键点: 2.1.将输入字符串转为数组: 2.2.对转换来的字符进行遍历:创建一个数组,用来给存储 ...

  3. 练习3.20 a 将中缀表达式转换为后缀表达式

    //将中缀表达式转换为后缀表达式 int main() { ; ]={,,,,,,,}; char tmp; PtrToStack s; s = CreateStack( MaxSize ); ) { ...

  4. NYOJ--257--郁闷的C小加(一)(中缀表达式变后缀表达式 )

    郁闷的C小加(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 我们熟悉的表达式如a+b.a+b*(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说 ...

  5. .net表达式计算器(中缀表达式转后缀表达式,支持20多个数学函数,支持函数嵌套)

    最近在网上查了一下表达工计算器的类库,发现Java版本的有一个比较成熟的叫W3EVal,好像是一个IBM工程师写的,.net就很少了(可能是我了解不够多),但投机取巧的实现思路有很多,比如: (1)将 ...

  6. hdu-1237 简单计算器---中缀表达式转后缀表达式

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1237 题目大意: 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. 思路 ...

  7. 中缀表达式得到后缀表达式(c++、python实现)

    将中缀表达式转换为后缀表达式的算法思想如下: 从左往右开始扫描中缀表达式 遇到数字加入到后缀表达式 遇到运算符时: 1.若为‘(’,入栈 2.若为’)‘,把栈中的运算符依次加入后缀表达式,直到出现'( ...

  8. c语言,中缀表达式转后缀表达式并计算

    //c语言中缀表达式计算 #include <stdio.h> #include <stdlib.h> #include <string.h> #include & ...

  9. ZH奶酪:Python 中缀表达式转换后缀表达式

    实现一个可以处理加减乘数运算的中缀表达式转换后缀表达式的程序: 一个输入中缀表达式inOrder 一个输出池pool 一个缓存栈stack 从前至后逐字读取inOrder 首先看一下不包含括号的: ( ...

  10. 栈的应用实例——中缀表达式转换为后缀表达式

    声明:本程序读入一个中缀表达式,将该中缀表达式转换为后缀表达式并输出后缀表达式. 注意:支持+.-.*./.(),并且输入时每输入完一个数字或符号都要加一个空格,特别注意的是在整个表达式输入完成时也要 ...

随机推荐

  1. 20V,24V转5V,20V,24V转3.3V降压芯片,IC介绍

    常用的20V和24V转5V,3.3V的LDO稳压和DC-DC降压芯片: PW6206系列是一款高精度,高输入电压,低静态电流,高速,低压降线性稳压器具有高纹波抑制.输入电压高达40V,负载电流高达10 ...

  2. 1.2V升压5V和2.4V升压5V芯片,适用于镍氢电池产品

    一节镍氢电池1.2V升压5V电路芯片,两节镍氢电池2.4V升压到5V的电源芯片 PW5100具有宽范围的输入工作电压,从很低的0.7V到5V电压. PW5100输出电压固定3V,3.3V,5V可选固定 ...

  3. Http中的options请求

    引自:https://www.jianshu.com/p/5cf82f092201.https://www.cnblogs.com/mamimi/p/10602722.html 一.options是什 ...

  4. FLask的偏函数应用

    偏函数 实际上,偏函数主要辅助原函数,作用其实和原函数差不多,不同的是,我们要多次调用原函数的时候,有些参数,我们需要多次手动的去提供值.而偏函数便可简化这些操作,减少函数调用,主要是将一个或多个参数 ...

  5. 基于Redo Log和Undo Log的MySQL崩溃恢复流程

    在之前的文章「简单了解InnoDB底层原理」聊了一下MySQL的Buffer Pool.这里再简单提一嘴,Buffer Pool是MySQL内存结构中十分核心的一个组成,你可以先把它想象成一个黑盒子. ...

  6. Vue之事件绑定

    Vue事件绑定 点击事件 @click="事件名" or v-on:click="事件名" 结构部分: <el-button type="pri ...

  7. 报错:java.lang.ClassNotFoundException: io.opentracing.util.GlobalTracer

    报错:java.lang.ClassNotFoundException: io.opentracing.util.GlobalTracer 近来在做一个在线教育的项目,课程信息放在数据库,而视频放在阿 ...

  8. Linux下nf_conntrack(最全面)_董明磊-CSDN博客_nf_conntrack https://blog.csdn.net/qq_35299863/article/details/79530732

    Linux下nf_conntrack(最全面)_董明磊-CSDN博客_nf_conntrack https://blog.csdn.net/qq_35299863/article/details/79 ...

  9. https://www.cs.cmu.edu/~dga/papers/cuckoo-conext2014.pdf 检验hash冲突

    https://github.com/google/cityhash We like to test hash functions with SMHasher, among other things. ...

  10. Page not found (404) 不被Django的exception中间件捕捉 中间件

    Using the URLconf defined in config.urls, Django tried these URL patterns, in this order: