栈的链表实现,以及编译原理中的括号匹配

来源:互联网 发布:软件测试虫师 编辑:程序博客网 时间:2024/06/04 20:01

一:

编译原理常有括号的匹配算法。用数组和链表实现的栈都可以实现。现用链表吧。

 

代码:

 

 

cyq@cyq-desktop:~/桌面/C$ cat LinkStack2.c

 

 

#include <iostream>

#include <cstdlib>

#include <assert.h>

using namespace std;

 

class LinkStackNode {

public:

char data;

LinkStackNode* link;

LinkStackNode(char& value):link(NULL),data(value){}

};

class LinkStack{

LinkStackNode* head;

public:

LinkStack():head(NULL){}

void Push(char& value);

char& GetTop();

char  Pop();

boolIsEmpty();

voidMakeEmpty();

};

 

voidLinkStack::Push(char& value)

{

LinkStackNode* add= new LinkStackNode(value);

add->link= head;

head=add;

}

 

char&LinkStack::GetTop()

{

return head->data;

}

 

char LinkStack::Pop()

{

assert(head!=NULL);

LinkStackNode*  old = head;

head = head->link;

char data=old->data;

deleteold;

return data;

}

 

bool LinkStack::IsEmpty()

{

return

head==NULL;

}

 

 

 void LinkStack::MakeEmpty()

{

while(!this->IsEmpty())

{

this->Pop();

}

}

 

 

int main(int argc , char *argv[])

{

cout<<"输入括号序列(以为@结束标志):"<<endl;

LinkStacksmall;

char a;

while(cin.peek()!='@'){

cin>>a;

switch(a)

{

case '(':small.Push(a);break;

case ')':

if(!small.IsEmpty())

{

small.Pop();    break;

}

if(small.IsEmpty())

{

cout<<"匹配失败!"<<endl;

exit(0);

break;

}

}

};

if(small.IsEmpty())

cout<<"匹配成功!"<<endl;

else

cout<<"匹配失败!"<<endl;

 

return 0;

 

}

 

 

二:编译并运行:

 

 

cyq@cyq-desktop:~/桌面/C$ g++ LinkStack2.c -o LinkStack2   && ./LinkStack2

输入括号序列(以为@结束标志):

longxibendi(()) (longxibendi)@

匹配成功!

cyq@cyq-desktop:~/桌面/C$ ./LinkStack2

输入括号序列(以为@结束标志):

(longxibendi@126.com)

匹配失败!

     
三:代码分析:
一共用了两个类,一个节点类,一个栈类。
节点类是:LinkStackNode
栈类是:LinkStack
    
如果链表会的话,这个程序很简单。就解释以下部分:
1.  while(cin.peek()!='@')
 使用peek方法,接收一个字符,如果是@则停止接收。
      
2.  this
  成员函数具有一个附加的隐含行参,即指向该类对象的一个指针。这个隐含行参命民为this,与调用成员函数的对象绑定在一起。成员函数的函数体可以显示的使用this指针。但不是必须这么做。所以:我在程序中,IsEmpty()使用了this .

 

void LinkStack::MakeEmpty()

{

while(!this->IsEmpty())

{

this->Pop();

}

}

 

如果不理解,就直接理解为对象的指针好了。而在定义函数时,还没有对象(是在类中定义函数),所以没法使用对象。但这时可以使用this来代替。
具体可以参考:http://topic.csdn.net/u/20070306/22/81af1a98-6633-4be4-9690-59575f42ee3a.html
也可以看《C++ Primer》 第四版 376页
      
3.  assert(head!=NULL);
assert(),如果括号内的条件满足,程序就往下执行,否则,程序终止
使用这个函数,需要包含头文件assert.h
       
四:代码扩充
使用fstream,打开读取文件
如果喜欢的话,可以用open,从文本读入数据,然后再匹配。
1.比如可以这样写
cyq@cyq-desktop:~/桌面/C$ cat LinkStack3.c
#include <iostream>
#include <cstdlib>
#include <assert.h>
#include <fstream>
using namespace std;
class LinkStackNode {
public:
char data;
LinkStackNode* link;
LinkStackNode(char& value):link(NULL),data(value){}
};
class LinkStack{
LinkStackNode* head;
public:
LinkStack():head(NULL){}
void Push(char& value);
char& GetTop();
char  Pop();
boolIsEmpty();
voidMakeEmpty();
};
voidLinkStack::Push(char& value)
{
LinkStackNode* add= new LinkStackNode(value);
add->link= head;
head=add;
}
char&LinkStack::GetTop()
{
return head->data;
}
char LinkStack::Pop()
{
assert(head!=NULL);
LinkStackNode*  old = head;
head = head->link;
char data=old->data;
deleteold;
return data;
}
bool LinkStack::IsEmpty()
{
return
head==NULL;
}
/*
 void LinkStack::MakeEmpty()
{
while(!this->IsEmpty())
{
this->Pop();
}
}
*/
int main(int argc , char *argv[])
{
cout<<"输入括号序列(以为@结束标志):"<<endl;
LinkStacksmall;
char a;
ifstream inf;
inf.open("test.txt");
if(!inf)
{cerr<<"Error!Open fault!"<<endl;
return 0 ;
}
while(inf >>a)
{
if(a=='@')
break;
switch(a)
{
case '(':small.Push(a);break;
case ')':
if(!small.IsEmpty())
{
small.Pop();    break;
}
if(small.IsEmpty())
{
cout<<"匹配失败!"<<endl;
exit(0);
break;
}
}
};
inf.close();
  
if(small.IsEmpty())
cout<<"匹配成功!"<<endl;
else
cout<<"匹配失败!"<<endl;
return 0;
}
    
2.test.txt 内容如下:
cyq@cyq-desktop:~/桌面/C$ cat test.txt
#include <iostream>
main
(    )
(000)
longxibendi@126.com
  
http://blog.csdn.net/longxibendi
  
3.编译运行:
cyq@cyq-desktop:~/桌面/C$ g++ LinkStack3.c -o LinkStack3  && ./LinkStack3
输入括号序列(以为@结束标志):
匹配成功!
               
五:总结:
这个程序编译器中用到了。结合以前学过的this,assert,peek,open来灵活运用栈。顺便复习以下以前的知识了。

声明:本文档可以随意更改,但必须署名原作者

                       

作者:凤凰舞者 qq:578989855

 

原创粉丝点击