facebook hacker cup 2013资格赛第二题

一个递归算法

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; 
    } 
}
posted @ 2013-02-26 22:52  ttang  阅读(416)  评论(0编辑  收藏  举报