zoukankan      html  css  js  c++  java
  • *[topcoder]BracketExpressions

    http://community.topcoder.com/stat?c=problem_statement&pm=13243

    就是能否通过把字符串中的'X'替换成"()", "[]", and "{}"来变成合法的括号字符串,

    "([]X()[()]XX}[])X{{}}]"
    Returns: "possible"
    You can replace 'X's respectively with '{', '(', ')' and '['.

    DFS搜索,Valid的判断使用stack。

    #include <stack>
    #include <vector>
    #include <string>
    using namespace std;
    
    class BracketExpressions {
    public:
    	string candidates;
    
        string ifPossible(string expression)
    	{
    		candidates = "()[]{}";
    		vector<int> xPos;
    		for (int i = 0; i < expression.length(); i++)
    		{
    			if (expression[i] == 'X')
    			{
    				xPos.push_back(i);
    			}
    		}
    		bool possible = ifPossRe(expression, 0, xPos);
    		if (possible)
    			return "possible";
    		else
    			return "impossible";
    	}
    	
    	bool isValid(const string &expression)
    	{
    		stack<char> stk;
    		for (int i = 0; i < expression.length(); i++)
    		{
    			if (stk.empty())
    			{
    				stk.push(expression[i]);
    			}
    			else if (match(stk.top(), expression[i]))
    			{
    				stk.pop();
    			}
    			else
    			{
    				stk.push(expression[i]);
    			}
    		}
    		return stk.empty();
    	}
    	
    	bool match(char a, char b)
    	{
    		if (a == '(' && b == ')') return true;
    		if (b == '(' && a == ')') return true;
    		if (a == '[' && b == ']') return true;
    		if (b == '[' && a == ']') return true;
    		if (a == '{' && b == '}') return true;
    		if (b == '{' && a == '}') return true;
    		return false;
    	}
    	
    	bool ifPossRe(string &expression, int idx, vector<int> &xPos)
    	{
    		if (idx == xPos.size())
    		{
    			return isValid(expression);
    		}
    		int n = xPos[idx];
    		for (int i = 0; i < candidates.length(); i++)
    		{
    			char ch = expression[n];
    			expression[n] = candidates[i];
    			bool res = ifPossRe(expression, idx+1, xPos);
    			expression[n] = ch;
    			if (res)
    				return true;
    		}
    		return false;
    	}
    };
    

    http://apps.topcoder.com/wiki/display/tc/SRM+628

    但其实判断Backet合法的代码是错的,因为没有判断先有左括号再有右括号,以下做法更好更简洁。

    bool correctBracket(string exp)
    {
        stack<char> s;
        // an assoicaitive array: opos[ ')' ] returns '(', opos[ ']' ] is '[', ...
        map<char,char> opos = {
            { ')', '(' },
            { ']', '[' },
            { '}', '{' },
        };
        for (char ch: exp) {
            // we push opening brackets to the stack
            if (ch == '(' || ch == '[' || ch == '{' ) {
                s.push(ch);
            } else {
                // If we find a closing bracket, we make sure it matches the
                // opening bracket in the top of the stack
                if (s.size() == 0 || s.top() != opos[ch]) {
                    return false;
                } else {
                    // then we remove it
                    s.pop();
                }
            }
        }
        // stack must be empty.
        return s.empty();
    }
    

    解法中还是用了基于6的幂来计算所有组合,比DFS要快。

    string ifPossible(string expression)
    {
        vector<int> x;
        int n = expression.size();
        for (int i = 0; i < n; i++) {
            if (expression[i] == 'X') {
                x.push_back(i);
            }
        }
        int t = x.size();
         
        // to easily convert to base 6 we precalculate the powers of 6:
        int p6[6];
        p6[0] = 1;
        for (int i = 1; i < 6; i++) {
            p6[i] = 6 * p6[i - 1];
        }
         
        const char* CHARS = "([{)]}";
        for (int m = 0; m < p6[t]; m++) {
            string nexp = expression;
            for (int i = 0; i < t; i++) {
                // (m / p6[i]) % 6 extracts the i-th digit of m in base 6.
                nexp[ x[i] ] = CHARS[ (m / p6[i]) % 6 ];
            }
            if (correctBracket(nexp)) {
                return "possible";
            }
        }
         
        return "impossible";
    }
    

      

  • 相关阅读:
    C#数组
    找不到命名空间命名空间:System.Windows.Forms
    WebService 的创建,部署和使用
    动态调用webservice时 ServiceDescriptionImporter类在vs2010无法引用的解决方法
    SQL语句新建表,同时添加主键、索引、约束
    SQLServer Ansi_Padding的用法
    浅析jQuery删除节点的三个方法
    C# JSON 序列化和反序列化——JavaScriptSerializer实现
    命令行启动tomcat,怎么配置
    ojective-c convert to pascal pattern
  • 原文地址:https://www.cnblogs.com/lautsie/p/3886024.html
Copyright © 2011-2022 走看看