函数——括号匹配问题

描述
   在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算术式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号:首先输出原来字符串,下一行是和原字符串等长的一行,标出不能匹配的括号,其中不能匹配的左括号用"$"标注,不能匹配的右括号用"?"标注

    
关于输入
第一行一个正整数n,表示数据的组数。后面n行,每组数据一行,包含一个字符串,只包含左右括号和大小写字母,字符串长度不超过100
关于输出
   对每组输出数据,输出两行,第一行包含原始输入字符,第二行由"$","?"和空格组成,与第一行等长,"$"和"?"表示与之对应的左括号和右括号不能匹配。
   注意:即使所有括号都匹配,第二行也要输出等长的一行空格
例子输入
2

((ABCD(x)

)(rttyy())sss)(
例子输出
((ABCD(x)

$$       

)(rttyy())sss)(

?            ?$

方法:

从左开始遍历,如果遇到左括号1在位置x,则从下一位往后寻找右括号1在位置y,找到后则从右括号1前一位往前寻找左括号2,标记左括号2与右括号1位’ ‘,他们是正确匹配。如果左括号1与2为同一位置的括号,则从下一位置x+1进行下一次寻找;若左括号1与2不同,则从y+1位置开始继续寻找右括号。

若开始遇到的是右括号,情形相似。

最终标记的结果:

        所有匹配的括号——空格;

        所有不是括号的字符——空格;

        不匹配的括号——保留,不做改动。

#include<iostream>
#include<cstring>
using namespace std;
void mark(string &s)//记得加&,否则实参不会改变!
{
	int l = s.size();
	for (int i = 0; i < l; ++i) {
		if (s[i] == '(') {
			int flag = 1;
			for (int j = i+1; j < l; ++j) {
				if (s[j] == ')') {
					for (int m = j - 1; m >= i; --m) {
						if(s[m]=='('){
							s[m] = ' ';
							s[j] = ' ';
							if (m == i) { flag = 0; }
							break;
						}
					}
				}
				if (flag == 0) { break; }
			}
		}
		else if (s[i] == ')') {
			int flag = 1;
			for (int j = i - 1; j >= 0; --j) {
				if (s[j] == '(') {
					for (int m = j + 1; m <= i; ++m) {
						if (s[m] == ')') {
							s[m] = ' ';
							s[j] = ' ';
							if (m == i) { flag = 0; }
							break;
						}
					}
				}
				if (flag == 0) { break; }
			}
		}
		else s[i] = ' ';
	}
}

int main()
{
	int N;
	cin >> N;
	while (N--) {
		string str;
		cin >> str;
		int len = str.size();
		cout << str << endl;
		mark(str);
		for (int i = 0; i < len; ++i) {
			if (str[i] == '(') { cout << "$"; }
			else if (str[i] == ')') { cout << "?"; }
			else cout << " ";
		}
		cout << endl;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值