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

}

  

你可能感兴趣的:(topcoder)