-
Notifications
You must be signed in to change notification settings - Fork 8
/
check_brackets.c
159 lines (143 loc) · 4.27 KB
/
check_brackets.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/* ----------------------------------------------------------------------- *
*
* Author: Leandro Augusto Lacerda Campos <[email protected]>
*
* Data Structures and Algorithms Specialization,
* by University of California, San Diego,
* and National Research University Higher School of Economics
*
* Course 2: Data Structures
*
* Solution for Check Brackets in the Code Problem
*
* ----------------------------------------------------------------------- */
#include <stdio.h>
#include <stdlib.h>
#define MAXLEN 100000 /* max length of any string */
typedef struct Item Item;
struct Item {
char bracket;
int index;
};
typedef struct Stack Stack;
struct Stack { /* stack implementation with growable array */
int nit; /* current number of items */
int max; /* allocated number of items */
Item *base; /* array of items - refer to its elements by subscripts */
};
enum { STKINIT = 15625, STKGROW = 2 };
/*
* push: adds item to stack and returns the index of the item just add, or -1
* if some error occurred in memory allocation
*/
int push(Stack *stack, Item item)
{
Item *membck;
if (stack->base == NULL) { /* first item */
stack->base = (Item *)malloc(STKINIT * sizeof(Item));
if (stack->base == NULL)
return -1;
stack->max = STKINIT;
stack->nit = 0;
} else if (stack->nit == stack->max) { /* grow */
membck = (Item *)realloc(stack->base,
(STKGROW * stack->max) * sizeof(item));
if (membck == NULL)
return -1;
stack->max *= STKGROW;
stack->base = membck; /* the address of the array may change */
}
stack->base[stack->nit] = item;
return stack->nit++;
}
/*
* top: copies the most recently-added item in stack into the Item pointed to
* by item and returns its 0-based index, or -1 if some error occurred
*/
int top(const Stack *stack, Item *item)
{
Item *itemp;
if (stack->nit == 0) {
return -1;
} else {
itemp = &stack->base[stack->nit-1];
item->bracket = itemp->bracket;
item->index = itemp->index;
return (stack->nit - 1);
}
}
/*
* pop: copies the most recently-added item in stack into the Item pointed to
* by item, removes it and returns its 0-based index, or -1 if some error
* occurred
*/
int pop(Stack *stack, Item *item)
{
Item *itemp;
if (stack->nit == 0) {
return -1;
} else {
itemp = &stack->base[--(stack->nit)];
item->bracket = itemp->bracket;
item->index = itemp->index;
return stack->nit;
}
}
/*
* isempty: returns -1 if there are any items in stack and 0 otherwise
*/
inline int isempty(const Stack *stack)
{
return (stack->nit == 0);
}
/*
* brktchk: checks the usage of brackets in the string str. If the usage is
* correct, returns -1. Otherwise, returns the 0-based index of the first
* unmatched closing bracket, and if there are no unmatched closing brackets,
* output the 0-based index of the first unmatched opening bracket. And if
* some error occurred in push function, returns -2.
*/
int brktchk(const char *str)
{
int i, c;
Stack stk;
Item top;
stk = (Stack){ 0, 0, NULL };
for (i = 0; (c = str[i]) != '\0'; i++) {
if (c == '[' || c == '{' || c == '(') {
if (push(&stk, (Item){ c, i }) == -1)
return -2;
} else if (c == ']' || c == '}' || c == ')') {
if (isempty(&stk))
return i;
pop(&stk, &top);
if ((top.bracket == '[' && c != ']')
|| (top.bracket == '{' && c != '}')
|| (top.bracket == '(' && c != ')'))
return i;
}
}
if (isempty(&stk))
return -1;
pop(&stk, &top);
if (stk.base != NULL)
free(stk.base);
return top.index;
}
int main()
{
char str[MAXLEN+2]; /* two extra characters, for '\n' and '\0' */
int res;
/* one extra character, for '\n' */
if (fgets(str, MAXLEN+1, stdin) == NULL)
return -1;
if ((res = brktchk(str)) == -2) {
puts("error in push function\n");
return -1;
} else if (res == -1) {
puts("Success\n");
} else {
printf("%d\n", res + 1); /* 1-based index */
}
return 0;
}