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. java笔记--理解java类加载器以及ClassLoader类

    类加载器概述: java类的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类加载机制 ...

  2. 你真的会玩SQL吗?无处不在的子查询

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  3. 线程安全性:num++操作为什么也会出问题?

    线程的安全性可能是非常复杂的,在没有充足同步的情况下,由于多个线程中的操作执行顺序是不可预测的,甚至会产生奇怪的结果(非预期的).下面的Tools工具类的plus方法会使计数加一,为了方便,这里的nu ...

  4. 5.在MVC中使用泛型仓储模式和工作单元来进行增删查改

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...

  5. fastjson-alibaba

    fastjson使用 package com.alibaba.json.demo; import org.junit.Assert; import com.alibaba.fastjson.JSON; ...

  6. Docker的ubuntu镜像安装的容器无ifconfig和ping命令的解决

    Docker的Ubuntu镜像安装的容器无ifconfig命令和ping命令 解决: apt-get update apt install net-tools       # ifconfig apt ...

  7. javaweb

    关于java,作为一个初学者,作为一个即将跨入其中的钻研者,我觉得我很必要好好地升入其中认真学习每一个环节

  8. 《连载 | 物联网框架ServerSuperIO教程》- 6.并发通讯模式开发及注意事项

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

  9. linux之cp/scp命令+scp命令详解

    名称:cp 使用权限:所有使用者 使用方式: cp [options] source dest cp [options] source... directory 说明:将一个档案拷贝至另一档案,或将数 ...

  10. 解决motools和jquery之间的冲突

    在同一个页面需要同时使用motools和jquery,对于$,发生了冲突,以下是解决的办法. <head> <script src="./Scripts/lib/jquer ...