在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括号匹配 解析及源码实现的更多相关文章

  1. [算法2-数组与字符串的查找与匹配] (.NET源码学习)

    [算法2-数组与字符串的查找与匹配] (.NET源码学习) 关键词:1. 数组查找(算法)   2. 字符串查找(算法)   3. C#中的String(源码)   4. 特性Attribute 与内 ...

  2. mvc5 解析route源码实现自己的route系统

    Asp.net mvc5 解析route源码实现自己的route系统   url route 路由系统的责任是找到匹配的路由,创建路由数据,并将请求分配给一个处理程序. 选择动作是 MVC 的处理程序 ...

  3. 浩哥解析MyBatis源码(十)——Type类型模块之类型处理器

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6715063.html 1.回顾 之前的两篇分别解析了类型别名注册器和类型处理器注册器,此二 ...

  4. 解析 ViewTreeObserver 源码(下)

    继上篇内容,本文介绍 ViewTreeObserver 的使用,以及体会其所涉及的观察者模式,期间会附带回顾一些基础知识.最后,我们简单聊一下 Android 的消息传递,附高清示意图,轻松捋清整个传 ...

  5. Jsoup解析网页源码时常用的Element(s)类

    Jsoup解析网页源码时常用的Element(s)类 一.简介 该类是Node的直接子类,同样实现了可克隆接口.类声明:public class Element extends Node 它表示由一个 ...

  6. 用Beautiful Soup解析html源码

    #xiaodeng #python3 #用Beautiful Soup解析html源码 html_doc = """ <html> <head> ...

  7. Python解析器源码加密系列之(二):一次使用标准c的FILE*访问内存块的尝试

    摘要:由于近期打算修改Python解释器以实现pyc文件的加密/解密,出于保密的要求,解密之后的数据只能放在内存中,不能写入到文件中.但是后续的解析pyc文件的代码又只能接受FILE*作为入参,所以就 ...

  8. HtmlAgilityPack --解析Html源码

    最近项目需要从网络上抓取一下数据解析Html源码,奈何正则表达式难写,于是网上搜索找到了“ HtmlAgilityPack”类库,敏捷开发,果然效率非同寻常. 在此做笔记,写下心得,顺便给自己总结一下 ...

  9. 二十三、并发编程之深入解析Condition源码

    二十三.并发编程之深入解析Condition源码   一.Condition简介 1.Object的wait和notify/notifyAll方法与Condition区别 任何一个java对象都继承于 ...

随机推荐

  1. 201521123071 《JAVA程序设计》第四周学习总结

    1. 本周学习总结 1.1 1.2 在本周的学习中,主要学习了以下几点: 注释的应用,并能在Eclipse中查看 继承的基本定义,关键字super的用法,覆盖与重载 多态与is-a,instanceo ...

  2. 201521123098 《Java程序设计》第1周学习总结

    1. 本章学习总结 在本章的学习中,我和当初学习C语言一样由"Hello world"入手,初步了解了: 1. *NotePad++*的文件创建和编写*Hello world.ja ...

  3. 201521123032 《Java程序设计》第3周学习总结(编辑器修改后)

    本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用思维导图将这些碎片化的概念.知识组织起来.请使用纸笔或者下面的工具画出本周学习到的知识点.截图或者拍照上传. 书面作业 代码阅读 ...

  4. Eclipse rap 富客户端开发总结(5): RAP国际化之路

    Eclipse RCP 中的plugin.xml国际化实现 1.  在工程的根目录下面建立一个plugin.properties资源文件:在此资源文件中写入需要国际化的内容(键/值对),举例如下: h ...

  5. SIT 和 UAT

    在企业级软件的测试过程中,经常会划分为三个阶段--单元测试,SIT和UAT,如果开发人员足够,通常还会在SIT之前引入代码审查机制(Code Review)来保证软件符合客户需求且流程正确.下面简单介 ...

  6. 一篇搞定微信分享和line分享

    前言 在h5的页面开发中,分享是不可或缺的一部分,对于一些传播性比较强的页面,活动页之类的,分享功能极为重要.例如,京东等电商年末时会有一系列的总结h5在微信中传播,就不得不提到微信的分享机制. 微信 ...

  7. 初识Hibernate之环境搭建

         相信所有做后端的程序员同行们,没有不知道Hibernate大名的.这是一个经典的轻量级Java EE持久层的解决方案,它使得我们程序员能以面向对象的思维操作传统的关系型数据库,这也是其存在的 ...

  8. Centos7环境下使用Nginx托管.Net Core应用程序

    一.安装.Net Core 参考官方文档:https://www.microsoft.com/net/core#linuxcentos 1.添加dotnet产品Feed 在安装.NET Core之前, ...

  9. Egg + Vue 服务端渲染工程化实现

    在实现 egg + vue 服务端渲染工程化实现之前,我们先来看看前面两篇关于Webpack构建和Egg的文章: 在 Webpack工程化解决方案easywebpack 文章中我们提到了基于 Vue ...

  10. mysql客户端(Navicat)远程登录操作遇到问题1142

    遇到此问题的原因是:用户user对数据库test 无权限操作. 解决方法:mysql> grant all privileges on test.* to user@'localhost' id ...