作业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'; 后,运行截图如下:
可以观察到每个不匹配的括号都成功输出了,但是最终仍然输出了一条错误信息,不知道程序中哪里出了问题,这是本次作业尚未解决的问题。
12-31
07-14
07-14
02-27
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交