时间限制:50000ms
单点时限:5000ms
内存限制:256MB

描述

在lisp语言中,表达式都用前缀法表示,例如,1 + 2 在lisp中使用(+ 1 2)来表示,其中,表达式的括号是必需的。Bob 想实现一种类 lisp 的脚本语言,这个语言中的表达式是这样定义的:

1、每个表达式的形式都是 ( operator arg_1 arg_2 ... ),即由左括号,运算符,运算数,和右括号组成。

2、运算符包括三种,分别是'+', '-', '*'。

3、运算符如果可以接受一个运算数,就称为一元运算符,如果可以接受两个运算数,就称为二元运算符,如果可以接受三个及以上运算数,就称为多元运算符。

+ 可以是一元,二元,乃至多元运算符。

(+ 9) 表示正整数9;

(+ 1 2) 代表 1 + 2;

(+ 1 2 3 4) 代表 1, 2, 3, 4 的连加和。

- 可以是一元或者二元运算符。

(- 9) 表示整数-9;

(- 5 4) 代表 5 - 4。

* 可以是二元运算符或者多元运算符。

(* 2 3) 代表 2 * 3;

(* 1 2 3 4) 代表 1 * 2 * 3 * 4。

4、运算数可以是一个正整数,或者0,还可以是另外一个表达式,例如

(+ (* 2 3) 1) 也是一个合法的表达式,代表了 2 * 3 + 1

5、运算符与运算数之间,运算数与运算数相互之间都以空格进行分隔。在不产生歧义的情况下,空格也可以省略。例如,

(+ 2 3) 和 ( +2 3) 都被认为是合法的输入,且有相同的意义,代表 2 + 3。(+ 23)也是一个合法的输入,但其代表的是正整数23。

输入

输入由多行组成,第一行包含一个正整数T(T <= 5000)。代表共包含T组测试数据。

接下来会有T行输入。每一行包含一个表达式。这个表达式可能是一个合法的表达式,也可能是不合法的表达式。

每行数据所包含的字符数,不超过1000000。

输入数据中的数字全部是十进制正整数或者0,而且正整数的值不会大于65535。

输入中的表达式只包含三种不同类型的错误,除此之外的情况,都不必考虑。

第一类错误,括号不匹配,例如

(+ (* 2 3) 1)) 多了一个右括号;

+ 2 3 缺少括号等。

第二类错误,运算符缺失,例如

(2 3) 没有运算符。

第三类错误,运算符与数字不匹配,例如

(- 1 2 3),由于 - 只能接受最多两个算数,所以这也是一个不合法的表达式。

输出

对于合法的表达式,请输出表达式的值,对于不合法的表达式,请输出“invalid expression”。

可以假设最后的结果不超过32位整数的表示范围,但不保证在某些情况下,计算的中间值全部不超过32位整数的表示范围。

样例输入
5
(+ 1 (* 2 3)))
(2 3)
(- 3 2 1)
(+ (+ 1 2) (* 2 3) (- 2 1))
(- 2)
样例输出
invalid expression

invalid expression

invalid expression

10

-2

代码:
#include "stdafx.h"
#include <string>
#include <stdio.h>
#include <stack>
#include <iostream>

using namespace std;

int pow( int n)
{
    int result = 1 ;
    if (n == 0 )
    {
         return 1 ;
    }
    else {
         for ( int i = 0 ; i < n; ++i )
         {
            result *= 10 ;
         }
    }
    return result ;
}

int main()
{
    int n;
    string str;
    stack<char > temp;
    cin >> n ;
    cin.ignore (0x7fffffff, '\n');
    while (n--)
    {
        stack <int> num;
         bool hasnum = false;
        getline (cin, str);
         bool isexit = false;
         if ( str[0 ] != '(' )
         {
            cout << "invalid expression" << endl;
         }
         else
         {
             for ( int i = 0 ; i < str.length (); ++ i)
             {
                 if ( str[i ] == '(' )
                 {
                     if ( str[i + 1 ] != '+' && str[i + 1 ] != '-' && str[i + 1 ] != '*' ) {
                        cout << "invalid expression" << endl;
                        isexit = true ;
                         break;
                     }
                     else {
                        temp .push( str[i ]);
                     }
                 }
                 else if (str[i ] == ')' ) {
                     int multi = 0;
                     int count = 0;
                     int cnt = 0 ;
                     int subcount = 0;
                     bool isfirst = false;
                     int first = 0;
                     bool isback = false;
                     if ( temp.empty ())
                     {
                        cout << "invalid expression" << endl;
                        isexit = true ;
                         break;
                     }
                     while ( temp.size () > 0 && temp.top () != '(' )
                     {
                         if ( temp.top () >= '0' && temp.top () <= '9' )
                         {
                            hasnum = true ;
                            multi += ( temp.top () - '0' ) * pow(count );
                            count ++;
                            temp .pop();
                         }
                         else if (temp.top () == '#' )
                         {
                             if ( hasnum == true)
                             {
                                num .push( multi);
                                hasnum = false ;
                                multi = 0 ;
                                count = 0 ;
                                 if ( isfirst == false)
                                 {
                                    first = num. top();
                                    isfirst = true ;
                                 }
                             }

                            temp .pop();
                         }
                         else if (temp.top () == '+' )
                         {
                             int result = 0;
                             if ( hasnum == true)
                             {
                                num .push( multi);
                                hasnum = false ;
                                multi = 0 ;
                                count = 0 ;
                             }
                             while ( num.top () != first && num .size() > 1)
                             {
                                result += num. top();
                                num .pop();
                             }
                            result += num. top();
                            num .pop();

                            num .push( result);
                            temp .pop();
                            isback = true ;
                         }
                         else if (temp.top () == '-' )
                         {
                             int result = 0;
                             if ( hasnum == true)
                             {
                                num .push( multi);
                                hasnum = false ;
                                multi = 0 ;
                                count = 0 ;
                             }
                             int a[ 2] = { 0 };
                             while ( num.top () != first && num .size() > 1)
                             {
                                subcount ++;
                                a [0] = num.top ();
                                num .pop();
                             }
                             if ( subcount == 1)
                             {
                                a [1] = num.top ();
                                num .pop();
                                 if ( a[1] == first)
                                 {
                                    result = a[ 0] - a[ 1];
                                 }
                                 else
                                    result = a[ 1] - a[ 0];
                             }
                             else if (subcount >= 2) {
                                cout << "invalid expression" << endl;
                                isexit = true ;
                                 break;
                             }
                             else {
                                result = 0 - num.top ();
                                num .pop();
                             }
                            subcount = 0 ;
                            num .push( result);
                            temp .pop();
                            isback = true ;
                         }
                         else if (temp.top () == '*' )
                         {
                             int result = 1;
                             if ( hasnum == true)
                             {
                                num .push( multi);
                                hasnum = false ;
                                multi = 0 ;
                                count = 0 ;
                             }
                             if ( num.size ())
                             {
                                 while ( num.top () != first&& num .size() > 1)
                                 {
                                    result *= num. top();
                                    num .pop();
                                 }
                                result *= num. top();
                                num .pop();
                             }
                             else
                             {
                                cout << "invalid expression" << endl;
                                isexit = true ;
                                 break;
                             }
                            subcount = 0 ;
                            num .push( result);
                            temp .pop();
                            isback = true ;
                         }
                     }
                    temp .pop();
                 }
                 else {
                     if ( str[i ] == ' ' )
                     {
                        temp .push( '#');
                     }
                     else
                        temp .push( str[i ]);
                 }
             }
         }

         if (! isexit)
         {
             if (! temp.empty ())
             {
                cout << "invalid expression" << endl;
                 break;
             }
             if ( num.size () == 1 )
             {
                cout << num. top() << endl;
             }

         }

    }
    return 0;
}

【面试笔试算法】Program 3 : Complicated Expression(网易游戏笔试题)的更多相关文章

  1. 【面试笔试算法】Program 2:Amusing Digits(网易游戏笔试题)

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 网易成立于1997年6月,是中国领先的互联网技术公司.其相继推出了门户网站.在线游戏.电子邮箱.在线教育.电子商务等多种服 ...

  2. 【面试笔试算法】Program 5 : 推箱子 (网易游戏笔试题)

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 推箱子是一款经典游戏.如图所示,灰色格子代表不能通过区域,蓝色方格是箱子,黑色圆形代表玩家,含有圆点的格子代表目标点. 规 ...

  3. 【面试笔试算法】Program 4 : Best Compression Algorithms(网易游戏笔试题)

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 易信是由网易和电信联合开发的一款即时通讯软件.除了语音聊天,免费电话等新功能以外,传统的文字信息聊天功能也得以保留,因此每 ...

  4. 【面试笔试算法】Program 6: 字符消除(hiho题库)

    时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi最近在玩一个字符消除游戏.给定一个只包含大写字母"ABC"的字符串s,消除过程是如下进行的: 1) ...

  5. 【面试笔试算法】Problem 1 : DP滑雪问题--网易互联网算法实习生2017笔试题

    Description Michael喜欢滑雪百这并不奇怪,因为滑雪的确很刺激.可是 为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道 ...

  6. 【面试笔试算法】Problem 9: 腾讯2016年研发实习笔试题:最长回文子串

    (一)题目 问题:求给定字符串s的回文(palindrome)子串中,长度最大的回文子串的长度. 回文(palindrome)是指从左往右读和从右往左读字符串,看到的字符串都是一样的.比如" ...

  7. 【面试笔试算法】牛客网一站通Offer编程题2016.4.19

    牛客网一站通offer (一)字符串变形 1. 题目: 对于一个给定的字符串,我们需要在线性(也就是O(n))的时间里对它做一些变形.首先这个字符串中包含着一些空格,就像"Hello Wor ...

  8. 【面试笔试算法】Problem 8: 然而沼跃鱼早就看穿了一切(hiho题库)

    时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 fjxmlhx每天都在被沼跃鱼刷屏,因此他急切的找到了你希望你写一个程序屏蔽所有句子中的沼跃鱼("marshtom ...

  9. 【面试笔试算法】Problem 7: 补提交卡(hiho题库)

    时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho给自己定了一个宏伟的目标:连续100天每天坚持在hihoCoder上提交一个程序.100天过去了,小Ho查看自己的提交 ...

随机推荐

  1. ML学习分享系列(1)_计算广告小窥[上]

    原作:面包包包包包包 修改:寒小阳 && 龙心尘 时间:2016年1月 出处: http://blog.csdn.net/breada/article/details/50572914 ...

  2. ubuntu垃圾清理命令

    ubuntu的空间莫名不够用了 通过系统自带的工具磁盘使用分析器,发现var文件下面的log100多个g,这个日志文件是可以删除的,然后tmp文件也是可以删除的. 1.sudo rm -rf /tmp ...

  3. ghmm在 Linux 上安装

    ghmm在 Linux 上安装 http://ghmm.sourceforge.net/documentation.html http://www.ghmm.org http://www.comp.l ...

  4. Dynamics CRM2016 新功能之从CRM APP通过电子邮件发送页面链接

    通过电子邮件发送页面链接在PC端早就有了,但APP端却始终没有,这版加上了这个功能,这里还是以case为例,发送页面链接的方式有两种 第一种在list界面,长按你要share的数据,会出来选项shar ...

  5. 第一行代码阅读笔记---AndroidMainfest.xml分析

    按照这本书的指引,我随作者一样创建了一个安卓应用,开始了安卓开发的启程. 找到AndroidMainfest.xml这个文件,打开后看到了我创建的Activity在这个文件里被成功注册,文件内容如下: ...

  6. Linux的sleep()和usleep()

    1.sleep和usleep都是linux中的程序挂起函数.只是时间的单位不一样. 2. sleep的基本单位是s(秒),也可以用m(分).h(小时). 例: sleep 1 : 挂起1秒 sleep ...

  7. C++对象模型的那些事儿之三:默认构造函数

    前言 继前两篇总结了C++对象模型及其内存布局后,我们继续来探索一下C++对象的默认构造函数.对于C++的初学者来说,有如下两个误解: 任何class如果没有定义default constructor ...

  8. (九十四)集成PKRevealController实现左右抽屉视图

    使用PKRevealController可以实现类似于QQ等软件的左右抽屉视图,拖出的视图分为leftView和rightView,分别取自View的左半部分和右半部分,因此,根据不同的需求,可以选择 ...

  9. 从Eclipse插件中读取资源

    可以通过Eclipse里的OSGi的Bundle类,获取插件目录下的某个文件的输入流: 1. Bundle bundle = Platform.getBundle(Activator.PLUGIN_I ...

  10. cocos2d-js(一)引擎的工作原理和文件的调用顺序

    Cocos2d-js可以实现在网页上运行高性能的2D游戏,实现原理是通过HTML5的canvas标签,该引擎采用Javascript编写,并且有自己的一些语法,因为没有成熟的IDE,一般建立工程是通过 ...