/*====================================================================== 扩号匹配问题 总时间限制: 1000ms 内存限制: 65536kB 描述 在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号。不能匹配的左括号用"$"标注,不能匹配的右括号用"?"标注. 输入 输入包括多组数据,每组数据一行,包含一个字符串,只包含左右括号和大小写字母,字符串长度不超过100 注意:cin.getline(str,100)最多只能输入99个字符! 输出 对每组输出数据,输出两行,第一行包含原始输入字符,第二行由"$","?"和空格组成,"$"和"?"表示与之对应的左括号和右括号不能匹配。 样例输入 ((ABCD(x) )(rttyy())sss)( 样例输出 ((ABCD(x) $$ )(rttyy())sss)( ? ?$ 思路: 输入一组数据后(一个字符串,这里输入到数组a),先输出数组a 统计数组a的长度len,设置数组b代表的栈的栈顶end指向0. (注意把end清零) 然后扫描检测数组a,遇到左括号之间进栈(数组b代表的栈的元素存储进栈的 那个字符以及该字符在字符串a中的下标。)遇到右括号则按下面法则处理: 假如数组b代表的栈是空的(即end为0),则右括号进栈。 假如b不是空的(end大于0),则检测栈顶元素(下标是end-1) 是否是左括号,如果刚好是左括号则该栈顶元素出栈(end自己减1), 假如栈顶元素(下标是end-1)不是左括号,则该右括号进栈。 注意:这里end是指向栈顶元素的下一个位置。也就是说某一次进栈后end自己加1, 而栈顶元素下标是end-1。 另外:扫描完后,b数组的下标应该是0到end-1.扫描该数组, 按b的每一个元素的num值所指向的a数组的下标对应的元素设置为$或? 然后扫描a数组,假如不是$或?则输出空格,否则输出对应元素的值 然后处理下一组数据(但是要注意处理下一组数据前要把end清零。) ========================================================================*/ #include<stdio.h> #include<string.h> struct s { char ch; int num; }; int main() { char a[105]; struct s b[105]; int i,len; int end=0;//指向b数组代表的栈的栈顶 freopen("5.in","r",stdin); while(scanf("%s",a)!=EOF) { printf("%s\n",a); len=strlen(a); end=0; for(i=0;i<len;i++) { if(a[i]=='(')//左括号直接进栈(因为它不可能使栈顶元素出栈的。) { b[end].ch=a[i]; b[end].num=i; end++; } else if(a[i]==')') { if(end==0)//b数组代表的栈是空的 { b[end].ch=a[i]; b[end].num=i; end++; } else { if(b[end-1].ch=='(') { end--; } else { b[end].ch=a[i]; b[end].num=i; end++; } } } } for(i=0;i<end;i++) { if(b[i].ch=='(') { a[b[i].num]='$'; } else { a[b[i].num]='?'; } } for(i=0;i<len;i++) { if(a[i]!='$'&&a[i]!='?') { printf(" "); } else printf("%c",a[i]); } printf("\n"); /*for(i=0;i<end;i++) { printf("%c ",b[i].ch); } printf("\n"); for(i=0;i<end;i++) { printf("%d ",b[i].num); } printf("\n");*/ } return 0; }