[c언어]알고리즘이 잘된건지좀 보고 리플좀..부탁.

lh8557의 이미지

알고리즘은 자연어로 기술할께요.
중위연산자[infix]로 입력받아서 후위연산자[postfix]로 바까서
출력하고 후위연산자를 계산하여 값을 출력하는 계산기입니다.
거기에 ++ 연산자도 되게 포함했는데 값은나오는데
맞게 구현한건지 모르겠네요..리플좀부탁합니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STACK_SIZE 100			/* 스택 최대 크기 */
#define MAX_EXPR_SIZE 100			/* 받는 문자열 최대 크기 */
typedef enum {lparen, rparen, plus, minus, times, divide, mod, rbig, lbig, not, equal, and, or,
			increase, eos, operand} precedence;
int stack[MAX_STACK_SIZE];
char inexpr[MAX_EXPR_SIZE];			/* 중위 배열 */
char outexpr[MAX_EXPR_SIZE];		/* (중위 -->)후위 배열 */
void postfix(void);					
int eval();
static int isp[] = {0,19,12,12,13,13,13,10,10,15,9,5,4,15,0};
static int icp[] = {20,19,12,12,13,13,13,10,10,15,9,5,4,15,0};

void main(void)						/* 중위식 후위식으로 변환/계산 */
{
	
	char c = 'y';
	while(c=='y')	
	{
		printf("Input the expression : ");
		scanf("%s", inexpr);
		postfix();
		printf("%s\n",outexpr);
		printf("Evaluation Value : %d\n",eval());
		printf("\nDo you want to do another expression('y'or'n')? ");
		scanf("%s", &c);
	}
}

char delete(int *top)
{
	if(*top == -1)
	{
		printf("Stack Empty!!");
		exit(1);
	}
	return stack[(*top)--];
}

void add(int *top,int item)
{
	if(*top == MAX_STACK_SIZE - 1)
	{
		printf("Stack Full!!");
		exit(1);
	}
	stack[++*top] = item;
}

precedence get_token(char expr[],char *symbol, int *n)	/* 중위식-후위식 토큰 */
{
	
	if(expr[*n] == '+' && expr[(*n)+1] == '+') // ++연산자를 a로 치환하기위해 ++연산자를 찾는과정
	{
		
		expr[++(*n)]='\0'; // ++연산자를 찾았으면 공백를 줘서 다음에 a로 치환된 연산자를 읽음
		
		return increase;
	}
	else
		*symbol = expr[(*n)++];
		switch(*symbol)
		{
			case '(' : return lparen;
			case ')' : return rparen;
			case '+' : return plus;
			case '-' : return minus;
			case '/' : return divide;
			case '*' : return times;
			case '%' : return mod;
			case '\0': return eos;
			case '>' : return rbig;
			case '<' : return lbig;
			case '!' : return not;
			case '==': return equal;
			case '&&': return and;
			case '||': return or;
			case 'a' : return increase;
			default  : return operand;
		}
}

char print_token(precedence deltop)				/* 문자열 연산식을 기호로 바꾼다 */
{
	if(deltop == plus) 
		return putchar('+');
	else if (deltop == minus) 
		return putchar('-');
	else if (deltop == times) 
		return putchar('*');
	else if (deltop == divide) 
		return putchar('/');
	else if (deltop == mod) 
		return putchar('%');
	else if (deltop == increase) // 인크리즈가 get_token에서 리턴되면 a로 치환
		return putchar('a');
}


void postfix(void)		/* 중위식(inexpr)을 후위식으로 바꾸고 outexpr 배열에 삽입 */
{
	char symbol;
	precedence token;
	int n = 0;
	int top = 0;
	int n2 = 0;			/* outexpr을 하나씩 증가 시켜 후위식을 넣기 위한 변수 */
	stack[0] = eos;

	for(token = get_token(inexpr,&symbol, &n); token != eos; token = get_token(inexpr,&symbol, &n))
	{
		if(token == operand)
			outexpr[n2++] = symbol;
		else if(token == rparen)
		{
			while (stack[top] != lparen)
				outexpr[n2++] = print_token(delete(&top));
			delete(&top);
		}
		else
		{
			while (isp[stack[top]]>=icp[token])
				outexpr[n2++] = print_token(delete(&top));
			add(&top,token);
		}
	}
	while((token = delete(&top)) != eos)		/* 스택에 남은 나머지를 모두 빼서 outexpr에 넣는다 */
		outexpr[n2++] = print_token(token);
	printf("\n");
}

int eval()				/* 후위식 계산 */
{
	precedence token;
	char symbol;
	int op1, op2;
	int n = 0;
	int top = -1;
	token = get_token(outexpr,&symbol, &n);
	while(token != eos) 
	{
		if(token == operand)	/* 토큰이 상수이면 ASKI Code '0'을 빼서 상수화한후에 삽입 */
			add(&top, symbol-'0');
		else if(token == increase)/*++연산자일경우*/
		{
			op2 = delete(&top);
			op2 = op2 + 1;
			add(&top, op2);
		}
		else
		{
			op2 = delete(&top);		/* 연산식이 나오면 스택 맨위(첫번째)에 상수값을 빼서 저장 */
			op1 = delete(&top);		/* 스택 맨위(두번째) 상수값을 뺀다 */
			switch (token)			/* op1과 op2를 계산 후 다시 스택에 쌓는다 */
			{
				case plus: add(&top, op1+op2);
					break;
				case minus: add(&top, op1-op2);
					break;
				case times: add(&top, op1*op2);
					break;
				case divide: add(&top, op1/op2);
					break;
				case mod: add(&top, op1%op2);
			}
		}
		token = get_token(outexpr,&symbol, &n);
	}
	return delete(&top);
}
galadriel의 이미지

우선 지금 보이는 건

       case '==': return equal; 
       case '&&': return and; 

이 두부분인데요.. 저런식으로 선언되어 있으면 문자열일텐데요.
차라리 토큰으로 다 짤려져 있다면 strcmp를 쓰는것도 좋지 않을까요?

galadriel in the tower of elves

세벌의 이미지

galadriel wrote:
우선 지금 보이는 건

       case '==': return equal; 
       case '&&': return and; 

이 두부분인데요.. 저런식으로 선언되어 있으면 문자열일텐데요.
차라리 토큰으로 다 짤려져 있다면 strcmp를 쓰는것도 좋지 않을까요?


에러는 안 나나요? '==' 가 character 맞나요? case 다음에는 character 가 나와야 되는 것으로 알고 있었는데...
galadriel의 이미지

sebul wrote:
galadriel wrote:
우선 지금 보이는 건

       case '==': return equal; 
       case '&&': return and; 

이 두부분인데요.. 저런식으로 선언되어 있으면 문자열일텐데요.
차라리 토큰으로 다 짤려져 있다면 strcmp를 쓰는것도 좋지 않을까요?


에러는 안 나나요? '==' 가 character 맞나요? case 다음에는 character 가 나와야 되는 것으로 알고 있었는데...

warning이 뜨는데요...
test1.c:5: warning: multi-character character constant
이놈은 선언시에 뜨구요.
char c = '=='; 이런식으로 선언하거나 할때.

test1.c:5: warning: overflow in implicit constant conversion
이 워닝은 위에서 선언한 변수를 사용할때 뜹니다.

galadriel in the tower of elves

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.