*[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";
}

  

posted @ 2014-08-01 23:50  阿牧遥  阅读(177)  评论(0编辑  收藏  举报