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

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

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

#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. Linux下利用ifconfig命令查看和操纵网络接口

    为了说明这个问题,首先我们需要解释一下在Linux系统下"网络接口"的含义.通俗来讲,Linux中的所谓网络接口就是指本机的网卡,它相当于计算机的一台负责对网络进行收发数据的外设. ...

  2. nginx.service: control process exited, code=exited status=1

    安装linux的宝塔面板,结果面板显示nginx和php已经运行了,但是机器系统上并没有运行.记录一次nginx报错,操作步骤看下代码: [root@localhost nginx]# systemc ...

  3. 手把手做一个基于vue-cli的组件库(上篇)

    基于vue-cli4的ui组件库,先贴个最终效果吧,步骤有点多,准备分上下篇,上篇:如何做一个初步的组件.下篇:编写说明文档及页面优化.开工. GitHub源码地址:https://github.co ...

  4. CODING 再携手腾讯云 Serverless,让开发者跑步上云

    近年来,腾讯云持续在云原生领域打磨和完善产品矩阵,致力于为开发者上云提供更好的产品和服务.继前段时间 CODING CI 助力腾讯云 Serverless 全新应用控制台.持续保障 Serverles ...

  5. Linux 通过端口终止进程

    以下命令可用于杀死占用某端口的所有进程. root 用户: kill -9 $(lsof -i tcp:进程号 -t) 非 root 用户: kill -9 $(sudo lsof -i tcp:进程 ...

  6. CentOS7.9静默安装Oracle19C软件

    CentOS7.9静默安装Oracle19C软件 Oracle发布了支持的版本.可以看到了Oracle11gR2和Oracle12C.一直到2022年就不支持patch和服务.(感慨Oracle 11 ...

  7. 丢包 ICMP

    小结: 1.ICMP 常见网络丢包故障分析及处理 云极安 云极安 2019-12-25 我们在管理维护网络的过程中经常会遇到数据包丢失的现象.使用Ping命令进行连通性测试,则会发现Ping包延时远远 ...

  8. nginx http模块开发入门

    导语 本文对nginx http模块开发需要掌握的一些关键点进行了提炼,同时以开发一个简单的日志模块进行讲解,让nginx的初学者也能看完之后做到心里有谱.本文只是一个用作入门的概述. 目录 背景 主 ...

  9. WPF和MVVM的结合使用方法,不可错过

    Model:存储数据模型(类) 也在此业务逻辑,主要负责类文件的存储. ViewModel:连接View和Model,借助Command来负责界面的跳转和调用Model中方法来操作Model的数据. ...

  10. LOJ10100

    原题来自:CEOI 1996 一个电话线公司(简称 TLC)正在建立一个新的电话线缆网络,他们连接了若干个地点,编号分别从 1 到 N,没有两个地点有相同的号码,这些线是双向的并且能使两个地点保持通讯 ...