알고리즘 질문입니다.

namola의 이미지

#include <stdio.h>
#include <stdlib.h>

#define MAX 10

typedef struct _node   /*나무의 노드*/
{
	int key;
	struct _node *left;
	struct _node *right;
} node;

node *head, *tail;/* 머리와 꼬리*/
node *stack[MAX];/*스택 구조의 정의*/
node *queue[MAX];/*큐 구조의 정의*/

int  front, rear;
int  top;

void init_stack( void );
node *push( node *t );
node *pop( void );
int  is_stack_empty( void );
void init_queue();
node *put( node *k );
node *get( void );
int  is_queue_empty( void );
void init_tree( void );
int  is_operator( int k );
node *make_parse_tree( char *p );
int  is_legal( char *s );
void visit( node *t );
void preorder_traverse( node *t );
void inorder_traverse( node *t );
void postorder_traverse( node *t );
void levelorder_traverse( node *t );

int main( void )
{
	char post[256];/*후위표기법 수식을 저장*/
	init_stack(); /*스택과 큐의 나무의 초기화*/
	init_queue();/*큐를 초기화 하는 함수*/	
	init_tree();/*나무 구조의 초기화*/

	while( 1 )
	{
		printf("\n Input Postfix expression ->");
		fgets( post, sizeof(post), stdin );

		if( *post == NULL )/*아무것도 입력하지 않은 경우*/
		{
			printf("\n Program ends....\n");
			exit( 0 );
		}
		
		if( !is_legal( post ) )/*수식이 적법하지 않으면*/
		{
			printf("\nExpression is not legal.\n");
			continue;
		}

		head->right = make_parse_tree( post );/*수식나무 구성*/

		printf("\nPreorder traverse ->");
		preorder_traverse( head->right );

		printf("\nInorder traverse ->");
		inorder_traverse( head->right );

		printf("\nPostorder traverse ->");
		postorder_traverse( head->right );

		printf("\nLevelorder traverse ->");
		levelorder_traverse( head->right );
	}

	return 0;
}

void init_stack( void )
{
	top = -1;
}

node *push( node *t )
{
	if( top >= MAX - 1 )
	{
		printf("\n Stack overflow.\n");
		return NULL;
	}
	stack[++top] = t;
	return t;
}

node *pop( void )
{
	if( top < 0 )
	{
		printf("\n Stack underflow." );
		return NULL;
	}

	return stack[top--];
}

int is_stack_empty( void )
{
	return ( top == -1 );
}

void init_queue( void )
{
	front = rear = 0;
}

node *put( node *k )
{
	if( ( rear + 1 ) % MAX == front )/*큐가 꽉 찼으면*/
	{
		printf("\n Queue overflow.");
		return NULL;
	}

	queue[rear] = k;
	rear = ++rear % MAX;
	return k;
}

node *get( void )
{
	node *i;
	if( front == rear )/*큐가 비어 있으면*/
	{
		printf("\n Queue underflow.");
		return NULL;
	}

	i = queue[front];
	front = ++front % MAX;
	return i;
}

int is_queue_empty( void )
{
	return ( front == rear );
}

void init_tree( void )/*나무 구조의 초기화*/
{
	head = (node*)malloc( sizeof( node ) );
	tail = (node*)malloc( sizeof( node ) );
	head->left  = tail;
	head->right = tail;
	tail->left  = tail;
	tail->right = tail;
}

int is_operator( int k )/*k가 연산자이면 참*/
{
	return ( k == '+' || k == '-' || k == '*' || k == '/' );
}

node *make_parse_tree( char *p )/*후외 표기법 수식에서 수식 나무 구성*/
{
	node *t;
	while( *p )
	{
		while( *p == ' ' )/*공백 문자는 제거*/
			p++;

		t = (node*)malloc( sizeof( node ) );
		t->key   = *p;
		t->left  = tail;
		t->right = tail;
		
		if( is_operator( *p ) )/* 연산자이면 팝을 하여 자식 노드로 삼음*/
		{
			t->right = pop();
			t->left  = pop();
		}

		push( t );
		p++;
	}

	return pop();
}

int is_legal( char *s )
{
	int f = 0;
	while( *s )
	{
		while( *s == ' ' )/*공백을 제거*/
			s++;
		
		if( is_operator( *s ) )
		{
			printf("리턴값 : %d\n", is_operator( *s ) );
			f--;/*연산이면 감소*/
		}
		else
		{
			f++;/*피연산자 이면 증가*/
			//printf("f 증가 : %d\n", f );
		}

		if( f < 1 ) break;/* f가 1보다 작아지면 언더플로*/
			s++;
	}

	printf(" f: %d\n", f );
	return ( f == 1 );/* 피연산자 - 연산자수 = 1이 되어야함*/
}

void visit( node *t )/*........_traverse()류 함수에서 사용*/
{
	printf("%c", t->key );
}

void preorder_traverse( node *t )/*뿌리를 먼저 타는 방식*/
{
	if( t != tail )
	{
		visit( t );
		preorder_traverse( t->left  );
		preorder_traverse( t->right );
	}
}

void inorder_traverse( node *t )/*뿌리를 중간에 타는 방식*/
{
	if( t != tail )
	{
		inorder_traverse( t->left );
		visit( t );
		inorder_traverse( t->right );
	}
}

void postorder_traverse( node *t )/*뿌리를 나중에 타는 방식*/
{
	if( t != tail )
	{
		postorder_traverse( t->left  );
		postorder_traverse( t->right );
		visit( t );
	}
}

void levelorder_traverse( node *t )/*층별로 타는 방식*/
{
	put( t );
	while( !is_queue_empty() )
	{
		t = get();
		visit( t );
		
		if( t->left != tail )
			put( t->left );
		
		if( t->right != tail )
			put( t->right );
	}
}

에러는 다음과 같이 나옵니다.
tree.c: In function `main':
tree.c:50: warning: comparison between pointer and integer
tree.c: In function `put':
tree.c:126: warning: operation on `rear' may be undefined
tree.c: In function `get':
tree.c:140: warning: operation on `front' may be undefined

만약에 이프로그램을 실행 시키면

Input Postfix expression->AB+CD-*E/FG*+
Preorder traverse->+/*+AB-CDE*FG
Inorder traverse->A+B*C-D/E+F*G
Postorder traverse->AB+CD-*E/FG*+
Levelorder traverse->+/**EFG+-ABCD

아무것도 입력안하고 ENTER만 쳤을때는 
Input Postfix expression->
Program ends....

이렇게 나와야 하는데...
Input Postfix expression ->AB+CD-*E/FG*+

Expression is not legal.

엔터만 쳤을겨우
 Input Postfix expression ->

Preorder traverse ->

Inorder traverse ->

Postorder traverse ->

Levelorder traverse ->

 Input Postfix expression ->

무엇이 잘못된건가요.
sozu의 이미지

입렵받는 것을 다음과 같이 해보니

while(gets(post) != NULL && strcmp(post, "#") != 0)

잘 되는군요. 8)

-----------
청하가 제안하는 소프트웨어 엔지니어로써 재미있게 사는 법
http://sozu.tistory.com

kall의 이미지

line 50을
if( strcmp(post,"\n") == 0 )/*아무것도 입력하지 않은 경우*/
또는
if( post[0] == '\n' )/*아무것도 입력하지 않은 경우*/

----
자신을 이길 수 있는자는
무슨짓이든 할수있다..
즉..무서운 넘이란 말이지 ^-_-^
나? 아직 멀었지 ㅠㅠ

nayana의 이미지

일단 답변 감사합니다.
엔터처리는 이제는 양호하게 됩니다.
그런데...

Input Postfix expression ->AB+CD-*E/FG*+

Expression is not legal.

 Input Postfix expression ->

 Program ends....

왜 그러는 거지요 그리고...
다음과 같은 WARNNING
gcc -o tree tree.c -Wall
tree.c: In function `put':
tree.c:127: warning: operation on `rear' may be undefined
tree.c: In function `get':
tree.c:141: warning: operation on `front' may be undefined
kall의 이미지

nayana wrote:

Input Postfix expression ->AB+CD-*E/FG*+

Expression is not legal.

 Input Postfix expression ->

 Program ends....

왜 그러는 거지요

디버거로 post의 값을 찍어보면 아시겠지만,
스트링의 끝에 '\n'이 들어갑니다.
그걸 제거 하시면 문제없이 돌아갑니다.

nayana wrote:

다음과 같은 WARNNING
gcc -o tree tree.c -Wall
tree.c: In function `put':
tree.c:127: warning: operation on `rear' may be undefined
tree.c: In function `get':
tree.c:141: warning: operation on `front' may be undefined

글쎄요..제 기계에서는 에러없이 도는데요.. gcc 2.95 입니다.

ps. 디버거를 사용하시는 습관을 들어보시기 바랍니다.

----
자신을 이길 수 있는자는
무슨짓이든 할수있다..
즉..무서운 넘이란 말이지 ^-_-^
나? 아직 멀었지 ㅠㅠ

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.