【面试笔试算法】Program 3 : Complicated Expression(网易游戏笔试题)
描述
在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
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(网易游戏笔试题)的更多相关文章
- 【面试笔试算法】Program 2:Amusing Digits(网易游戏笔试题)
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 网易成立于1997年6月,是中国领先的互联网技术公司.其相继推出了门户网站.在线游戏.电子邮箱.在线教育.电子商务等多种服 ...
- 【面试笔试算法】Program 5 : 推箱子 (网易游戏笔试题)
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 推箱子是一款经典游戏.如图所示,灰色格子代表不能通过区域,蓝色方格是箱子,黑色圆形代表玩家,含有圆点的格子代表目标点. 规 ...
- 【面试笔试算法】Program 4 : Best Compression Algorithms(网易游戏笔试题)
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 易信是由网易和电信联合开发的一款即时通讯软件.除了语音聊天,免费电话等新功能以外,传统的文字信息聊天功能也得以保留,因此每 ...
- 【面试笔试算法】Program 6: 字符消除(hiho题库)
时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi最近在玩一个字符消除游戏.给定一个只包含大写字母"ABC"的字符串s,消除过程是如下进行的: 1) ...
- 【面试笔试算法】Problem 1 : DP滑雪问题--网易互联网算法实习生2017笔试题
Description Michael喜欢滑雪百这并不奇怪,因为滑雪的确很刺激.可是 为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道 ...
- 【面试笔试算法】Problem 9: 腾讯2016年研发实习笔试题:最长回文子串
(一)题目 问题:求给定字符串s的回文(palindrome)子串中,长度最大的回文子串的长度. 回文(palindrome)是指从左往右读和从右往左读字符串,看到的字符串都是一样的.比如" ...
- 【面试笔试算法】牛客网一站通Offer编程题2016.4.19
牛客网一站通offer (一)字符串变形 1. 题目: 对于一个给定的字符串,我们需要在线性(也就是O(n))的时间里对它做一些变形.首先这个字符串中包含着一些空格,就像"Hello Wor ...
- 【面试笔试算法】Problem 8: 然而沼跃鱼早就看穿了一切(hiho题库)
时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 fjxmlhx每天都在被沼跃鱼刷屏,因此他急切的找到了你希望你写一个程序屏蔽所有句子中的沼跃鱼("marshtom ...
- 【面试笔试算法】Problem 7: 补提交卡(hiho题库)
时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho给自己定了一个宏伟的目标:连续100天每天坚持在hihoCoder上提交一个程序.100天过去了,小Ho查看自己的提交 ...
随机推荐
- Android输入控件详解
输入控件 输入控件是您的应用用户界面中的交互式组件.Android 提供了多种可在 UI 中使用的控件,如按钮.文本字段.定位栏.复选框.缩放按钮.切换按钮等. 向 UI 中添加输入控件与向 XML ...
- Android源码浅析(六)——SecureCRT远程连接Linux,配置端点和字节码
Android源码浅析(六)--SecureCRT远程连接Linux,配置端点和字节码 需要编译源码的同学,一般都是win+虚拟机吧,但是再虚拟机里体验并不是很好,所有市面上有很多的软件能够做到在wi ...
- springMVC源码分析--ControllerBeanNameHandlerMapping(八)
在上一篇博客springMVC源码分析--AbstractControllerUrlHandlerMapping(六)中我们介绍到AbstractControllerUrlHandlerMapping ...
- Java并发框架——什么是AQS框架
什么是AQS框架 1995年sun公司发布了第一个java语言版本,可以说从jdk1.1到jdk1.4期间java的使用主要是在移动应用和中小型企业应用中,在此类领域中基本不用设计大型并发场景,当然也 ...
- java类加载器——ClassLoader
Java的设计初衷是主要面向嵌入式领域,对于自定义的一些类,考虑使用依需求加载原则,即在程序使用到时才加载类,节省内存消耗,这时即可通过类加载器来动态加载. 如果你平时只是做web开发,那应该很少会跟 ...
- x264源代码简单分析:x264_slice_write()
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- 有两个序列A和B,A=(a1,a2,...,ak),B=(b1,b2,...,bk),A和B都按升序排列。对于1<=i,j<=k,求k个最小的(ai+bj)。要求算法尽量高效。
有两个序列A和B,A=(a1,a2,...,ak),B=(b1,b2,...,bk),A和B都按升序排列.对于1<=i,j<=k,求k个最小的(ai+bj).要求算法尽量高效. int * ...
- Android简易实战教程--第二十三话《绚丽的菜单项》
转载本博客请注明出处:点击打开链接 http://blog.csdn.net/qq_32059827/article/details/52327456 今天这篇稍微增强点代码量,可能要多花上5分钟喽 ...
- Linux命令—文件目录
(1) shell的使用 <1>检查系统当前运行的shell版本: [root@lab root]# echo $SHELL <2>从当前shell下切换到csh: [r ...
- java中的interface接口
接口:java接口是一些方法表征的集合,但是却不会在接口里实现具体的方法. java接口的特点如下: 1.java接口不能被实例化 2.java接口中声明的成员自动被设置为public,所以不存在pr ...