读书人

输入表达式 转后缀 计算 输出 看看有关

发布时间: 2012-03-06 20:47:55 作者: rapoo

输入表达式 转后缀 计算 输出 看看问题出在哪里
我是这样想的 先用一个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

读书人网 >C++

热点推荐