• 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; 
        } 
    }
  • 相关阅读:
    为了兼容性问题,本人一律淘汰不兼容如下三种浏览器的js
    http://store.microsoft.com/home.aspx
    <转>JavaScript的IE和火狐的兼容性解决办法
    常用的正则表达式 我转与改的吧
    线程间操作无效: 从不是创建控件“textBox4”的线程访问它
    练习题 求a[i]到a[j]累积和为最大的部分
    自己写的操作记录的类,就是记录各种操作[原创]
    【MM系列】SAP MM中的委外加工与信息记录
    【MM系列】SAP MM模块-移动类型全部列表
    【MM系列】SAP MM模块-组织结构介绍
  • 原文地址:https://www.cnblogs.com/fstang/p/2934391.html
Copyright © 2020-2023  润新知