Given a string representing arbitrarily nested ternary expressions, calculate the result of the expression. You can always assume that the given expression is valid and only consists of digits 0-9?:T and F (T and Frepresent True and False respectively).

Note:

  1. The length of the given string is ≤ 10000.
  2. Each number will contain only one digit.
  3. The conditional expressions group right-to-left (as usual in most languages).
  4. The condition will always be either T or F. That is, the condition will never be a digit.
  5. The result of the expression will always evaluate to either a digit 0-9T or F.

Example 1:

Input: "T?2:3"

Output: "2"

Explanation: If true, then result is 2; otherwise result is 3.

Example 2:

Input: "F?1:T?4:5"

Output: "4"

Explanation: The conditional expressions group right-to-left. Using parenthesis, it is read/evaluated as:

             "(F ? 1 : (T ? 4 : 5))"                   "(F ? 1 : (T ? 4 : 5))"
-> "(F ? 1 : 4)" or -> "(T ? 4 : 5)"
-> "4" -> "4"

Example 3:

Input: "T?T?F:5:3"

Output: "F"

Explanation: The conditional expressions group right-to-left. Using parenthesis, it is read/evaluated as:

             "(T ? (T ? F : 5) : 3)"                   "(T ? (T ? F : 5) : 3)"
-> "(T ? F : 3)" or -> "(T ? F : 5)"
-> "F" -> "F"

这道题让我们解析一个三元表达式,我们通过分析题目中的例子可以知道,如果有多个三元表达式嵌套的情况出现,那么我们的做法是从右边开始找到第一个问号,然后先处理这个三元表达式,然后再一步一步向左推,这也符合程序是从右向左执行的特点。那么我最先想到的方法是用用一个stack来记录所有问号的位置,然后根据此问号的位置,取出当前的三元表达式,调用一个eval函数来分析得到结果,能这样做的原因是题目中限定了三元表达式每一部分只有一个字符,而且需要分析的三元表达式是合法的,然后我们把分析后的结果和前后两段拼接成一个新的字符串,继续处理之前一个问号,这样当所有问号处理完成后,所剩的一个字符就是答案,参见代码如下:

解法一:

class Solution {
public:
string parseTernary(string expression) {
string res = expression;
stack<int> s;
for (int i = ; i < expression.size(); ++i) {
if (expression[i] == '?') s.push(i);
}
while (!s.empty()) {
int t = s.top(); s.pop();
res = res.substr(, t - ) + eval(res.substr(t - , )) + res.substr(t + );
}
return res;
}
string eval(string str) {
if (str.size() != ) return "";
return str[] == 'T' ? str.substr(, ) : str.substr();
}
};

下面这种方法也是利用栈stack的思想,但是不同之处在于不是存问号的位置,而是存所有的字符,将原数组从后往前遍历,将遍历到的字符都压入栈中,我们检测如果栈首元素是问号,说明我们当前遍历到的字符是T或F,然后我们移除问号,再取出第一部分,再移除冒号,再取出第二部分,我们根据当前字符来判断是放哪一部分进栈,这样遍历完成后,所有问号都处理完了,剩下的栈顶元素即为所求:

解法二:

class Solution {
public:
string parseTernary(string expression) {
stack<char> s;
for (int i = expression.size() - ; i >= ; --i) {
char c = expression[i];
if (!s.empty() && s.top() == '?') {
s.pop();
char first = s.top(); s.pop();
s.pop();
char second = s.top(); s.pop();
s.push(c == 'T' ? first : second);
} else {
s.push(c);
}
}
return string(, s.top());
}
};

下面这种方法更加简洁,没有用到栈,但是用到了STL的内置函数find_last_of,用于查找字符串中最后一个目前字符串出现的位置,这里我们找最后一个问号出现的位置,刚好就是最右边的问号,我们进行跟解法一类似的处理,拼接字符串,循环处理,参见代码如下:

解法三:

class Solution {
public:
string parseTernary(string expression) {
string res = expression;
while (res.size() > ) {
int i = res.find_last_of("?");
res = res.substr(, i - ) + string(, res[i - ] == 'T' ? res[i + ] : res[i + ]) + res.substr(i + );
}
return res;
}
};

参考资料:

https://discuss.leetcode.com/topic/64389/easy-and-concise-5-lines-python-java-solution

https://discuss.leetcode.com/topic/64409/very-easy-1-pass-stack-solution-in-java-no-string-concat/2

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Ternary Expression Parser 三元表达式解析器的更多相关文章

  1. Leetcode: Ternary Expression Parser

    Given a string representing arbitrarily nested ternary expressions, calculate the result of the expr ...

  2. java字符串应用之表达式解析器

    一.表达式的组成    1.数字    2.运算符:+ - / * ^ % =    3.圆括号    4.变量二.运算符优先级    由高到低分别为:+-(正负号).^.*/%.+-.=    优先 ...

  3. LeetCode 439. Ternary Expression Parser

    原题链接在这里:https://leetcode.com/problems/ternary-expression-parser/description/ 题目: Given a string repr ...

  4. Ternary Expression Parser

    Given a string representing arbitrarily nested ternary expressions, calculate the result of the expr ...

  5. [LeetCode] 282. Expression Add Operators 表达式增加操作符

    Given a string that contains only digits 0-9 and a target value, return all possibilities to add bin ...

  6. C 四则运算表达式解析器

    下载实例:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=1074 程序主要包括:基础结构定义.词法分析.语法分 ...

  7. [leetcode]282. Expression Add Operators 表达式添加运算符

    Given a string that contains only digits 0-9 and a target value, return all possibilities to add bin ...

  8. SPEL 表达式解析

    Spring Expression Language 解析器 SPEL解析过程 使用 ExpressionParser 基于 ParserContext 将字符串解析为 Expression, Exp ...

  9. Spring 缓存注解 SpEL 表达式解析

    缓存注解上 key.condition.unless 等 SpEL 表达式的解析 SpEl 支持的计算变量: 1)#ai.#pi.#命名参数[i 表示参数下标,从 0 开始] 2)#result:Ca ...

随机推荐

  1. 给jquery-validation插件添加控件的验证回调方法

    jquery-validation.js在前端验证中使用起来非常方便,提供的功能基本上能满足大部分验证需求,例如:1.内置了很多常用的验证方法:2.可以自定义错误显示信息:3.可以自定义错误显示位置: ...

  2. LCS记录

    如题:求两个序列的最长公共序列.(如:"ABCBDAB"与"BCDB"最长公共序列为"BCDB")代码如下: #define MAX_SIZ ...

  3. Rafy 框架-发布网页版用户手册

    前段时间把 Rafy 的用户手册由 CHM 格式转换为了网页格式,而且发布到了 github.io 上,即方便文档的实时更新,也方便大家查看. Rafy 用户手册网页版地址: http://zgynh ...

  4. Kafka消息时间戳(kafka message timestamp)

    最近碰到了消息时间戳的问题,于是花了一些功夫研究了一下,特此记录一下.   Kafka消息的时间戳 在消息中增加了一个时间戳字段和时间戳类型.目前支持的时间戳类型有两种: CreateTime 和 L ...

  5. 文字处理控件TX Text Control的使用

    这几天一直在研究TX Text Control的使用,由于这方面的资料相对比较少,主要靠下载版本的案例代码进行研究,以及官方的一些博客案例进行学习,使用总结了一些心得,特将其总结出来,供大家分享学习. ...

  6. C#开发微信门户及应用(25)-微信企业号的客户端管理功能

    我们知道,微信公众号和企业号都提供了一个官方的Web后台,方便我们对微信账号的配置,以及相关数据的管理功能,对于微信企业号来说,有通讯录中的组织架构管理.标签管理.人员管理.以及消息的发送等功能,其中 ...

  7. IT基础架构规划方案一(网络系统规划)

    背景                   某集团经过多年的经营,公司业务和规模在不断发展,公司管理层和IT部门也认识到通过信息化手段可以更好地支撑公司业务运营.提高企业生产和管理效率.同时随着新建办公 ...

  8. xinetd cpu 100%

    今天,有个给客户试用的环境出现xinetd cpu 100%,而且连续运行很长时间了.之前也有环境发生过,今天排查解决了三四个问题,实在是查的身体都不舒服了,还没时间查这个问题... 知道的求解...

  9. ORM是什么?如何理解ORM

    一.ORM简介         对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.简单的说,ORM是通过使 ...

  10. 【大前端之打通账号系统】passport应该如何落地?

    前言 之前接入百度账号系统的时候写了一篇博客做研究:[大前端]认识单点登录,出来后才发现,很多小公司其实并没有将账号系统打通,总结一下账号系统没通的原因是: ① 最初设计就没想过身份认证应该做整合 ② ...