在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. 201521123114 《Java程序设计》第3周学习总结

    1. 本章学习总结 2. 书面作业 Q1.代码阅读 以上代码可否编译通过?哪里会出错?为什么?尝试改正? 如果创建3个Test1对象,有内存中有几个i,几个j?请分析原因? 不能编译通过,Test1g ...

  2. 201521123105 第三周Java学习总结

    1. 本周学习总结 对象(实际个体) 对象与类 类(模板) 2.书面作业 1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private ...

  3. 201521123055 《Java程序设计》第2周学习总结

     1. 本章学习总结 (1)认识PATH和CLASSPATH (2)SET PATH/CLASSPATH和-cp的用法 (3)了解BigDecimal.BigInteger.ArrayList/Lis ...

  4. 201521123035《Java程序设计》第一周学习总结

     1.本周学习总结 本周学习了Java从诞生到如今的部分历史,并通过了老师的课堂演示了解了Java在cmd中的编译过程.然后还学习了JDK,JRE,JVM. 2. 书面作业 1.为什么java程序可以 ...

  5. VBScript中Msgbox函数的用法

    MsgBox(prompt[, buttons][, title][, helpfile, context]) [用途]:弹出对话框,并获取用户的操作结果. [参数说明]: propmt:对话框中展示 ...

  6. 201521123063 《Java程序设计》 第14周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图.Onenote或其他)归纳总结多数据库相关内容. 2. 书面作业 1. MySQL数据库基本操作 1.1 建立数据库test.表students. ...

  7. 201521123030 《Java程序设计》 第14周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自 ...

  8. Markdown 模板

    一个例子: 例子开始 1. 本章学习总结 今天主要学习了三个知识点 封装 继承 多态 2. 书面作业 Q1. java HelloWorld命令中,HelloWorld这个参数是什么含义? 今天学了一 ...

  9. java web:在eclipse中如何创建java web 项目

    Eclipse创建java web工程 eclipse版本:eclipse-jee-4.5-win32-x64 tomcat版本:apache-tomcat-7.0.63-windows-x64 jd ...

  10. 微信小程序购物车产品计价

    微信小程序购物车产品计价: 问题:当选中商品,价格累加时会出现无限循环小数 解答:在计算前先parseFloat(变量),再计算的最后使用(变量).toFixed(2)保留两位小数 例如: jiaCa ...