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. vertical-align浅析

    一直以来都搞不懂vertical-align,它适用于什么元素,它的对齐规则是什么样的.索性查了下w3c相关规范,发现行高和基线对齐的规范说明里有如下内容: This section is being ...

  2. .Net语言 APP开发平台——Smobiler学习日志:Poplist控件的正确打开方式以及如何快速实现

    最前面的话:Smobiler是一个在VS环境中使用.Net语言来开发APP的开发平台,也许比Xamarin更方便 样式一 一.目标样式 我们要实现上图中的效果,需要如下的操作: 1.从工具栏上的&qu ...

  3. C# 视频编辑

    VidCoder VidCoder是一个开源免费的DVD/蓝光视频抓取和转码软件.使用HandBrake做为编码引擎.比Handbrake拥有更友好的用户界面. 可裁剪.剪切.字幕编辑.转码等. 官网 ...

  4. [Tool] Open Live Writer插件开发

    一 前言 Windows Live Writer(简称 WLW)开源之后变成 Open Live Writer(简称 OLW),原先 WLW 的插件在 OLW 下都不能用了,原因很简单,WLW 插件开 ...

  5. C#开发微信门户及应用(9)-微信门户菜单管理及提交到微信服务器

    微信公众号(包括服务号和订阅号)都可以对菜单进行自定义设置,我们为了方便管理,一般先把菜单数据在本地管理维护,需要更新的时候,把它们更新到微信服务器上就可以了.本文基于这个方式,介绍我的微信门户平台管 ...

  6. FunDA(0)- Functional Data Access accessible to all

    大数据.多核CPU驱动了函数式编程模式的兴起.因为函数式编程更适合多线程.复杂.安全的大型软件编程.但是,对许多有应用软件开发经验的编程者来说,函数式编程模式是一种全新的.甚至抽象的概念,可能需要很长 ...

  7. 节日来了发个HTML5红包

    效果图: 请关注微信公众号 何问起 , 账号ihewenqi ,或者微信扫描下图二维码: 关注后发送 愚人节 ,或 微信节日红包 ,可以体验效果. 代码如下: <!DOCTYPE html> ...

  8. 块级标签包含行内标签底部出现3px间隔的解决办法

    当块级标签(如div)内包含了行内标签(如img),则外层元素与内层元素底部会出现3px的间隔: 代码如下: <!doctype html> <html lang="en& ...

  9. 函数的使用顺序---TABLES,USING,CHANGING

    SAP使用PERFORM的时候: ... [TABLES   itab1 itab2 ...]     [USING    a1 a2 ...]     [CHANGING a1 a2 ...]. E ...

  10. 通过使用OpenVPN来构建一个VPN

    首先我们需要简单熟悉一下OpenVPN和VPN概念,方便我们在使用OpenVPN构建VPN时的操作~  VPN概述 VPN,即虚拟专用网络,其功能是:在公用网络上建立专用网络,进行加密通讯.在企业网络 ...