66

来源:互联网 发布:windows放大镜快捷键 编辑:程序博客网 时间:2024/04/29 08:41
作业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'; 后,运行截图如下:  可以观察到每个不匹配的括号都成功输出了,但是最终仍然输出了一条错误信息,不知道程序中哪里出了问题,这是本次作业尚未解决的问题。