自己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 首先看一下不包含括号的: ( ...
- 栈的应用实例——中缀表达式转换为后缀表达式
声明:本程序读入一个中缀表达式,将该中缀表达式转换为后缀表达式并输出后缀表达式. 注意:支持+.-.*./.(),并且输入时每输入完一个数字或符号都要加一个空格,特别注意的是在整个表达式输入完成时也要 ...
随机推荐
- centos7搭建dolphinscheduler集群
一.简述 Apache DolphinScheduler是一个分布式去中心化,易扩展的可视化DAG工作流任务调度系统.致力于解决数据处理流程中错综复杂的依赖关系,使调度系统在数据处理流程中开箱即用.有 ...
- 微信登录1-OAuth2简介
一.OAuth2解决什么问题 1.开放系统间授权 照片拥有者想要在云冲印服务上打印照片,云冲印服务需要访问云存储服务上的资源 2.图例 资源拥有者:照片拥有者 客户应用:云冲印 受保护的资源:照片 3 ...
- Atlas 2.1.0 实践(3)—— Atlas集成HIve
Atlas集成Hive 在安装好Atlas以后,如果想要使用起来,还要让Atlas与其他组件建立联系. 其中最常用的就是Hive. 通过Atlas的架构,只要配置好Hive Hook ,那么每次Hiv ...
- linux驱动设备号
一.设备号基础 一般来说,使用ls -l命令在时间一列的前一列的数字表示的是文件大小,但如果该文件表示的是一个设备的话,那时间一列的前一列将有两个数字,用逗号分隔开,如下图: 前一个数字表示主设备号, ...
- 前端面试之ES6新增了数组中的的哪些方法?!
前端面试之ES6新增了数组中的的哪些方法?! 我们先来看看数组中以前有哪些常用的方法吧! 1 新增的方法! 1 forEach() 迭代遍历数组 回调函数中的三个参数 value: 数组中的每一个元素 ...
- ubuntu更新下载软件卡住0% [Connecting to archive.ubuntu.com (2001:67c:1360:8001::23)]
一台ubuntu系统,查看硬件和配置环境的时候发现下载卡住了 根据提示就是有ipv6地址,系统也是配置了ipv6地址的.海外机器,而且可以ping通域名 最佳解决方案 我想出了如何让apt-get再次 ...
- 一、JavaScript实现AJAX(只需四步)
-----------------------------------------------一.JavaScript实现AJAX(只需四步)----------------------------- ...
- spring 之7种重要设计模式
Spring中涉及的设计模式总结 1.简单工厂(非23种设计模式中的一种) 实现方式: BeanFactory.Spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获 ...
- 翻页bug 在接口文档中应规范参数的取值区间 接口规范
<?php$a=array("red","green","blue","yellow","brown&q ...
- ThinkPHP3.2.4 order方法注入
漏洞详情: 漏洞文件:./ThinkPHP\Library\Think\Db\Driver.class.php 中的 parseOrder方法: 这也是继上次order方法注入之后的修复手段. 可以看 ...