11206: 【原1206】pascal
题目
题目描述
author: DS TA 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1206
Description
对给定一个Pascal源文件,请检查其中
(1)begin与end
(2)if,then,else
是否合法配对。
对于begin与end,可以理解为C语言中的“{”与“}”
对于if,then,else,可以这么理解:if与then合在一起相当于C语言中的if, else与C语言中的else完全相同。
注意1:为了简化问题,end出现的时候,后面没有“;”,“.”,也就是只有“end”的情况,没有“end;”,"end."。
注意2: 实际pascal语言里面是会有上述几种情况的(这只是介绍,怕这道题误导群众)。
注意3:5个关键词都会单独出现,不会有和其它字符连在一起的情况。
Example
Pascal源代码:
Var a:char;
begin
writeln(‘Do you fell happy ?’);
readln(a);
if a=’y’ then writeln(‘smile’);
else writeln(‘sad’);
end
等价的C++源代码:
char a;
int main()
{
cout<<"Do you fell happy ?"<<endl;
cin>>a;
if(a=='y')
cout<<"smile"<<endl;
else
cout<<"sad"<<endl;
}
Input Format
一段Pascal代码。
输入文本大小不超过4kb。
Output Format
对于一个正确匹配的Pascal代码,请输出一个"Match!",否则输出一个"Error!"(无"")。请使用自己写的栈来完成此题。
Sample Input1
Var a:char;
begin
writeln(‘Do you fell happy ?’);
readln(a);
if a=’y’ then writeln(‘smile’)
else writeln(‘sad’);
end
Sample Output1
Match!
Sample Input2
Var a:char;
begin
writeln(‘Do you fell happy ?’);
readln(a);
if a=’y’ then writeln(‘smile’)
else writeln(‘sad’);
Sample Output2
Error!
BugenZhao's solution
//
// Created by BugenZhao on 2019/3/24.
//
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
#include <cstring>
using namespace std;
template<typename Item>
class Stack {
class Node {
public:
Item val;
Node *next = nullptr;
};
int size;
Node *top;
public:
Stack() {
top = nullptr;
size = 0;
}
void push(const Item &item) {
top = new Node{item, top};
}
Item peek() {
return top->val;
}
Item pop() {
Node *tmp = top;
Item ret = top->val;
top = top->next;
delete tmp;
return ret;
}
bool isEmpty() {
return top == nullptr;
}
virtual ~Stack() {
Node *tmp;
while (top) {
tmp = top;
top = top->next;
delete tmp;
}
}
};
const char *tokens[] = {"begin", "end", "if", "then", "else"};
int main() {
Stack<int> s;
char token[100];
bool flag = true;
int tmp;
while (cin >> token) {
if (strcmp(token, "BZ") == 0) break;
if (!flag) break;
int i;
for (i = 0; i < 5; ++i) {
if (strcmp(token, tokens[i]) == 0) break;
}
switch (i) {
case 0:
s.push(0);
break;
case 1:
if (s.isEmpty()) {
flag = false;
break;
}
while (true) {
tmp = s.pop();
if (tmp == 3) continue;
else if (tmp == 0) break;
else flag = false;
}
break;
case 2:
s.push(2);
break;
case 3:
if (s.isEmpty()) {
flag = false;
break;
}
tmp = s.peek();
if (tmp != 2) {
flag = false;
} else {
s.pop();
s.push(3);
}
break;
case 4:
if (s.isEmpty()) {
flag = false;
break;
}
tmp = s.peek();
if (tmp != 3) {
flag = false;
} else {
s.pop();
}
break;
}
}
if (flag && s.isEmpty()) {
cout << "Match!" << endl;
} else {
cout << "Error!" << endl;
}
return 0;
}
ligongzzz's solution
#include "iostream"
#include "cstring"
using namespace std;
class myList {
public:
int data;
myList* next = nullptr;
};
class myStack {
public:
myList* head;
myStack() {
head = new myList;
}
void push(int b) {
head->data = b;
auto temp = head;
head = new myList;
head->next = temp;
}
int pop() {
auto temp = head;
int result = temp->next->data;
head = head->next;
delete temp;
return result;
}
bool isEmpty() {
return head->next == nullptr;
}
int getBack() {
return head->next->data;
}
};
int main() {
myStack Stack;
char op[10000][100] = { 0 };
int num = 0;
for (; cin >> op[num]; num++);
//循环判断(begin 0,if then 1)
for (int i = 0; i < num; i++) {
if (strcmp(op[i], "begin") == 0) {
//入栈0
Stack.push(0);
}
else if (strcmp(op[i], "if") == 0) {
Stack.push(2);
}
else if (strcmp(op[i], "then") == 0) {
if (!Stack.isEmpty() && Stack.getBack() == 2) {
Stack.pop();
Stack.push(1);
}
else {
cout << "Error!";
return 0;
}
}
else if (strcmp(op[i], "else") == 0) {
if (!Stack.isEmpty() && Stack.getBack() == 1) {
Stack.pop();
}
else {
cout << "Error!";
return 0;
}
}
else if (strcmp(op[i], "end") == 0) {
if (!Stack.isEmpty() && Stack.getBack() == 0) {
Stack.pop();
if (!Stack.isEmpty() && Stack.getBack() == 1 && strcmp(op[i + 1], "else") != 0)
Stack.pop();
}
else {
cout << "Error!";
return 0;
}
}
else if (!Stack.isEmpty() && Stack.getBack() == 1 &&op[i][strlen(op[i])-1]==';') {
Stack.pop();
}
}
//判断是否全部弹出
if (Stack.isEmpty())
cout << "Match!";
else
cout << "Error!";
return 0;
}
Neight99's solution
#include <cstring>
#include <iostream>
using namespace std;
template <class T>
class seqStack {
private:
T* data;
int nowSize;
int maxSize;
void doublespace();
public:
seqStack(int initSize = 10);
seqStack(const seqStack<T>&);
~seqStack();
int size() const;
void push(T);
T top();
T pop();
bool isEmpty();
T find(T) const;
seqStack<T>& operator=(const seqStack<T>&);
T& operator[](int);
};
template <class T>
seqStack<T>::seqStack(int initSize) {
data = new T[initSize];
nowSize = 0;
maxSize = initSize;
}
template <class T>
void seqStack<T>::doublespace() {
T* tmp;
maxSize *= 2;
tmp = new T[maxSize];
for (int i = 0; i < nowSize; i++) {
tmp[i] = data[i];
}
delete[] data;
data = tmp;
tmp = NULL;
}
template <class T>
seqStack<T>::seqStack(const seqStack<T>& right) {
nowSize = right.nowSize;
maxSize = right.maxSize;
data = new T[maxSize];
for (int i = 0; i < nowSize; i++) {
data[i] = right.data[i];
}
}
template <class T>
seqStack<T>::~seqStack() {
delete[] data;
data = NULL;
}
template <class T>
int seqStack<T>::size() const {
return nowSize;
}
template <class T>
void seqStack<T>::push(T x) {
if (nowSize == maxSize) {
doublespace();
// return;
}
data[nowSize++] = x;
}
template <class T>
T seqStack<T>::find(T x) const {
for (int i = 0; i < nowSize; i++) {
if (data[i] == x) {
return x;
}
}
return -1;
}
template <class T>
T seqStack<T>::top() {
return data[nowSize - 1];
}
template <class T>
T seqStack<T>::pop() {
if (nowSize != 0) {
return data[--nowSize];
}
return -1;
}
template <class T>
bool seqStack<T>::isEmpty() {
return (nowSize == 0);
}
template <class T>
seqStack<T>& seqStack<T>::operator=(const seqStack<T>& right) {
if (this != &right) {
delete[] data;
nowSize = right.nowSize;
maxSize = right.maxSize;
data = new T[maxSize];
for (int i = 0; i < nowSize; i++) {
data[i] = right.data[i];
}
}
return *this;
}
template <class T>
T& seqStack<T>::operator[](int x) {
return data[nowSize - x - 1];
}
class check {
private:
char* data;
int pair;
seqStack<int> vec1;
seqStack<int> vec2;
public:
check(char[]);
~check();
int checkWord(char*);
bool checkIssue(int);
bool checkAll();
};
check::check(char words[]) : pair(0) { data = words; }
check::~check() { data = NULL; }
int check::checkWord(char* ch) {
if (strcmp(ch, "begin") == 0) {
return 1;
} else if (strcmp(ch, "end") == 0) {
return 2;
} else if (strcmp(ch, "if") == 0) {
return 3;
} else if (strcmp(ch, "then") == 0) {
return 4;
} else if (strcmp(ch, "else") == 0) {
return 5;
} else {
return 0;
}
}
bool check::checkIssue(int i) {
if (i == 1) {
if (vec1.top() == 3) {
return 0;
} else {
vec1.push(1);
vec2.push(0);
}
} else if (i == 2) {
if (vec1.isEmpty() || vec1.top() != 1) {
return 0;
} else {
vec1.pop();
vec2.pop();
}
} else if (i == 3) {
if (vec1.top() == 3) {
return 0;
} else {
vec1.push(3);
}
} else if (i == 4) {
if (vec1.isEmpty() || vec1.top() != 3) {
return 0;
} else {
vec1.pop();
if (vec2.isEmpty()) {
++pair;
} else {
return 0;
}
}
} else if (i == 5) {
if (vec2.isEmpty()) {
if (pair) {
--pair;
} else {
return 0;
}
} else {
if (vec2.top()) {
int temp = vec2.pop();
vec2.push(temp - 1);
} else {
return 0;
}
}
}
return 1;
}
bool check::checkAll() {
if (data == NULL) {
return 0;
} else {
char* p = data;
char tmp[100] = {'\0'};
int type, last = 0;
while (1) {
int pos = 0;
while (*p == ' ') {
p++;
}
while (*p && *p != ' ') {
tmp[pos++] = *p;
p++;
}
tmp[pos++] = 0;
type = checkWord(tmp);
checkIssue(type);
if (*p == 0) {
break;
}
}
while (vec1.isEmpty() == 0) {
int tmp = vec1.pop();
if (tmp == 1) {
return 0;
} else if (tmp == 3 && last != 4) {
return 0;
}
last = type;
}
return 1;
}
}
int main() {
int pair, pos = 0;
bool flag = 1;
char words[50000], ch;
ch = getchar();
while (ch != EOF) {
if (ch == '\n') {
ch = ' ';
}
words[pos++] = ch;
ch = getchar();
}
words[pos] = 0;
check che(words);
if (che.checkAll()) {
cout << "Match!" << endl;
} else {
cout << "Error!" << endl;
}
return 0;
}
skyzh's solution
#include <iostream>
#include <cstring>
using namespace std;
enum program { BEGIN = 0, END, IF, THEN, ELSE };
template <typename T>
class Stack {
public:
T *data;
int top_ptr;
Stack(int cap) : data(new T[cap]), top_ptr(0) {}
~Stack() { delete[] data; }
void push(const T& d) { data[top_ptr++] = d; }
T pop() { return data[--top_ptr]; }
T top() { return data[top_ptr - 1]; }
bool empty() { return top_ptr == 0; }
};
void pop_else_then(Stack<int> &d) {
while (!d.empty()) {
if (d.top() == THEN) d.pop();
else if (d.top() == ELSE) d.pop();
else return;
}
}
void pop_then(Stack<int> &d) {
while (!d.empty()) {
if (d.top() == THEN) d.pop();
else return;
}
}
bool run() {
Stack <int> d(10000);
char token[100];
while (cin >> token) {
if (strcmp(token, "begin") == 0) {
d.push(BEGIN);
}
if (strcmp(token, "end") == 0) {
if (d.empty()) return false;
if (d.top() == BEGIN) d.pop(); else {
pop_else_then(d);
if (d.empty()) return false;
if (d.top() == BEGIN) d.pop(); else return false;
}
}
if (strcmp(token, "if") == 0) {
d.push(IF);
}
if (strcmp(token, "else") == 0) {
if (d.empty()) return false;
if (d.top() == THEN) { d.pop(); d.push(ELSE); } else {
pop_then(d);
if (d.empty()) return false;
if (d.top() == THEN) d.pop(); else return false;
}
}
if (strcmp(token, "then") == 0) {
if (d.empty()) return false;
if (d.top() == IF) { d.pop(); d.push(THEN); } else return false;
}
}
pop_else_then(d);
return d.empty();
}
int main() {
if (run()) cout << "Match!" << endl; else cout << "Error!" << endl;
return 0;
}
yyong119's solution
#include <iostream>
#include <cstring>
using namespace std;
class stack {
private:
char *data;
int topP, maxSize;
void doubleSpace() {
char *tmp = data;
data = new char[maxSize * 2];
for (int i = 0; i < maxSize; ++i)data[i] = tmp[i];
maxSize *= 2;
delete[] tmp;
}
public:
stack() :topP(-1), maxSize(10) {
data = new char[maxSize];
}
bool empty() {
return topP == -1;
}
void push(char c) {
if (topP == maxSize - 1)doubleSpace();
data[++topP] = c;
}
char pop() {
if (!empty()) return data[topP--];
}
char top() {
if (!empty()) return data[topP];
}
};
int main() {
ios::sync_with_stdio(false);
stack v;
char str[1000];
bool isOk = true;
while (cin >> str) {
if (strcmp(str, "begin") == 0 || strcmp(str, "if") == 0)
v.push(str[0]);
else if (strcmp(str, "then") == 0) {
if (v.empty() || v.pop() != 'i') isOk = false;
else v.push('t');
}
else if (strcmp(str, "end") == 0) {
do {
if (v.empty() || v.top() == 'i') {
isOk = false; break;
}
if (v.pop() == 'b')break;
} while (true);
if (!isOk)break;
}
else if (strcmp(str, "else") == 0) {
if (v.empty() || v.pop() != 't') isOk = false;
}
if (!isOk) break;
}
while (isOk && !v.empty()) {
if (v.pop() != 't') isOk = false;
}
if (isOk) cout << "Match!" << '\n';
else cout << "Error!" << '\n';
return 0;
}