2.Delimiter Matching

Prerequisites, Goals, and Outcomes

Prerequisites: Students should have mastered the following prerequisite skills. 

· Stack - Understanding of the implementation of stack. 

· Templates - Creation and use of template classes

· File IO - Basic file IO skills 

Goals: This assignment is designed to reinforce the student's understanding of the structure and use of stack as containers. 

Outcomes: Students successfully completing this assignment would master the following outcomes. 

· Familiarize how to implement a template class 

· Familiarize the structure and the use of the stack 

Background

Compilers check your programs for syntax errors, but frequently a lack of one symbol (such as a missing brace or comment starter) will cause the compiler to spill out a hundred lines of diagnostics without identifying the real error. 

A useful tool in this situation is a program that checks whether everything is balanced. Thus, every right brace, bracket, and parenthesis must correspond to their left counterparts. The sequence [()] is legal, but [(]) is wrong. Obviously, it is not worthwhile writing a huge program for this, but it turns out that it is easy to check these things. 

Description

Make an empty stack. Read characters until end of file. If the character is an open anything, push it onto the stack. If it is a close anything, then if the stack is empty report an error. Otherwise, pop the stack. If the symbol popped is not the corresponding opening symbol, then report an error. At end of file, if the stack is not empty report an error. 

Besides the balancing of the parentheses, brackets, and bracesthe Annotation (/**/) should be balanced. When a /* is found, all the letters behind will be ignored until a */ is found. If it is not found at the end of the file, an error will be reported.

Some of the contents of the stack are shown in the figure below.

Tasks

To complete this assessment, you need to define the implementation of class Stack and complete the main.cpp file in which the delimiter matching is defined. 

Following is an ordered list of steps that serves as a guide to completing this assessment. Work and test incrementally. Save often.

1. Begin by the creation of the class StackYou can implement a stack through either an array or a list. But this class should be defined as a template class. And it should contain the following basic operation. 

void Pop():  Pop an element from the top of the stack 

void Push(const T & e):  Push this element into the stack.

T & Top(): Return the top element of the stack.

bool Isempty() const: If the stack is empty, return true; otherwise return false.

int Size() const:  Return the number of the elements in the stack.

2. Nextcreate the file main.cpp and complete the implementation of delimiter matching. The detail steps are as follows.

Get a file name from the command line parameter, which specifies the file name needing delimiter matching. Invoke the delimiterMatching function using the file name.

Complete the function delimiterMatching, which accepts a string type parameterThis parameter is the file name described as above. This function repeats reading one character from the file and taking it into process until an error appears or at the end of the file. 

Submission

Submit only the following.

1. Stack.h - your completed class Stack definition 

2. Stack.cpp - if created 

3. main.cpp - your completed delimiter matching file

#include<iostream>
#include<fstream>
#include<string>
using namespace std;

template <class T>
class Stack
{
private:
	T *data;//指向栈顶指针
	int size;//栈长度
	int top;
public:
	Stack(int size=0)//构造函数
	{
		this->size=size;
		this->top=0;
		this->data=new T[size];
	}
	~Stack()//析构函数
	{
		size=0;
		top=0;
		delete []data;	
	}
	void Pop()//栈顶元素出栈
	{
		if(!isEmpty())
		{
			top--;
		}
	}
	void Push(const T & item)//入栈
	{
		if(top<size)
		{
			data[top]=item;
			top++;
		}
	}
	T & Top()//获取栈顶元素
	{
		if(!isEmpty())
		{	
			return data[top-1];
		}
	}
	bool isEmpty()
	{
		if(top==0)
		{
			cout<<"Stack is empty"<<endl;
			return true;
		}
		else return false;
	}
	int Size()
	{
		return top;
	}
};
bool delimiterMatching()
{
	cout<<"请向文件输入字符串:"<<endl;
	string s;
	cin>>s;
	ofstream out("F:\\test.txt");
	out<<s<<endl;
	out.close();//关闭文件
	ifstream get("F:\\test.txt");
	char string[50];
	get>>string;//获取文件
	int i=0;
	Stack<char> stack(100);
	while(string[i]!='\0')
	{
		//1、判断是否为左括号,是则入栈
		if(string[i]=='('||string[i]=='['||string[i]=='{')
		{
			stack.Push(string[i]);
			i++;
		}
		//2、右括号的情况
		else if(string[i]==')'||string[i]==']'||string[i]=='}')
		{
			if(stack.isEmpty())//如果栈空说明没有左匹配符
			{
				return false;
			}
			else//栈未空
			{
				char temp;
				temp=stack.Top();//获取栈顶元素,匹配的话栈顶元素出栈
				if((string[i]==')'&&temp=='(')||(string[i]=='}'&&temp=='{')||(string[i]==']'&&temp=='['))
				{
					stack.Pop();
					i++;
				}
				else return false;	
			}
		}
		//3、当读到 / 时有可能是注释符的情况
		else if(string[i]=='/')
		{
			if(string[i+1]=='/'&&stack.isEmpty())
				return true;
			else if(string[i+1]=='/'&&!stack.isEmpty())
				return false;
			else if(string[i+1]=='*')
			{
				int flag=0;
				stack.Push(string[i]);
				stack.Push(string[i+1]);
				i=i+2;        //i加2,读取/*后面的字符
				while(string[i]!='\0')
				{
					if(string[i]=='*'&&string[i+1]=='/')
					{
							stack.Pop();
							stack.Pop();
							i=i+2;
							flag=1;
							break;//中断循环
					}
					else
						i++;//未读到*,往后走
				}
				if(flag==0)
					return false;
			}
		}
		//4、读到*/说明而之前没有与之匹配的/*
		else if(string[i]=='*'&&string[i+1]=='/')
			return false;
		//5、往后遍历
		else
		{
			i++;
		}
		if(string[i]=='\0'&&stack.isEmpty())//最终栈空返回true
			return true;
		if(string[i]=='\0'&&!stack.isEmpty())//最终栈非空返回false
			return false;
	}
}

int main()
{
	Stack<int> s(10);
	/*s.Push(10);
	s.Push(20);
	cout<<s.Size()<<endl;
	s.Pop();
	cout<<s.Size()<<endl;
	cout<<s.isEmpty()<<endl;*///Test Stack

	char c='y';
	while(c=='Y'||c=='y')
	{
		if(delimiterMatching())
			cout<<"分隔符匹配成功!"<<endl;
		else
			cout<<"分隔符匹配不成功!"<<endl;
		cout<<"是否继续 (Y/N)"<<endl;
		cin>>c;
	}
	cout<<"退出程序"<<endl;
	return 0;
}


 

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值