#include < stdio.h >
#include < stdlib.h >
#include < string.h >#define TRUE 1 // 'true' is OK !
#define FALSE 0 // 'false' is OK !
#define OK 1
#define ERROR 0
#define OVERFLOW -2#define MAXSIZE 100 //串的定长顺序存储表示
typedef char SString[ MAXSIZE + 1 ] ; //0号单元存放串的当前长度typedef int Status;
typedef char AtomType ;typedef enum { ATOM , LIST }ElemTag ; //ATOM==0:原子,LIST==1:子表 ( enum 枚举 )
typedef struct GLNode
{
ElemTag tag ; // 公共部分,用于区分原子结点和表结点
union // 原子结点和表结点的联合部分 ( union 联合体 )
{
AtomType atom ; // atom是原子结点的值域,AtomType由用户定义.只供原子节点使用
struct GLNode *hp ; //表结点的表头指针
} ;
struct GLNode *tp ; //相当于线性链表的next,指向下一个元素结点
} GLNode , *GList ;//-----------------------String Fuction!--------------------------//
Status StrAssign( SString T , char *ch )
{
int i = 0 ;
if( strlen( ch ) > MAXSIZE )
{
exit( 0 ) ;
}
else
{
T[ 0 ] = strlen( ch ) ;
for( i = 1 ; i <= T[ 0 ] ; ++ i )
{
T[ i ] = ch[ i - 1 ] ;
}
}
T[ i ] = '\0' ;return OK ;
}Status StrCopy( SString T , SString S ) //S = T ;
{
int i = 0 ;for( i = 0 ; i <= T[ 0 ] ; ++ i )
{
S[ i ] = T[ i ] ;
}return OK ;
}Status StrEmpty( SString S ) //已有的前提是S已经存在
{
if( S[ 0 ] == 0 )
{
return TRUE ;
}
else
{
return FALSE ;
}
}// 若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0
Status StrCompare( SString S , SString T )
{
int i = 0 ;for( i = 1 ; i <= S[ 0 ] && i <= T[ 0 ] ; ++ i )
{
if( S[ i ] != T[ i ] ) //相等则比较下一位
{
return S[ i ] - T[ i ] ;
}
}
return S[ 0 ] - T[ 0 ] ; //相同长度的字符比较完后如果还没分出胜负,呵呵,就得看谁耐力更好了!
}// 返回串的元素个数
Status StrLength( SString S )
{
return S[ 0 ] ;
}// 将S清为空串
Status ClearString( SString S )
{
S[ 0 ] = 0 ;
return OK ;
}// 用Sub返回串S的第pos个字符起长度为len的子串。
Status SubString( SString Sub , SString S , int pos , int len )
{
int i = 0 ;if( pos < 0 || pos > S[ 0 ] || len < 0 || len > S[ 0 ] - pos + 1 ) //安全判断必不可少哦!
{
exit( 0 ) ;
}Sub[ 0 ] = len ;
// for( i = pos ; i < pos + len ; ++ i )
// {
// Sub[ i - pos + 1 ] = S[ i ] ;
// }
for( i = 1 ; i <= len ; ++ i ) // It's OK !
{
Sub[ i ] = S[ i + pos - 1 ] ;
}
Sub[ i ] = '\0' ;return OK ;
}//将非空串str分割成两部分:hsub为第一个','之前的子串,str为之后的子串
//如果串str中没有字符',',则操作后的hstr即为操作前的str,而操作后的str为空串NULL
Status sever( SString str , SString hstr )
{
int n = 0 , i = 0 , k = 0 ; // k记尚未配对的左括号个数
SString ch , c1 , c2 , c3 ;n = StrLength( str ) ;
/* do //搜索最外层的第一个逗号
{
++ i ;
SubString( ch , str , i , 1 ) ;
if( ch == '(' )
{
++ k ;
}
else
{
if( ch == ')' )
{
-- k ;
}
}
}while( i < n && ( ch != ',' || k != 0 ) ) ; //Take care about it !if( i < n ) //ch != ',' or k != 0
{
SubString( hstr , str , 1 , i - 1 ) ;
SubString( str , str , i + 1 , n - i ) ;
}
else
{
StrCopy( str , hstr ) ; //hstr = str ;
ClearString( str ) ;
} */StrAssign( c1 , "," ) ;
StrAssign( c2 , "(" ) ;
StrAssign( c3 , ")" ) ;
SubString( ch , str , 1 , 1 ) ;
// 搜索最外层的第一个逗号
for( i = 1 , k = 0 ; i <= n && StrCompare( ch , c1 ) || k != 0 ; ++ i )
{
SubString( ch , str , i , 1 ) ;
if( !StrCompare( ch , c2 ) )
{
++ k ;
}
else
{
if( !StrCompare( ch , c3 ) )
{
-- k ;
}
}
}if( i <= n ) //ch != ',' or k != 0
{
SubString( hstr , str , 1 , i - 2 ) ;
SubString( str , str , i , n - i + 1 ) ;
}
else
{
StrCopy( str , hstr ) ; //hstr = str ;
ClearString( str ) ;
}return OK ;
}//---------------------------GList Fuction!-----------------------------//
Status InitGList( GList *L )
{
*L = NULL ;
return OK ;
}Status CreateGList( GList *L , SString S )
{
SString emp , sub , hsub ;GList p ;
StrAssign( emp , "()" ) ;*L = ( GList )malloc( sizeof( GLNode ) ) ; //take care! It's '*L', not 'L'.
if( !(*L) )
{
exit( OVERFLOW ) ;
}if( !StrCompare( S , emp ) ) //List is NULL!
{
( *L )->tag = LIST ;
( *L )->hp = ( *L )->tp = NULL ;
}
else
{
if( StrLength( S ) == 1 ) //only one atom!
{
( *L )->tag = ATOM ;
( *L )->atom = S[ 1 ] ;
( *L )->tp = NULL ;
}
else
{
( *L )->tag = LIST ;
( *L )->tp = NULL ;SubString( sub , S , 2 , StrLength( S ) - 2 ) ;
sever( sub , hsub ) ;
CreateGList( &( *L )->hp , hsub ) ;
p = ( *L )->hp ;
while( !StrEmpty( sub ) )
{
sever( sub , hsub ) ;
CreateGList( & p->tp , hsub ) ;
p = p->tp ;
}
}
}
return OK ;
}Status DestoryGList( GList *L )
{
GList ph , pt ;if( *L ) // (*L) is not a NULL List .
{
if( ( *L )->tag == 1 ) //It's a List !
{
ph = ( *L )->hp ;
}
else //It's a atom!
{
ph = NULL ;
}
pt = ( *L )->tp ;
DestoryGList( &ph ) ;
DestoryGList( &pt ) ;
free( *L ) ;
( *L ) = NULL ;
}
return OK ;
}Status CopyGList( GList *T , GList L ) //( *T ) = L ;
{
( *T ) = NULL ; //when L is a NULL List ,that's OK!
if( L )
{
( *T ) = ( GList )malloc( sizeof( GLNode ) ) ;
if( !( *T ) )
{
exit( OVERFLOW ) ;
}( *T )->tag = L->tag ;
if( L->tag == ATOM ) //atom
{
( *T )->atom = L->atom ;
}
else //List
{
CopyGList( &( *T )->hp , L->hp ) ;
}if( L->tp == NULL ) //the tail of list !
{
( *T )->tp = L->tp ;
}
else
{
CopyGList( &( *T )->tp , L->tp ) ;
}
}
return OK ;
}int GListDepth( GList L ) //括弧的重数
{
int max , dep ;
GList p ;if( L == NULL || ( L->tag == LIST && !( L->hp ) ) )
{
return 1 ; //The List of NULL!
}
else
{
if( L->tag == ATOM )
{
return 0 ; //only one atom!
}
else
{
for( max = 0 , p = L->hp ; p ; p = p->tp)
{
dep = GListDepth( p ) ;
if( dep > max )
{
max = dep ;
}
}
}
}
return ( max + 1 ) ;
}int GListLength( GList L ) //广义表长度是数第一层括号内的逗号数目加一
{
int len = 0 ;
if( L )
{
L = L->hp ;
while( L )
{
L = L->tp ;
++ len ;
}
}
return len ;
}Status GListEmpty( GList L )
{
if( L == NULL || ( L->tag == LIST && !( L->hp ) ) ) //"L == NULL" is more clear than "!L".
{
return OK ;
}
return FALSE ;
}GList GetHead( GList L )
{
GList h , p ;if( L == NULL || ( L->tag == LIST && !( L->hp ) ) )
{
return NULL ;
}p = L->hp->tp ; //p point to the tail! take care about it!
L->hp->tp = NULL ; // cut the tail!CopyGList( &h , L->hp ) ;//very good!
L->hp->tp = p ; //recover the tail!return h ;
}GList GetTail( GList L )
{
GList t , p ;if( L == NULL || ( L->tag == LIST && !( L->hp ) ) )
{
return NULL ;
}p = L->hp ;
L->hp = p->tp ; //cut head of 'p'! Then L is a tail!CopyGList( &t , L ) ;
L->hp = p ; //recover!return t ;
}Status InsertFirst_GL( GList *L , GList e )
{
GList p ;p = ( *L )->hp ;
( *L )->hp = e ;
e->tp = p ; //link!return OK ;
}Status DeleteFirst_GL( GList *L , GList *e )
{
if( ( *L ) && ( *L )->hp )
{
*e = ( *L )->hp ;
( *L )->hp = ( *e )->tp ;
( *e )->tp = NULL ;
}
else
{
*e = *L ;
}
return OK ;
}Status Travers_GL( GList L , void ( *v )( AtomType ) )
{
GList hp ;
if( L )
{
if( L->tag == ATOM )
{
v( L->atom ) ;
hp = NULL ;
}
else
{
hp = L->hp ;
}Travers_GL( hp , v ) ;
Travers_GL( L->tp , v ) ;
}
return OK ;
}Status visit( AtomType e )
{
printf( "%3c" , e ) ;
return OK ;
}//----------------------------Main Fuction!--------------------------//
int main( )
{
char *ch = { "(a,(b),c,(d,(e)))" } ;
SString T ;
GList L ;InitGList( &L ) ;
StrAssign( T , ch ) ;// printf( "%d\n" , GListEmpty( L ) ) ; //'1' equal empty!
// printf( "%d\n" , GListDepth( L ) ) ;
// printf( "%d\n" , GListLength( L ) ) ;CreateGList( &L , T ) ;
puts( ch ) ;
// printf( "%d\n" , GListEmpty( L ) ) ;
// printf( "%d\n" , GListDepth( L ) ) ;
// printf( "%d\n" , GListLength( L ) ) ;
Travers_GL( L , visit ) ;
printf( "\n" ) ;Travers_GL( GetHead( L ) , visit ) ;
printf( "\n" ) ;Travers_GL( GetTail( L ) , visit ) ;
printf( "\n" ) ;InsertFirst_GL( &L , GetHead( L ) ) ;
Travers_GL( L , visit ) ;
printf( "\n" ) ;
DeleteFirst_GL( &L , GetHead( L ) ) ;
Travers_GL( L , visit ) ;
printf( "\n" ) ;return 0 ;
}