您的位置:首页 > 其它

facebook hacker cup 2013资格赛第二题

2013-02-26 22:52 357 查看
一个递归算法

bool isbalance(字符串s,未匹配的左括号数unmatched, 当前要考察的字符位置idx)

(1)考察字符串s从idx开始到末尾的子字符串,若为空或只包含一个字符,讨论可得,是边界情况

(2)否则,考察子字符串前两个字符,即s[idx]和s[idx+1],如果是笑脸或哭脸,考虑两种可能性,解释为表情或左右括号,记录未匹配的左括号数;若为其他字符,相应考虑unmatched是否改变,idx加1或2,递归

(递归函数保证:当s[idx] == ‘)’或’(’时,s[idx-1]不为’:’,即处理从idx开始的子字符串时,不必考虑s[idx-1])

下面是完整代码:

#include <stdio.h>
#include <string>
#include <iostream>
using namespace std;
bool isbalance(string &s, int unmatched, int idx)
{
if(idx >= s.length()){
if (unmatched == 0) {
return true;
} else {
return false;
}
}else if (idx == s.length() - 1) {
if (s[idx] == '(') {
return false;
}else if(s[idx] == ')'){
if(unmatched == 1){
return true;
}else{
return false;
}
}else{
if (unmatched == 0) {
return true;
} else {
return false;
}
}
}else{//have at least two chars
if (s[idx] == ':') {
if (s[idx + 1] == ':') {
return isbalance(s, unmatched, idx + 1);
} else if(s[idx + 1] == '('){
return isbalance(s, unmatched, idx + 2) || isbalance(s, unmatched + 1, idx + 2);
} else if (s[idx + 1] == ')') {
if (unmatched == 0) {
return isbalance(s, unmatched, idx + 2);
} else {
return isbalance(s, unmatched, idx + 2) || isbalance(s, unmatched - 1, idx + 2);
}
} else {
return isbalance(s, unmatched, idx + 2);
}
}else if (s[idx] == '(') {
return isbalance(s, unmatched + 1, idx + 1);
}else if(s[idx] == ')'){
if (unmatched == 0) {
return false;
}else{
return isbalance(s, unmatched - 1, idx + 1);
}
}else{
return isbalance(s, unmatched, idx + 1);
}
}
}
//保证当s[idx] == ')'或'('时,s[idx-1] != ':'
int main(int argc, const char *argv[])
{
freopen("balanced_smileystxt.txt", "r", stdin);
freopen("out2.txt", "w", stdout);
int T;
string s;
cin >> T;
getline(cin, s);
for (int i = 1; i <= T; i++) {
getline(cin, s);
if (isbalance(s, 0, 0)) {
printf("Case #%d: YES\n", i);
}else {
printf("Case #%d: NO\n", i);
}
}
return 0;
}


 

一个线性算法

记左括号、哭脸‘:(’、右括号、笑脸’:)’个数分别为left, lface, right, rface

总是优先识别为笑脸和哭脸

从左到右扫描字符串,

(1)每次遇到左括号,left++;

(2)每次遇到lface,lface++

(3)每次遇到一个右括号可以直接让左括号--(如果左括号个数>0),如果此时左括号为0,让lface--(如果lface>0),否则,不平衡

(4)每次遇到rface,如果left和lface都为0,什么也不做(rface表示能够解释为右括号的笑脸的个数),否则,rface++

所以关键是为每个右括号配上左括号,和为每个左括号配上一个右括号;当“不构成笑脸“的右括号出现的时候,立即配对;最后检查左括号能否成功配对:left小于等于可以解释为右括号的笑脸数,即left<=rface

(因此,实际上right变量基本用不到)

 

bool isbalance(string s)
{
int left = s[0] == '(', right = s[0] == ')', lface = 0, rface = 0;
if (right == 1) {
return false;
}
for (int i = 1; i < s.length(); i++) {
switch (s[i]){
case '(':
if (s[i - 1] == ':') {
lface++;
} else {
left++;
}
break;
case ')':
if (s[i - 1] == ':') {
if (left != 0 || lface != 0) {//means that this ':)' can be interpreted as ':' and ')'
rface++;
}//else do nothing
} else {
if (left > 0) {
left--;
} else {//left==0
if (lface > 0) {
lface--;
} else {//lface == 0
return false;
}
}
}
break;
}
}
//至此,右括号均匹配成功
if (left <= rface) {//左括号也匹配成功
return true;
} else {
return false;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: