华为笔试题--LISP括号匹配 解析及源码实现
在17年校招中3道题目AC却无缘华为面试,大概是华为和东华互不待见吧!分享一道华为笔试原题,共同进步!
***************************************************************************************************************************************************************************
题目描述:
LISP语言唯一的语法就是括号要匹配。
形如(OP P1 P2 …),括号内元素由单个空格分割。
其中第一个元素OP为操作符,后续元素均为其参数,参数个数取决于操作符类型
注意:参数P1,P2也有可能是另外一个嵌套的(OP P1 P2 …)
其中OP类型为add/sub/mul/div(全小写),分别代表整数的加减乘除法
其中add/mul参数个数2或以上,sub/div参数个数为2
举例:
-输入:(mul 3 -7) 输出:-21
-输入:(add1 2 3) 输出:6
-输入:(sub (mul 2 4) (div 9 3)) 输出:5
-输入:(div 1 0) 输出:error
题目涉及数字均为整数,可能为负;不考虑32位溢出翻转
除零错误时,输出"error",除法遇除不尽,取整,即3/2=1
输入描述:
合法C字符串,字符串长度不超过512;用例保证了无语法错误
输出描述:
合法C字符串,字符包括'0'-'9'及负号'-'或者'error'
示例
输入 (add 1 2 3) 输出 6
*********************************************************
这是数据结构中括号匹配问题的变形。在检验括号是否匹配的方法中,可用“期待的急迫程度”这个概念来描述。在算法中设置了一个栈,每读入一个括号,若是右括号,则或者使置于栈顶的最急迫的期待得以消解,或者是不合法的情况;若是左括号,则作为一个新的更急迫的期待压入栈中,自然使原有的在栈中的所有未消解的期待的急迫性降了一级。另外,在算法的开始和结束时,栈都应该是空的。
同样的道理,针对LISP的括号匹配,我们不仅需要一个符号栈opstack去保存每一个括号里的操作符OP,还需要一个栈strstack去保存括号里的参数P1、P2及符号位。
从头到尾对输入的C字符串进行遍历,当遇到左括号"("时,将"("压入strstack中,其后的操作符压入opstack栈中;当遇到参数P时,通过字符串分割,放入strstack中;当遇到右括号")"时,在strstack栈中依次弹出参数,压入tmps栈,直到遇到"("为止,那么tmps中为一个不包含子括号参数列表,运算符为opstack的栈顶元素,其中根据操作符和参数可以进行加减乘除运运算,这部分不讨论。注意,运算结果需要在压入strstack栈中作为参数P。
如下图所示,以(sub (mul 2 4) (div 9 3))为例,在遇到第一个")"时,strstack中分别为{(,(,2,4},opstack中分别为{sub ,mul},则strstack中依次弹出4,2,(,运算符为opstack的栈顶元素mul,可以得到结果为8,其中运算结果再压入strstack中作为参数。
程序输入输出,运行结果示意图:
源码分享:
代码同步更新于 https://github.com/wylloong/TinyPrograms/blob/master/Coding%20Interviews/LISPGenerateParentheses.cpp
- #include <iostream>
- #include <algorithm>
- #include <string>
- #include <stack>
- #include <vector>
- #include <cstdio>
- #include <stdlib.h>
- #include <cstring>
- using namespace std;
- int main()
- {
- char chs[];
- bool error = false;
- gets_s(chs);
- //gets(chs); //old version
- std::string str(chs);
- std::stack<std::string> opstack; // operations
- std::stack<std::string> strstack; // divided strings
- for (int i = ; i < str.size();)
- {
- if (str[i] == ' ')
- {
- i = i + ;
- continue;
- }
- if (str[i] == '(')
- {
- strstack.push(std::string("("));
- int spaceIndex = str.find(' ', i);
- std::string tmp = str.substr(i + , spaceIndex - i - );
- opstack.push(tmp); // operation
- i = spaceIndex;
- }
- else if (str[i] == ')')
- {
- std::string curOp = opstack.top();
- opstack.pop();
- std::vector<std::string> tmps; // strs temp
- while (strstack.top() != "(")
- {
- tmps.push_back(strstack.top());
- strstack.pop();
- }
- strstack.pop();
- // add
- if (curOp == "add")
- {
- int temp = ;
- for (int i = ; i<=tmps.size() - ; ++i)
- {
- temp += atoi(tmps[i].c_str());
- }
- strstack.push(to_string(temp));
- }
- // sub
- else if (curOp == "sub")
- {
- int temp = ;
- if (tmps.size() > )
- temp = atoi(tmps[tmps.size() - ].c_str());
- for (int i = tmps.size() - ; i >= ; --i)
- {
- temp -= atoi(tmps[i].c_str());
- }
- strstack.push(to_string(temp));
- }
- // mul
- else if (curOp == "mul")
- {
- int temp = ;
- if (tmps.size() > )
- temp = atoi(tmps[tmps.size() - ].c_str());
- for (int i = tmps.size() - ; i >= ; --i)
- {
- temp *= atoi(tmps[i].c_str());
- }
- strstack.push(to_string(temp));
- }
- // div
- else if (curOp == "div")
- {
- int temp = ;
- if (tmps.size() > )
- temp = atoi(tmps[tmps.size() - ].c_str());
- for (int i = tmps.size() - ; i >= ; --i)
- {
- int data1 = atoi(tmps[i].c_str());
- if (data1 == )
- {
- error = true;
- break;
- }
- else
- temp /= data1;
- }
- if (error)
- break;
- else
- strstack.push(to_string(temp));
- }
- ++i;
- }
- else // substrs
- {
- // get substring by ' ' or ')'
- auto index = str.find(' ', i);
- auto index2= str.find(')', i);
- if (index < index2)
- {
- strstack.push(str.substr(i, index - i));
- i = index;
- }
- else
- {
- strstack.push(str.substr(i, index2 - i));
- i = index2;
- }
- }
- }
- if (error)
- cout << "error";
- else
- cout << atoi(strstack.top().c_str());
- return ;
- }
华为笔试题--LISP括号匹配 解析及源码实现的更多相关文章
- [算法2-数组与字符串的查找与匹配] (.NET源码学习)
[算法2-数组与字符串的查找与匹配] (.NET源码学习) 关键词:1. 数组查找(算法) 2. 字符串查找(算法) 3. C#中的String(源码) 4. 特性Attribute 与内 ...
- mvc5 解析route源码实现自己的route系统
Asp.net mvc5 解析route源码实现自己的route系统 url route 路由系统的责任是找到匹配的路由,创建路由数据,并将请求分配给一个处理程序. 选择动作是 MVC 的处理程序 ...
- 浩哥解析MyBatis源码(十)——Type类型模块之类型处理器
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6715063.html 1.回顾 之前的两篇分别解析了类型别名注册器和类型处理器注册器,此二 ...
- 解析 ViewTreeObserver 源码(下)
继上篇内容,本文介绍 ViewTreeObserver 的使用,以及体会其所涉及的观察者模式,期间会附带回顾一些基础知识.最后,我们简单聊一下 Android 的消息传递,附高清示意图,轻松捋清整个传 ...
- Jsoup解析网页源码时常用的Element(s)类
Jsoup解析网页源码时常用的Element(s)类 一.简介 该类是Node的直接子类,同样实现了可克隆接口.类声明:public class Element extends Node 它表示由一个 ...
- 用Beautiful Soup解析html源码
#xiaodeng #python3 #用Beautiful Soup解析html源码 html_doc = """ <html> <head> ...
- Python解析器源码加密系列之(二):一次使用标准c的FILE*访问内存块的尝试
摘要:由于近期打算修改Python解释器以实现pyc文件的加密/解密,出于保密的要求,解密之后的数据只能放在内存中,不能写入到文件中.但是后续的解析pyc文件的代码又只能接受FILE*作为入参,所以就 ...
- HtmlAgilityPack --解析Html源码
最近项目需要从网络上抓取一下数据解析Html源码,奈何正则表达式难写,于是网上搜索找到了“ HtmlAgilityPack”类库,敏捷开发,果然效率非同寻常. 在此做笔记,写下心得,顺便给自己总结一下 ...
- 二十三、并发编程之深入解析Condition源码
二十三.并发编程之深入解析Condition源码 一.Condition简介 1.Object的wait和notify/notifyAll方法与Condition区别 任何一个java对象都继承于 ...
随机推荐
- 201521123038 《Java程序设计》 第十一周学习总结
201521123038 <Java程序设计> 第十一周学习总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多 ...
- 201521123115《Java程序设计》第14周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自 ...
- Linux下的定时任务 - Cron服务
最近搞咕自己的笔记系统,虽然现在是个人的使用,对于数据库的数据还是比较少,但是安全还是一个我必须注意的东西. (特别是前段时间中了比特币的病毒之后,更是让我关注了我的主机的安全的问题.) 今天的随记是 ...
- 深度学习(一)cross-entropy softmax overfitting regularization dropout
一.Cross-entropy 我们理想情况是让神经网络学习更快 假设单模型: 只有一个输入,一个神经元,一个输出 简单模型: 输入为1时, 输出为0 神经网络的学习行为和人脑差的很多, 开始学习 ...
- python 浅析模块
今天买了一本关于模块的书,说实话,模块真的太多了,小编许多也不知道,要是把模块全讲完,可能得出本书了,所以小编在自己有限的能力范围内在这里浅析一下自己的见解,同时讲讲几个常用的模块. 首先说一下对模块 ...
- Could not execute JDBC batch update; SQL [delete from role where roleId=?]; constraint [null]; neste
今天在写多个删除功能的时候出现了这么一个错误:意思是删除操作的时候,没有找到对应的外键. Cannot delete or update a parent row: a foreign key con ...
- Hello PyQt5
在 ubuntu 系统上 GUI 编程,PyQt5 是个不错的选择.首先,当然是安装 PyQt5 了.终端输入命令: pip3 install PyQt5 即可. 1. 建立一目录 x01.PyQtH ...
- JS(三)
上周介绍了JS中两个比较重要的东西,循环和函数,这周再给大家介绍一下BOM和DOM 一.BOM 1.首先来说一下什么是BOM,BOM即浏览器对象模型,说白一点就是与浏览器进行的交互的对象模型. 2.B ...
- oracle 表查询(二)
1.使用逻辑操作符号问题:查询工资高于500或者是岗位为manager的雇员,同时还要满足他们的姓名首字母为大写的J?select * from emp where (sal > 500 or ...
- 1.在CentOS 6.4安装python3
CentOS安装Python3.X 1.系统环境说明 [root@Python ~]# uname -r 2.6.32-431.el6.i686 [root@Python ~]# uname -m i ...