输入表达式 转后缀 计算 输出 看看问题出在哪里
我是这样想的 先用一个string输入表达式 然后将里边的数字和运算符分离 顺序不做改变 用一个链表存起来//StrToList,再将这个链表改为后缀//StrToStr,最后运算//Calcu
编译通过 运行时StrToList无法返回值
- C/C++ code
//func.h#ifndef FUNC_H#define FUNC_H#include "list.h"#include "Stack.h"#include<string>#include<iostream>using namespace std;List StrToList(string &);List StrToStr(List &);float Calcu(List &);#endif
- C/C++ code
//func.cpp#include"func.h"#include<cctype>List StrToList(string &Mstr){ string numing=""; float num1=0; float num2=0; char ch='\0'; Value data; List M; for(int i=0;i<=Mstr.length();i++) { numing=""; num1=0;//小数点之前 num2=0;//小数点之后 if(Mstr.at(i)=='.')//遇到小数点 { i++; while(isdigit(Mstr.at(i))) { numing+=Mstr.at(i); i++; } i--; num2=atoi(&numing.at(0)); for(int j=0;j<=numing.length();j++) num2=num2/10; M.Getlast()->Data.num=M.Getlast()->Data.num+num2;//chang list's last } else { if(isdigit(Mstr.at(i))) { while(isdigit(Mstr.at(i))) { numing+=Mstr.at(i); i++; } i--; num1=atoi(&numing.at(0)); data.num=num1; M.Insert(data,Float)//insert list } else { data.ch=Mstr.at(i); M.Insert(data,Char);//insert list } } } return M;}List StrToStr(List &M){ List B; Stack temp; Value data; data.ch='#'; temp.Push(data,Char); M.Insert(data,Char); Node *p=M.Getfirst(); while(p!=0) { if(p->Type==Float)////////////操作数 输出 { B.Insert(p->Data,Float); p=p->link; } else { if(temp.Gettop()->isp()==p->icp()) { temp.Pop(); p=p->link; } if(temp.Gettop()->isp()<p->icp())///////////////isp<icp 入栈 { temp.Push(p->Data,Char); p=p->link; } if(temp.Gettop()->isp()>p->icp()) { while(temp.Gettop()->isp()>p->icp()) { B.Insert(temp.Pop(),Char); p=p->link; } } } } return B;}float Calcu(List &B){ Value data; Stack temp; Node *p=B.Getfirst(); while(p!=0) { if(p->Type==Float) temp.Push(p->Data,Float); else { data=temp.Pop(); if(p->Data.ch='+') data.num=data.num+temp.Pop().num; if(p->Data.ch='-') data.num=data.num-temp.Pop().num; if(p->Data.ch='*') data.num=data.num*temp.Pop().num; if(p->Data.ch='/'); data.num=data.num/temp.Pop().num; temp.Push(data,Float); } p=p->link; } return temp.Pop().num;}- C/C++ code
#include"func.h"#include<iostream>using namespace std;void main(){ string Mstr; cin>>Mstr; cout<<Calcu(StrToStr(StrToList(Mstr))); int i; cin>>i;}list和stack用的节点是自己做的
- C/C++ code
#ifndef NODE_H#define NODE_Henum Ntype{Char,Float};union Value{ char ch; float num;};class Stack;class List;class Node{public: friend class Stack; friend class List; Node(Value data,Ntype type) {Data=data;Type=type;link=0;} int isp(){...} int icp() {...} Ntype Type; Value Data; Node *link;};#endif[解决办法]
可以分步调试一下,确认一下list转换是否正确,表达式转换是否正确,最终检查表达式计算
异常部分,可以断点后单步执行调试分析一下
[解决办法]
while(temp.Gettop()->isp()>p->icp())
应改为
while(p && temp.Gettop()->isp()>p->icp())
比较安全
[解决办法]
List是一个链表,中间的数据都是用指针链接的,返回时可能造成其它结点部分被释放,而返回的最后M只是一个头结点(该结点可能是一个类对象或者一个结构体 看你是怎么构造的这个链!)
可以在List出来函数里进行动态分配内存,过后返回一个List指针(不过记得不用的时候的释放该List动态的内存)
还可以采用另外一种很有技巧性做法
给List建立一个伙伴类,就是建立一个智能指针类(c++本身也提供了以一个智能类auto_ptr但和这种用法有所区别)来管理List存储的内容
class List{
.....
private:
EleType *ptr; //List内容的管理
size_t *use; //use是一个整数,用来标记共享内存
};
关于智能指针类的管理和控制详解c++ primer