66

作业6(合作完成)  SA17225205_刘金福   SA17225238_吕畅
2017年11月23日星期四
1.	数据结构
堆栈结构
struct stack_struct {
    struct StkElement 	 *base;        	/*堆栈的基地址指针 */
    int                stack_size; 		/*元素个数 */
    int                min_stack;     / *最底层元素的位置 */
    int                max_stack;      /*最大能存储的元素位置*/
    int                top;         	/*当前top指针的位置 */
};

堆栈元素结构
struct StkElement  {
    int   line_no;			/*行号 */
    char  opener;			/*存储括号字符 */
};

2.	函数
void   ClearStack    ( Stack * );        	/*清空堆栈 */
Stack* CreateStack   ( int );          	/*新建堆栈 */
int    PopElement    ( Stack *, struct StkElement * );		/*弹出栈顶元素*/
int    PushElement   ( Stack *, struct StkElement * );       /*弹入一个元素*/

/*以int型的偏移值指向堆栈的相对位置*/
struct StkElement *  ViewElement   ( Stack *, int );	

3.	STACK.c
/*---------------------------------------------------------------
 * 通过将堆栈的top指针指向一个无效的地方从而清空堆栈
 *-------------------------------------------------------------*/
void ClearStack ( Stack *this_stack )
{
    this_stack->top = -1;
}

/*---------------------------------------------------------------
 * 新建堆栈,参数为堆栈大小。初始化堆栈的最小有效数据位置和最大有效数据位置。
 *-------------------------------------------------------------*/
Stack *CreateStack ( int how_many )
{
    Stack *pstk;

    assert ( how_many > 0 );    /* 使用断言判断大小是否正确 */

    pstk = (Stack *) malloc ( sizeof ( Stack ));
    if ( pstk == NULL )
        return ( NULL );

    pstk->stack_size = how_many;
    /* 初始化base指针 */
    pstk->base = ( struct StkElement * )
        malloc ( how_many * sizeof ( struct StkElement ));

    if ( pstk->base == NULL ) /* 如果分配堆栈失败 */
        return ( NULL );

   pstk->min_stack = 0;
   pstk->max_stack = how_many - 1;

   ClearStack ( pstk );

   return ( pstk );
}

/*---------------------------------------------------------------
 * 如果堆栈不为空,弹出一个元素,并且复制该元素的值,top-1
 *-------------------------------------------------------------*/
int PopElement ( Stack *this_stack,
                 struct StkElement * destination )
{
    if ( this_stack->top == -1 ) /* 堆栈已经为空*/
        return ( 0 );

    memmove ( destination,
                &(( this_stack->base )[this_stack->top] ),
                sizeof ( struct StkElement ));

    this_stack->top -= 1;

    return ( 1 );
}

/*---------------------------------------------------------------
 * 将一个元素压入堆栈,如果堆栈未满,top+1;复制这个新元素
 *-------------------------------------------------------------*/
int PushElement ( Stack *this_stack, struct StkElement * to_push )
{
    /* 如果栈满,返回错误 */
    if ( this_stack->top == this_stack->max_stack )
        return ( 0 );

    this_stack->top += 1;

    memmove ( &(( this_stack->base )[this_stack->top] ), to_push,
                        sizeof ( struct StkElement ));

    return ( 1 );
}

/*---------------------------------------------------------------
 * 查看堆栈上的元素。参数指定元素相对于栈顶的位置。 0是栈顶,1是栈顶下面一个的元素,
 * 如果传入一个无效值,该函数返回NULL; 否则,它返回一个指向所请求元素的指针。
 *-------------------------------------------------------------*/
struct StkElement * ViewElement ( Stack *this_stack,
                                  int which_element )
{
    if ( this_stack->top == -1 )
        return ( NULL );
    
    /*如果偏移量无效*/
    if ( this_stack->top - which_element < 0 )
        return ( NULL );

    return ( &(( this_stack->base )
                    [this_stack->top - which_element] ));
}

4.	BRACES.c
/*--- braces.c ---------------------------- Listing 2-8 ---------
 * 检查各种括号是否正确匹配。 
 * 如果不匹配,向stderr打印错误消息,说明在哪一行找到了不匹配的条目。 
 *-------------------------------------------------------------*/
int main ( int argc, char *argv[] )
{
    /* 新建并且初始化堆栈 */
    stk = CreateStack ( 40 );   /* create a stack of 40 items */
    if ( stk == NULL )
    {
        fprintf ( stderr, "Insufficient Memory\n" );
        exit ( EXIT_FAILURE );
    }

    /* 创建临时堆栈元素 */
    stk_el = (struct StkElement *) malloc ( sizeof ( struct StkElement ));
    if ( stk_el == NULL )
    {
        fprintf ( stderr, "Insufficient memory\n" );
        exit ( EXIT_FAILURE );
    }

    /* 行计数器置为0*/
    line_count = 0;

    while ( ! feof ( fin ))
    {
        /* read a line of a C program */
        if ( fgets ( buffer, 127, fin ) == NULL )
            break;
        
        /*读入一行数据就将行号+1 */
        line_count += 1;

        /* 去掉行尾的回车 */
        buffer [ strlen ( buffer ) - 1 ] = '\0';

        /* 扫描并处理各种括号 */
        for ( i = 0; buffer[i] != '\0'; i++ )
        {
            switch ( ch = buffer[i] )
            {
            case '(':
            case '[':
            case '{':
    /*如果遇到正括号,就将当前的行号和括号类型存储到临时堆栈元素中,并压入堆栈 */
                stk_el->opener  = ch;
                stk_el->line_no = line_count;
                if ( ! PushElement ( stk, stk_el ))
                {
                    fprintf ( stderr, "Out of stack space\n" );
                    exit ( EXIT_FAILURE );
                }
                break;
            case ')':
            case ']':
            case '}':
                /*如果遇到反括号,就弹出栈顶元素进行匹配 */
                if ( ! PopElement ( stk, stk_el ))  /*如果栈顶为空,说明不匹配*/
                    fprintf ( stderr, "Stray %c at line %d\n",
                                ch,  line_count );
                else     /*如果栈顶不为空,对括号进行类型匹配*/
                if (( ch == ')'&& stk_el->opener != '(' ) ||
                    ( ch == ']'&& stk_el->opener != '[' ) ||
                    ( ch == '}'&& stk_el->opener != '{' ))
                    fprintf ( stderr,
                      "%c at line %d not matched by %c at line %d\n",
                       ch, line_count,
                       stk_el->opener, stk_el->line_no );
                break;
            default:
                continue;
            }
        }
    }

    /* 读取完文件,如果堆栈中还有元素,说明还是不匹配的 */
    if ( ViewElement ( stk, 0 ) != NULL )
        while ( PopElement ( stk, stk_el ) != 0 )
            fprintf ( stderr, "%c from line %d unmatched\n",
                        stk_el->opener, stk_el->line_no );

    fprintf ( stderr, "Error checking complete\n" );

    fclose ( fin );
	getchar();
    return ( EXIT_SUCCESS );
}

5.	运行结果
传入一个文件内容如下,每行都是不匹配的括号,每一行就有对应行数个不匹配的括号。
{
[[
[[[
[[[[
[[[[[
 
可以看到最后一行最后一个括号(最后一个元素)没有入栈进行匹配。
是buffer [ strlen ( buffer )  -1 ] = '\0'; 处理最后一行元素时覆盖了最后一个元素,因为本程序只对各种括号进行匹配,对其他元素即使读入也不会进行匹配处理,因此可以将 -1 去掉,保证最后一个元素入栈。
修改为buffer [ strlen ( buffer ) ] = '\0'; 后,运行截图如下:
  
可以观察到每个不匹配的括号都成功输出了,但是最终仍然输出了一条错误信息,不知道程序中哪里出了问题,这是本次作业尚未解决的问题。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值