| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3818 人关注过本帖, 1 人收藏
标题:逆波兰计算器(后缀计算器)
取消只看楼主 加入收藏
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
结帖率:95.65%
收藏(1)
 问题点数:0 回复次数:8 
逆波兰计算器(后缀计算器)
第一版本。
输入函数是个坑。
先就这样了,以后想到了再来改进输入函数。

有一点小BUG,如果最后的运算符是减号,必须手动加一个空格或者多按一下回车。
这是为了可以进行负数计算。
看来还得继续努力修正这个问题。

程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
typedef double OpType;
void
MakeStack( void );
void
DeleteStack( void );
void 
Push( OpType value );
OpType
Top( void );
int
IsEmpty( void );
int
IsFull( void );
int
GetOperand( void );


int
main( void )
{
    int ch;
    OpType op;

    MakeStack();

    while( EOF != ( ch = GetOperand() ) )
    {
        switch( ch )
        {
            case '+':
                Push( Top() + Top() );
                break;
            case '-':
                op = Top();
                Push(  Top() - op );
                break;
            case '*':
                Push( Top() * Top() );
                break;
            case '/':
                op = Top();
                Push( Top() / op );
                break;
            case '%':
                op = Top();
                Push( ( OpType )( ( int )Top() % ( int )op ) );
                break;
            case '\n':
                if( IsEmpty() )
                    break;
                printf( "%.2lf\n", Top() );
                DeleteStack();
                MakeStack();
                break;
            default:
                break;
        }
    }
    printf( "Bye.\n" );
    DeleteStack();
    
    return 0;
}

#define MAXSIZE 128
#include <ctype.h>

int
GetOperand( void )    
{
    int ch;
    int lx;
    char Temp[ MAXSIZE ];

    for( lx = 0; MAXSIZE - 1 > lx && EOF != ( ch = getchar() ); ++lx )
    {
        if( isdigit( ch ) || '.' == ch )
        {
            if( 0 == lx )
                Temp[ lx++ ] = '0';
            Temp[ lx ] = ch;
        }
        else if( '-' == ch )
        {
            if( 0 == lx )
                Temp[ lx ] = ch;
            else
                break;
        }
        else
            break;
    }

    Temp[ lx ] = '\0';

    if( 1 == strlen( Temp ) && '-' == Temp[ 0 ] )
        return Temp[ 0 ];

    if( 0 < lx )
        Push( atof( Temp ) );

    return ch;
}


#define INITSIZE 128
static OpType *Stack;
static int stacktop = -1;
static int CurrentSize = INITSIZE;


void
MakeStack( void )
{
    Stack = ( OpType * )malloc( CurrentSize * sizeof( OpType ) );
    assert( NULL != Stack );
}


void
DeleteStack( void )
{
    free( Stack );
    Stack = NULL;
    CurrentSize = INITSIZE;
    stacktop = -1;
}


void
Push( OpType value )
{
    assert( !IsFull() );
    Stack[ ++stacktop ] = value;
}


OpType
Top( void )
{
    assert( !IsEmpty() );
    return Stack[ stacktop-- ];
}


int
IsEmpty( void )
{
    return -1 == stacktop;
}


int
IsFull( void )
{
    OpType *Temp;

    if( stacktop == CurrentSize - 1 )
    {
        CurrentSize += INITSIZE;
        Temp = ( OpType * )realloc( Stack, CurrentSize * sizeof( OpType ) );
        if( NULL == Temp )
        {
            CurrentSize -= INITSIZE;
            return 1;
        }
        Stack = Temp;
        return 0;
    }
    else
        return 0;
}


[此贴子已经被作者于2017-4-7 20:58编辑过]

搜索更多相关主题的帖子: 计算器 
2017-04-07 18:18
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 2楼 九转星河
咦……似乎想到一块去了,我下一步正好就准备写一个将中缀转为后缀的计算器。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-07 18:43
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 4楼 九转星河
程序会崩溃是安全检查的,那说明你的输入有问题而导致栈为空。

我举个例子。

比如:1 + 2 * 5
你应该写成 1 2 5 * +

另外闲扯一句,中缀转后缀需要学习,我自己测试的时候都经常因为输入问题而崩溃。

[此贴子已经被作者于2017-4-7 18:57编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-07 18:52
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 4楼 九转星河
当然也不排除存在BUG,我只进行了量比较少的测试。
如果你能告诉我你的输入,我想我会容易定位到可能存在的BUG。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-07 18:54
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 8楼 九转星河
啊啊啊啊,果然是哪里。
你把GetOperand()函数 for()语句中的‘-’ == ch 去掉。然后删除掉if( '-' == ch && 0 != lx )

当时这样写为了可以进行负数计算。
看来负数方面我还得进行修正。

嗯嗯,减法有点小BUG,已经修正了,更新后的代码重新发在主楼。

负数问题,我先想想,先吃饭了。

[此贴子已经被作者于2017-4-7 19:36编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-07 19:32
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 10楼 九转星河
是很简单的了。
唯一坑的其实就是输入函数。
负数问题暂时解决了,但不够完美。输入最后一个运算符如果是‘-’的时候,必须手动加一个空格或者多按一个回车,才可以正常运作。
看来还得继续努力。

[此贴子已经被作者于2017-4-7 20:47编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-07 20:19
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 12楼 九转星河
减法问题我已经修正了,我在九楼说了呀。
减法的问题是我写反了。

[此贴子已经被作者于2017-4-8 01:41编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-08 00:54
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 12楼 九转星河
图片附件: 游客没有浏览图片的权限,请 登录注册


为什么会等于2,应该等于8才对啊。

5 6 3 - +

换算成中缀应该是 5 + ( 6 - 3)

我研究了一小会儿,没弄清楚问题出在哪儿。

[此贴子已经被作者于2017-4-8 01:27编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-08 01:09
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 15楼 九转星河
现在,我的脑子差不多跟浆糊似的,也许跟你的状态差不多。

完成了中缀计算器(实际上依旧存在圆括号嵌套的BUG),但是一点都不想动,脑子开动不了。

输入问题一直都是一个很大的问题,好吧,这句话我貌似说过很多很多次。

[此贴子已经被作者于2017-4-8 15:47编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-08 15:45
快速回复:逆波兰计算器(后缀计算器)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019517 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved