首页 > 试题广场 >

表达式合法判断

[编程题]表达式合法判断
  • 热度指数:8148 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
写一段代码,判断一个包括'{','[','(',')',']','}'的表达式是否合法(注意看样例的合法规则。)
可以看到一个合法的表达式,左括号和右括号必须相互对应。
请注意:1+(2-[3*1)] 这种表达式是不合法的!

给定一个表达式A,请返回一个bool值,代表它是否合法。

测试样例1:
"[a+b*(5-4)]*{x+b+b*(({1+2}))}"
返回:true
测试样例2:
"q*c*k+r-w-{f-e*c+f}"
返回:true
测试样例3:
"g+{p+z-v"
返回:false


不考虑左右括号是否匹配,也不考虑括号内是否由数字,如:2+1*2+()+5*{) 这样的也合法,醉 了
下面注释去除测试不过
 import java.util.*;

public class ChkExpression {
    public boolean chkLegal(String A) {
        // write code here
      
        Stack<Character> stack = new Stack<Character>();
        HashMap<Character,Character> map = new HashMap<Character,Character>();
        map.put('[',']');
        map.put('{','}');
        map.put('(',')');
        for(int i =0;i<A.length();i++){
            char ch = A.charAt(i);
            if(map.containsKey(ch)){
                stack.push(ch);
            }else if(map.containsValue(ch)){
                if(stack.isEmpty())
                    return false;
                char top = stack.peek();
               // if(map.get(top).equals(ch)){
                    stack.pop();
               // }else{
                //    return false;
                //}
            }
        }
        return stack.isEmpty();
    }
}
发表于 2016-03-30 22:08:17 回复(9)

题目也是醉了 测试样例明明就错的
他的意思是左右括号数量相同就ok 头皮发麻

这根本用不到栈 还是把栈搞出来做做样子
注释掉的为正常的解即 每种括号的左括号必须与他的右括号匹配
class ChkExpression {
public:
    const string dic = "{[(}])";
    bool chkLegal(string A) {
        stack<int> s;
        for(int i = 0; i < A.length(); i++)
            if(dic.find(A[i]) != -1){
                if(s.empty()) s.push(dic.find(A[i]));
                else{
                    int a = s.top();
                    if(a < 3 && dic.find(A[i]) >= 3) s.pop();
                    //if(a + 3 == dic.find(A[i])) s.pop();
                    else s.push(dic.find(A[i]));
                }
            }
        if(s.empty()) return true;
        return false;
    }
};
编辑于 2018-10-10 10:28:39 回复(0)
刚开始想复杂了,这题没有这么复杂,就是让左括号(不管大中小)的数量等于右括号(不管大中小)的数量就行
import java.util.*;

public class ChkExpression {
   public static boolean chkLegal(String A) {
		StringBuffer sb = new StringBuffer(A);
		int length = sb.length();
		Stack<Character> s = new Stack<Character>();
		for (int i = 0; i < length; i++) {
			char c = sb.charAt(i);
			if (c == '{' || c == '['  || c == '(' ){
				s.push(c);
			}	
			if ( c == '}'   || c == ']'  || c == ')'){
				s.pop();
			}	
		}
		if(s.isEmpty())
			return true;
		return false;
	}
}

发表于 2016-06-24 15:35:40 回复(7)
这个题目只考虑了{},()及[]左右是否配套使用,没有考虑其他很多语法问题,练手而已,不用钻牛角尖的。
class ChkExpression {
public:
    bool chkLegal(string A) {
         // write code here
         int n=A.length();
         int f1=0,f2=0,f3=0;
         for(int i=0;i<n;i++)
             if(A[i]=='{')
                 f1++;
             else if(A[i]=='}')
                 f1--;
             else if(A[i]=='[')
                 f2++;
             else if(A[i]==']')
                 f2--;
             else if(A[i]=='(')
                 f3++;
             else if(A[i]==')')
                 f3--;                   
         if(f1==0&&f2==0&&f3==0)
             return true;
        else
            return false;           
    }
};

发表于 2017-04-18 20:48:26 回复(0)
//注意看题目给的样子本来就不是严格匹配。题目的样例里{和)也能匹配
import java.util.*;

public class ChkExpression {
    public boolean chkLegal(String A) {
        // write code here
        //凡是遇到右边的括号就将前一个弹出
        ArrayDeque<Character> stack = new ArrayDeque<Character>();
        for(int i=0;i<A.length();i++){
            if(A.charAt(i)=='{' || A.charAt(i)=='[' || A.charAt(i)=='('){
                stack.push(A.charAt(i));
            }else if(A.charAt(i)=='}' || A.charAt(i)==']' || A.charAt(i)==')'){
                if(stack.isEmpty()){
                    return false;
                }
                stack.pop();
            }
        }
        return stack.isEmpty();
    }
}

发表于 2017-03-06 13:34:36 回复(0)
通过测试

class ChkExpression {
public:
    bool chkLegal(string A) {
        int num=A.size();
        int s=0;
        int *flag=new int[num];
        for(int i=0;i<num;i++)
            flag[i]=0;
        for(int i=0;i<num;i++)
            {
            if(A[i]=='{'&&flag[i]==0)
                {
                flag[i]=1;
                s++;
                for(int j=i+1;j<num;j++)
                    if(A[j]=='}'&&flag[j]==0)
                {flag[j]=1;s--; break;}
            }
             if(A[i]=='('&&flag[i]==0)
                {
                flag[i]=1;
                s++;
                for(int j=i+1;j<num;j++)
                    if(A[j]==')'&&flag[j]==0)
                {flag[j]=1;s--; break;}
             }
             if(A[i]=='['&&flag[i]==0)
                {
                flag[i]=1;
                s++;
                for(int j=i+1;j<num;j++)
                    if(A[j]==']'&&flag[j]==0)
                {flag[j]=1;s--; break;}
             }
                 
            }
        if(s==0)return true;
        else return false;
        }
};

发表于 2015-10-17 17:53:33 回复(0)
可以用很流氓的办法,将中括号和大括号都换成小括号,将字母全部换成1,然后用eval函数去执行表达式,不抛异常就是合法的表达式。
# -*- coding:utf-8 -*-
import re

class ChkExpression:
    def chkLegal(self, A):
        # write code here
        try:
            A = re.sub('[\[{]', '(', A)
            A = re.sub('[\]}]', ')', A)
            A = re.sub('[A-Za-z]+', '1', A)
            eval(A)
            return True
        except:
            return False

编辑于 2021-04-09 11:54:46 回复(0)
只要判断左右括号数量是否一致就行了,题目描述是有问题的
class ChkExpression {
public:
    bool chkLegal(string A) {
        stack<char> ch;
        for (int i = 0; i < A.length(); i++) {
            if (A[i] == '{' || A[i] == '[' || A[i] == '(') {
                ch.push(A[i]);
            }
            
            if (A[i] == '}' || A[i] == ']' || A[i] == ')') {
                if (ch.size() == 0) return false;
                ch.pop();
            }
        }
        return ch.size() == 0;
    }
};



发表于 2020-12-28 21:33:08 回复(0)
        这个题真的是……无力吐槽了。估计出题人想把题目难度降低,但是这样反而让难度上升了。下面贴一段自己写的常规逻辑下的括号匹配代码,采用的依然是经典的栈匹配。仅匹配括号,对表达式不进行匹配,也就是说 ()+ 在我这里也是过的,大体方法如下:
        遍历字符串,当遇到 { [ ( 时入栈;当遇到 } ] ) 时出栈。但是在出栈时——1.若此时栈为空,也就是说没有前部分括号匹配,返回 false;2.若此时栈顶元素不能匹配,如遇到 } 时栈顶为 (,二者无法匹配,此时返回 false。直至遍历结束。最后再次检查栈区,若为空,证明完全匹配,然回 true;否则,证明仍有括号未匹配,然回 false。
        不知道我这样想有没有什么BUG,欢迎朋友们在讨论区流言,参考代码如下:
class ChkExpression {
public:
    bool chkLegal(string A) {
        stack<char> tmp;
        for (int i = 0; i < A.size(); i++)
        {
            if (A[i] == '{' || A[i] == '[' || A[i] == '(') tmp.push(A[i]);
            if (A[i] == '}')
            {
                if (tmp.empty() || tmp.top() != '{') return false;
                tmp.pop();
            }
            if (A[i] == ']')
            {
                if (tmp.empty() || tmp.top() != '[') return false;
                tmp.pop();
            }
            if (A[i] == ')')
            {
                if (tmp.empty() || tmp.top() != '(') return false;
                tmp.pop();
            }
        }
        if (tmp.empty()) return true;
        return false;
    }
};

发表于 2018-05-14 10:34:52 回复(0)

新思路

package com.special.first;

import java.util.Scanner;

/**
 * 去哪儿网01-表达式合法判断
 *
 * 去哪儿网出的题就这么不严谨把,题目描述的这么少,鬼知道你的意思
 * 你所谓的合法有没有包括加减乘除的合法,测试用例都是错的。
 *
 * 常见的思路就是用栈做,是左括号就进栈,是右括号的不进栈,且弹出栈顶元素
 * 这样一对括号就没了,只要判断最后栈的大小为0,说明左右是一一匹配的
 * 用真实的栈或者数组模拟都可以
 *
 * 我这里有一个更新奇的做法,就是计数法
 * 1.若是左括号,我就自增,因为中间状态时左括号是可以比右括号多的
 * 2.若是右括号,我就自减,同时判断是否小于0,若小于0,说明右括号多了,直接结束了
 * 3.遍历结束,最后我判断是否大于0,若大于0,说明左括号多了,正常的合法应该是0
 * Create by Special on 2018/3/3 11:03
 */
public class Pro032 {

    private static boolean isLeftBucket(char ch){
        return ch == '{' || ch == '[' || ch == '(';
    }

    private static boolean isRightBucket(char ch){
        return ch == '}' || ch == ']' || ch == ')';
    }

    public static boolean chkLegal(String A) {
        int status = 0;
        boolean result = true;
        for(int i = 0; i < A.length(); i++) {
            if (isLeftBucket(A.charAt(i))) {
                status++;
            } else if (isRightBucket(A.charAt(i))) {
                status--;
                if (status < 0) {
                    result = false;
                    break;
                }
            }
        }
        return status > 0 ? false : result;
    }

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while(input.hasNext()){
            String str = input.nextLine();
            System.out.println(chkLegal(str));
        }
    }
}
发表于 2018-03-03 11:23:44 回复(0)
就一个测试样例就想说明白,而且本身还是错误的样例,这道题不做也罢

发表于 2018-02-12 09:23:22 回复(0)
class ChkExpression {
public:
    bool chkLegal(string A) {
        vector<char> s;
        for(int i=0;i<A.size();i++)
        {
            if(A[i]=='{' || A[i]=='(' || A[i]=='[')
                s.push_back(A[i]);
            else if(A[i]=='}' || A[i]==')' || A[i]==']')
            {
                int l = s.size();
                if(l < 1)
                    return false;
                else
                    s.pop_back();             }         }         if(s.size()>0)             return false;         return true;
    }
};

发表于 2017-12-28 02:15:52 回复(0)
import java.util.*;

public class ChkExpression {
    public boolean chkLegal(String A) {
        // write code here
        Stack leftOpStack = new Stack();
        Stack rightOpStack = new Stack();
        for (int i = 0; i < A.length(); i++) {
            char curChar = A.charAt(i);
            if ("{[(".indexOf(curChar) != -1) {
                leftOpStack.push(curChar);
            } else if (")]}".indexOf(curChar) != -1) {
                rightOpStack.push(curChar);
            }
        }
        
        return leftOpStack.size() == rightOpStack.size();
    }
}

发表于 2017-09-17 23:18:32 回复(0)
class ChkExpression {//只要左括号和右括号的数量一样就是正确的,真是醉了
public:
    bool chkLegal(string A) {
        int left=0,right=0;
        for(string::size_type idx=0;idx<A.size();++idx){
            if('['==A[idx]||'('==A[idx]||'{'==A[idx])
                ++left;
            else if(']'==A[idx]||')'==A[idx]||'}'==A[idx])
                ++right;
        }
        if(left==right)
            return true;
        else
            return false;
    }
};

发表于 2017-09-04 15:47:49 回复(0)
//jbt
class ChkExpression {
public:
    bool chkLegal(string A) {
        vector<char> stack;
        for(int i=0;i<A.size();i++){
            if(A[i] == '{' || A[i] == '[' || A[i] == '(')
                stack.push_back(A[i]);
            else if(A[i] == '}' || A[i] == ']' || A[i] == ')'){
                if(stack.size() == 0)
                    return false;
                else
                    stack.pop_back();
            }
        }
        if(stack.size() == 0)
            return true;
        else
            return false;
    }
};

发表于 2017-07-15 17:08:30 回复(1)
import java.util.*;
public class ChkExpression {
    public boolean chkLegal(String A) {
        // 题目意思:让左括号(不管大中小)的数量等于右括号(不管大中小)的数量
        // write code here
        StringBuilder sb = new StringBuilder(A);
        int len = sb.length();
        Stack<Character> stack = new Stack<Character>();
        for (int i=0; i<len; i++) {
            char ch = sb.charAt(i);
            if (ch == '(' || ch == '[' || ch == '{')
                stack.push(ch);
            if (ch == ')' || ch == ']' || ch == '}')
                stack.pop();
        }
        if (stack.isEmpty())
            return true;
        return false;
    }
}

编辑于 2017-03-22 00:19:04 回复(1)
public static boolean chkLegal(String A) {
        // write code here
		Stack<Character> stack = new Stack<Character>();
		char[] cs = A.toCharArray();
		for(int i=0;i<cs.length;i++){
			if(cs[i] == '(' || cs[i] == '{' || cs[i] == '['){
				stack.push(cs[i]);
			}
			if(cs[i] == ')' || cs[i] == '}' || cs[i] == ']'){
				stack.pop();
			}
		}
		return stack.isEmpty();
    }

发表于 2016-09-23 16:36:51 回复(0)
import java.util.*;

public class ChkExpression {
    public boolean chkLegal(String A) {
        char c[]=A.toCharArray();
        Stack<Character> s=new Stack<>();
        char d;
        for(int i=0;i<c.length;i++){
            if(c[i]=='{'||c[i]=='['||c[i]=='(')//碰到左边括号就入栈
                s.push(c[i]);
            else if(c[i]=='}'||c[i]==']'||c[i]==')'){//碰到右括号就出栈看是否是左括号
                d=s.pop();
                if(d=='{'||d=='['||d=='('){}
                else 
                    return false;//不能匹配直接返回False
                 
            }
            else{}
        }
      return s.isEmpty();
    }
}
发表于 2016-09-12 21:40:50 回复(0)
萌头像
写的挺好的,不能过,改成最简单的就a了,
class ChkExpression {
public:
 bool chkLegal(string A) {
  // write code here
  stack<char> chs;
  for (int i = 0; i < A.length(); i++){
   char ch = A[i];
   if (ch =='{'||ch=='['||ch=='('){
    chs.push(ch);
   }
   else if(ch == '}' || ch == ']' || ch == ')'){
    chs.pop();
   }
   else continue;
  }
  return chs.empty();
 }
};

发表于 2016-09-09 16:01:34 回复(0)
class ChkExpression {
public:
    bool chkLegal(string A) {
        stack<char> S;
        for(int i=0;i<A.length();i++){
            if(A[i]=='{'||A[i]=='['||A[i]=='(')
            	S.push(A[i]);
            else if(A[i]=='}'||A[i]==']'||A[i]==')'){
            	if(!S.empty())//&&((A[i]=='}'&&S.top()=='{')||(A[i]==']'&&S.top()=='[')||(A[i]==')'&&S.top()=='(')))
                	S.pop();
                else
                	return false;                  
        	}
        }
        if(!S.empty())
            return false;
        return true;          	
    }
};

发表于 2016-08-30 19:18:13 回复(0)