ÃÑ ÆäÀÌÁö ¼ö : 3224
![]()
|
Facebook Joinc ±×·ì
Joinc QA »çÀÌÆ®
ÇöÀçÀ§Ä¡ : article>calculator
![]()
Tweet
joinc´Â Firefox¿Í chrome¿¡¼ Å×½ºÆ® Çß½À´Ï´Ù. IE¿¡¼´Â Å×À̺íÀÌ ±úÁö°Å³ª À̹ÌÁö°¡ º¸ÀÌÁö ¾ÊÀ» ¼ö ÀÖ½À´Ï´Ù. ƯÈ÷ ±¸±Û DocsÀ̹ÌÁöÀÇ °æ¿ì ¿¢¹Úó¸®µÉ ¼ö ÀÖ½À´Ï´Ù. 1 °è»ê±â ¿¹Á¦
ÀÛ¼ºÀÚ: mwyun(¸Û)
°¢Á¾ °è»ê±â ÇÁ·Î±×·¥À» º¸°í ½ºÅðú ¹è¿µîÀ» ¾î¶»°Ô ÀÌ¿ëÇÏ¿© ¾î¶»°Ô °è»ê±â¸¦ ±¸ÇöÇÏ¿´´ÂÁö ¾Ë¾Æº»´Ù. ¶ÇÇÑ ÀڷᱸÁ¶ °ÁÂÀÇ list¿Í stack ¼Ò½º¿Í º» °ÁÂÀÇ °è»ê±â ¾Ë°í¸®ÁòÀ» ÀÌ¿ëÇÏ¿© °è»ê±â ÇÁ·Î±×·¥À» Á÷Á¢ ¸¸µé¾î º»´Ù. º» °Á´ ÇÊÀÚ°¡ ´ëÇÐ ¶§ µµ½º±â¹ÝÀÇ TC++ 3.0¿¡¼ ÀÛ¼ºÇÏ¿´´ø ¼Ò½ºµéÀ» ´Ù½Ã ¸®´ª½º¿ëÀ¸·Î Æ÷ÆÃÇÑ °ÍÀÌ´Ù. 1.1 ¾Ë°í¸®Áò1.2 stack.h// °£´ÜÇÑ ½ºÅà ÅÛÇø´ Ŭ·¡½º
#include <iostream.h>
const int DefaultSize = 80;
enum Boolean
{ FALSE = 0, TRUE = 1 };
template < class KeyType > class Stack {
private:
int top; // ½ºÅÃÀÇ top
KeyType *stack; // ½ÇÁ¦ µ¥ÀÌÅͰ¡ ÀúÀåµÇ´Â ½ºÅà Æ÷ÀÎÅÍ
int MaxSize; // ½ºÅÃÀÇ ÃÖ´ëÅ©±â
public:
Stack (int MaxStackSize = DefaultSize); // °´Ã¼ »ý¼ºÀÚ
~Stack (); // °´Ã¼ ÆÄ±«ÀÚ
void Add (const KeyType & x); // ½ºÅÃÀÇ top¿¡ ÇØ´ç °ªÀ» Ãß°¡
KeyType *Delete (KeyType & x); // ½ºÅÃÀÇ topÀÇ ÇØ´ç °ªÀ» »èÁ¦
Boolean IsFull (); // ½ºÅÃÀÌ °¡µæÃ¡´Â°¡ üũ
Boolean IsEmpty (); // ½ºÅÃÀÌ ºñ¾ú´Â°¡ üũ
KeyType *GetStackTop (KeyType & x); // ½ºÅÃÀÇ top°ªÀ» ¸®ÅÏ
int GetTop ()
{
return top;
} // ½ºÅÃÀÇ top index¸¦ ¸®ÅÏ, ½ºÅÃÀÇ Å©±â
};
template < class KeyType > Stack < KeyType >::Stack (int MaxStackSize):MaxSize
(MaxStackSize)
{
stack = new KeyType[MaxSize];
top = -1;
}
template < class KeyType > Stack < KeyType >::~Stack ()
{
delete stack;
}
template < class KeyType > Boolean Stack < KeyType >::IsFull ()
{
if (top == MaxSize - 1)
return TRUE;
else
return FALSE;
}
template < class KeyType > Boolean Stack < KeyType >::IsEmpty ()
{
if (top == -1)
return TRUE;
else
return FALSE;
}
template < class KeyType > void Stack < KeyType >::Add (const KeyType & x)
{
if (IsFull ())
return;
else
stack[++top] = x;
}
template < class KeyType > KeyType * Stack < KeyType >::Delete (KeyType & x)
{
if (IsEmpty ())
return 0;
x = stack[top--];
return &x;
}
template < class KeyType >
KeyType * Stack < KeyType >::GetStackTop (KeyType & x)
{
if (IsEmpty ())
return 0;
x = stack[top];
return &x;
}
1.3 °è»ê±â ÇÁ·Î±×·¥ 11.3.1 calc1.cpp// ¼ö½ÄÀ» ÀÔ·Â¹Þ¾Æ postfix·Î ¹Ù²Û ´ÙÀ½ °è»êÇÏ´Â ÇÁ·Î±×·¥
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "stack.h" // ½ºÅà Ŭ·¡½º¸¦ include
// ¼ö½ÄÀ» °è»êÇϴ Ŭ·¡½º CalcÀÇ Á¤ÀÇ
class Calc
{
private:
int Position; // NewTokenÇÔ¼ö¿¡¼ ÇöÀçÀÇ ¹è¿À妽º¸¦ ³ªÅ¸³»´Â º¯¼ö
double Result; // ÃÖÁ¾°á°ú¸¦ ÀúÀåÇϱâ À§ÇÑ º¯¼ö
char *CurrentString; // ÇöÀç ÀÛ¾÷ÇÒ ¹è¿À» °¡¸®Å°´Â Æ÷ÀÎÅÍ
char *PostfixString; // ¼ö½ÄÀ» posifix ÇüÅ·Π¹Ù²ã ÀúÀåÇϱâ À§ÇÑ ¹è¿
char *InfixString; // ¼ö½ÄÀ» infix ÇüÅ·ΠÀÔ·Â¹Þ¾Æ ÀúÀåÇϱâ À§ÇÑ ¹è¿
public:
Calc (); // °´Ã¼»ý¼ºÀÚ
~Calc (); // °´Ã¼ÆÄ±«ÀÚ
void InitValue (); // °è¼ÓÀûÀÎ ½ÇÇàÀ» À§ÇØ º¯¼öµéÀÇ ÃʱⰪÀ» ÁÖ´Â ÇÔ¼ö
int Isp (char op); // ¿¬»êÀÚ¿¡ ´ëÇÑ isp°ªÀ» ³Ñ°ÜÁÖ´Â ÇÔ¼ö
int Icp (char op); // ¿¬»êÀÚ¿¡ ´ëÇÑ icp°ªÀ» ³Ñ°ÜÁÖ´Â ÇÔ¼ö
char *NewToken (); // ÅäÅ«À» ³Ñ°ÜÁÖ´Â ÇÔ¼ö
void Infix (); // ¼ö½ÄÀ» infix ÇüÅ·ΠÀоîµéÀÌ´Â ÇÔ¼ö
void Postfix (); // ¼ö½ÄÀ» postfix ÇüÅ·Π¹Ù²Ù´Â ÇÔ¼ö
void Eval (); // postfix ÇüÅÂÀÇ ¼ö½ÄÀ» °è»êÇÏ´Â ÇÔ¼ö
};
// °´Ã¼»ý¼ºÀÚ
Calc::Calc ()
{
InfixString = new char[DefaultSize]; // µ¿ÀûÀ¸·Î ¸Þ¸ð¸®¸¦ ÇÒ´ç
PostfixString = new char[DefaultSize];
InitValue (); // º¯¼öµéÀ» ÃʱⰪÇϱâ À§ÇØ ÇÔ¼ö È£Ãâ
}
// °´Ã¼ÆÄ±«ÀÚ
Calc::~Calc ()
{
delete InfixString; // µ¿ÀûÀ¸·Î ÇÒ´çÇß´ø ¸Þ·Î¸®¸¦ ÇØÁ¦
delete PostfixString;
}
// º¯¼ö ÃʱâÈ ÇÔ¼ö
void
Calc::InitValue ()
{
Position = 0;
Result = 0.0;
CurrentString = InfixString;
for (int i = 0; i < DefaultSize; i++)
PostfixString[i] = InfixString[i] = ' ';
}
// ¿¬»êÀÚ¿¡ ´ëÇÑ isp°ªÀ» ³Ñ°ÜÁÖ´Â ÇÔ¼ö
int
Calc::Isp (char op)
{
switch (op) {
case '#':
return 0;
case '(':
return 0;
case ')':
return 19;
case '+':
return 12;
case '-':
return 12;
case '*':
return 13;
case '/':
return 13;
}
}
// ¿¬»êÀÚ¿¡ ´ëÇÑ icp°ªÀ» ³Ñ°ÜÁÖ´Â ÇÔ¼ö
int
Calc::Icp (char op)
{
switch (op) {
case '#':
return 0;
case '(':
return 20;
case ')':
return 19;
case '+':
return 12;
case '-':
return 12;
case '*':
return 13;
case '/':
return 13;
}
}
// ÅäÅ«À» ³Ñ°ÜÁÖ´Â ÇÔ¼ö
char *
Calc::NewToken ()
{
int i;
int j;
char temp[DefaultSize];
for (i = 0; i < DefaultSize; i++)
temp[i] = ' ';
while ((CurrentString[Position] == ' ') || // °ø¹éÀ̳ª ÅÇÀº ¹«½ÃÇÏ°í ³Ñ¾î°¨
(CurrentString[Position] == '\t'))
Position++;
i = Position; // °ø¹éÀ̳ª ÅÇÀÌ ¾Æ´Ñ »õ·Î¿î À§Ä¡¿¡¼ ÀÛ¾÷ ½ÃÀÛ
switch ((CurrentString[i])) { // ÇϳªÀÇ ¹®ÀÚ¿¡ ´ëÇÏ¿© ºñ±³ÇÑ ÈÄ ÇØ´ç ÀÛ¾÷ ó¸®
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
while (isdigit (CurrentString[i]))
i++; // ÇÇ¿¬»êÀÚ¸¦ ÀúÀå
if (CurrentString[i] == '.')
i++; // ¼Ò¼öÁ¡ÀÌÇϵµ üũÇÏ¿© ÀúÀå
while (isdigit (CurrentString[i]))
i++;
for (j = 0; j <= i - Position - 1; j++)
temp[j] = CurrentString[Position + j];
temp[j] = '\0';
Position = i;
break;
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
case '#':
temp[0] = CurrentString[Position]; // ÇØ´ç ¿¬»êÀÚ¸¦ ÀúÀå
temp[1] = '\0';
Position++;
break;
}
return strdup (temp); // ÇÇ¿¬»êÀÚ ¶Ç´Â ¿¬»êÀÚ¸¦ ¸®ÅÏ
}
// ¼ö½ÄÀ» infix ÇüÅ·ΠÀоîµéÀÌ´Â ÇÔ¼ö
void
Calc::Infix ()
{
cout << "\n\nEnter the INFIX expression: ";
cin.getline (CurrentString, 80, '\n');
strcat (CurrentString, "#"); // ¼ö½ÄÀÇ ³¡À» ³ªÅ¸³»´Â '#'¸¦ ¼ö½ÄÀÇ ¸¶Áö¸·¿¡ ÀúÀå
}
// ¼ö½ÄÀ» postfix ÇüÅ·Π¹Ù²Ù´Â ÇÔ¼ö
void
Calc::Postfix ()
{
Stack < char >stack; // ¿¬»êÀÚ¸¦ ÀúÀåÇϱâ À§ÇÑ Å¬·¡½º StackÇüÀÇ °´Ã¼ stackÀÇ Á¤ÀÇ
char temp[DefaultSize], y, *x;
double value;
int j, k = 0;
stack.Add ('#'); // ¼ö½ÄÀÇ ³¡À» ³ªÅ¸³»´Â '#'À» ½ºÅÿ¡ ÀúÀå
while (1) {
for (int i = 0; i < DefaultSize; i++)
temp[i] = ' ';
x = NewToken ();
strcpy (temp, x);
if (temp[0] == '#')
break;
value = atof (temp); // doubleÇüÀÇ °ªÀ¸·Î º¯È¯
if (value != 0) { // doubleÇüÀÇ °ªÀ̸é 0ÀÌ ¾Æ´Ñ °ªÀ» ¹Ýȯ, 0ÀÌ¸é ¿¬»êÀÚ
// cout << z << ' '; // ÇÇ¿¬»êÀÚÀ̸é PostfixStirng¿¡ ÀúÀå
for (j = 0; j < strlen (temp); j++)
PostfixString[k++] = temp[j];
PostfixString[k++] = ' ';
}
// ')'ÀÌ ³ª¿À¸é '('°¡ ³ª¿Ã¶§ ±îÁö ½ºÅÿ¡¼ ¿¬»êÀÚ¸¦ popÇÑ´Ù.
else if (temp[0] == ')')
while (1) {
y = *stack.Delete (y);
// cout << y << ' ';
if (y == '(')
break;
// popÇÑ ¿¬»êÀÚ¸¦ Â÷·Ê·Î PostfixStirng¿¡ ÀúÀå
PostfixString[k++] = y;
PostfixString[k++] = ' ';
}
else {
while (1) {
y = *stack.Delete (y);
// isp >= icp : push, isp < icp : pop
if (Isp (y) < Icp (temp[0]))
break;
// cout << y << ' ';
PostfixString[k++] = y;
PostfixString[k++] = ' ';
}
stack.Add (y);
stack.Add (temp[0]);
}
}
while (!stack.IsEmpty ()) {
y = *stack.Delete (y);
// cout << y << ' ';
PostfixString[k++] = y;
PostfixString[k++] = ' ';
}
PostfixString[--k] = '\0'; // ¸¶Áö¸·¿¡ ²À ¹®ÀÚ¿ÀÇ ³¡À» ³ªÅ¸³»´Â ³Î¹®ÀÚ¸¦ ³Ö¾î¾ßÇÑ´Ù.
cout << "Postfix : " << PostfixString << endl; // postfixÇüÅÂÀÇ ¼ö½ÄÀ» Ãâ·Â
}
// postfix ÇüÅÂÀÇ ¼ö½ÄÀ» °è»êÇÏ´Â ÇÔ¼ö
void
Calc::Eval ()
{
Stack < double >stack; // double ÇüÀÇ °ªÀ» ÀúÀåÇÒ ¼ö ÀÖ´Â StackÇüÀÇ °´Ã¼ stackÀÇ Á¤ÀÇ
char temp[DefaultSize], *x;
double value, operand1, operand2, result;
Position = 0; // NextTokenÇÔ¼ö¿¡¼´Â À妽º Position°ú Æ÷ÀÎÅÍ CurrentString¸¦
CurrentString = PostfixString; // »ç¿ëÇϹǷΠ¼ö½ÄÀ» °è»êÇÒ ¶§ ¿Ã¹Ù¸£°Ô ÁöÁ¤ÇØ¾ß ÇÑ´Ù.
// cout << endl << CurrentString << endl;
while (1) {
for (int i = 0; i < DefaultSize; i++)
temp[i] = ' '; // temp ¹è¿ÀÇ ÃʱâÈ
x = NewToken (); // ´ÙÀ½ ÅäÅ«À» ÀоîµéÀδÙ.
strcpy (temp, x);
if (temp[0] == '#')
break; // ÀоîµéÀÎ ÅäÅ«ÀÌ '#'ÀÌ¸é ¿¬»êÀ» Á¾·á
value = atof (temp);
if (value != 0)
stack.Add (value); // ÇÇ¿¬»êÀÚ¸¦ ½ºÅÿ¡ ÀúÀå
else {
stack.Delete (operand2); // ÇÇ¿¬»êÀÚ 1¸¦ ½ºÅÿ¡¼ ²¨³¿
stack.Delete (operand1); // ÇÇ¿¬»êÀÚ 2¸¦ ½ºÅÿ¡¼ ²¨³¿
switch (temp[0]) // ÇØ´çÇÏ´Â ¿¬»êÀ» ¼öÇà
{
case '+':
result = operand1 + operand2;
break;
case '-':
result = operand1 - operand2;
break;
case '*':
result = operand1 * operand2;
break;
case '/':
result = operand1 / operand2;
break;
}
// cout << operand1 << '+' << operand2 << '=' << result << endl;
stack.Add (result); // °è»êÇÑ °á°ú¸¦ ´Ù½Ã ÀúÀå
}
}
stack.Delete (Result); // ÃÖÁ¾°á°ú¸¦ Result¿¡ ÀúÀå
cout << "= " << Result; // ÃÖÁ¾°á°ú¸¦ Ãâ·Â
}
// ¸ÞÀÎÇÔ¼ö
int
main (int argc, char *argv[])
{
Calc c; // Ŭ·¡½º CalcÀÇ °´Ã¼ cÀÇ Á¤ÀÇ
do { // do-while¹®À» ÀÌ¿ëÇÏ¿© °è¼Ó ¹Ýº¹ÇÑ´Ù.
c.InitValue (); // °è¼ÓÀûÀÎ ¼ö½Ä °è»êÀ» À§ÇØ º¯¼ö°ªÀ» ÃʱâÈ ÇÑ´Ù.
c.Infix (); // ¼ö½ÄÀ» ÀоîµéÀδÙ.
c.Postfix (); // ÀоîµéÀÎ ¼ö½ÄÀ» postfix ÇüÅ·Π¹Ù²Û´Ù.
c.Eval (); // postfix ÇüÅ·Π¹Ù²Û ¼ö½ÄÀ» °è»êÇÑ´Ù.
cout << "\n(C)ontinue, (E)nd?"; // °è¼ÓÇÒ °ÍÀΰ¡¸¦ ¹¯´Â ¸Þ½ÃÁö¸¦ Ãâ·Â
} while (toupper (getchar ()) != 'E' && getchar () == 10); // ´©¸¥ ۰¡ E, eÀ̸é ÇÁ·Î±×·¥ Á¾·á
return 0;
}
1.3.2 ÄÄÆÄÀÏ[mwyun@iokorea calc]$ make calc1 g++ -c -g -Wno-deprecated calc1.cpp g++ -o calc1 calc1.o -lstdc++ [mwyun@iokorea calc]$ 1.3.3 calc1 ½ÇÇà[mwyun@iokorea calc]$ ./calc1 Enter the INFIX expression: 10-(4/2)+3 Postfix : 10 4 2 / - 3 + # = 11 (C)ontinue, (E)nd?c Enter the INFIX expression: 10/(4-2)+3 Postfix : 10 4 2 - / 3 + # = 8 (C)ontinue, (E)nd?c Enter the INFIX expression: 10-4 Postfix : 10 4 - # = 6 (C)ontinue, (E)nd?e [mwyun@iokorea calc]$ 1.4 °è»ê±â ÇÁ·Î±×·¥ 21.4.1 calc2.cpp#include <iostream.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define max 100
#define null 0
#define underflow -1
int top = -1;
template < class T > void
push (T * stack, T item)
{
top++;
if (top > max) {
cout << "\nStack overflow\n";
exit (-1);
}
stack[top] = item;
}
template < class T > T pop (T * stack)
{
if (top < 0)
return underflow;
return stack[top--];
}
int
sunwi (int yunsanja)
{
switch (yunsanja) {
case '(':
return 0;
case ')':
return 0;
case '+':
return 1;
case '-':
return 1;
case '*':
return 2;
case '/':
return 2;
case '%':
return 2;
default:
return 3;
}
}
void
postfix (char *postsusik, char *susik)
{
char stack[max] = { ' ', };
while (*susik != '\0') {
if (*susik == '(')
push (stack, *susik++);
else if (*susik == ')') {
while (stack[top] != '(') {
*postsusik++ = pop (stack);
*postsusik++ = ' ';
}
pop (stack);
susik++;
}
else if (strchr ("+ - * / %", *susik) != NULL) {
while (top >= 0 && sunwi (stack[top]) >= sunwi (*susik)) {
*postsusik++ = pop (stack);
*postsusik++ = ' ';
}
push (stack, *susik++);
}
else if (isalnum (*susik)) {
do {
*postsusik++ = *susik++;
}
while (isalnum (*susik));
*postsusik++ = ' ';
}
else
susik++;
}
while (top >= 0) {
*postsusik++ = pop (stack);
*postsusik++ = ' ';
}
postsusik--;
*postsusik = null;
}
int
eval (char *postfix)
{
int integer[max] = { 0, }, v, op1, op2, r;
char string[max];
top = -1;
while (*postfix != '\0') {
if (*postfix == ' ') {
*postfix++;
continue;
}
else if (isdigit (*postfix)) {
int j = 0;
while (isdigit (*postfix))
string[j++] = *postfix++;
string[j] = '\0';
v = atoi (string);
push (integer, v);
}
else {
op2 = pop (integer);
op1 = pop (integer);
switch (*postfix) {
case '+':
r = op1 + op2;
break;
case '-':
r = op1 - op2;
break;
case '*':
r = op1 * op2;
break;
case '/':
r = op1 / op2;
break;
case '%':
r = op1 % op2;
break;
}
push (integer, r);
}
*postfix++;
}
r = pop (integer);
return r;
}
int
main (int argc, char *argv[])
{
int i;
char postsusik[max];
char susik[max];
cout << "Infix => ";
cin >> susik;
postfix (postsusik, susik);
cout << "Postfix => ";
for (i = 0; i < strlen (postsusik); i++)
cout << postsusik[i];
cout << endl << "= " << eval (postsusik) << endl;
return 0;
}
1.4.2 ÄÄÆÄÀÏ[mwyun@iokorea calc]$ make calc2 g++ -c -g -Wno-deprecated calc2.cpp g++ -o calc2 calc2.o -lstdc++ [mwyun@iokorea calc]$ 1.4.3 calc2 ½ÇÇà[mwyun@iokorea calc]$ ./calc2 Infix => 10-(4/2)+3 Postfix => 10 4 2 / - 3 + = 11 [mwyun@iokorea calc]$ ./calc2 Infix => 10/(4-2)+3 Postfix => 10 4 2 - / 3 + = 8 [mwyun@iokorea calc]$ ./calc2 Infix => 10-4 Postfix => 10 4 - = 6 [mwyun@iokorea calc]$ 1.5 °è»ê±â ÇÁ·Î±×·¥ 3
ÇÑÀÚ¸® ¼ýÀÚ¸¸ »çÄ¢ ¿¬»êÀÌ °¡´ÉÇÑ °è»ê±â ÇÁ·Î±×·¥ÀÌ´Ù.
¿¹) 8-(4/2)+3
1.5.1 calc3.cpp#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "stack.h"
const int MAX_STACK_SIZE = 100;
const int MAX_EXPR_SIZE = 100;
// ( ) + - * / % #
//static int isp[] = { 0, 19, 12, 12, 13, 13, 13, 0};
//static int icp[] = {20, 19, 12, 12, 13, 13, 13, 0};
typedef enum
{ lparen, rparen, plus, minus, times, divide,
mod, eos, operand
} precedence;
class calc
{
private:
char expr[MAX_EXPR_SIZE];
char postfix_expr[MAX_EXPR_SIZE];
char *pointer;
public:
calc ();
int Isp (precedence token);
int Icp (precedence token);
void expression_input (void);
char print_token (precedence token);
precedence get_token (char &symbol, int &n);
void postfix (void);
int eval (void);
};
calc::calc ()
{
pointer = expr;
for (int i = 0; i < MAX_EXPR_SIZE; i++)
expr[i] = postfix_expr[i] = ' ';
}
int
calc::Isp (precedence token)
{
switch (token) {
case lparen:
return 0;
case rparen:
return 19;
case plus:
return 12;
case minus:
return 12;
case times:
return 13;
case divide:
return 13;
case mod:
return 13;
case eos:
return 0;
}
}
int
calc::Icp (precedence token)
{
switch (token) {
case lparen:
return 20;
case rparen:
return 19;
case plus:
return 12;
case minus:
return 12;
case times:
return 13;
case divide:
return 13;
case mod:
return 13;
case eos:
return 0;
}
}
void
calc::expression_input (void)
{
/*
int i = 0, x;
while (i < MAX_EXPR_SIZE) {
x = cin.get();
if (x != ' ' || x != '\t') expr[i++] = x;
}
expr[i] = '\0';
*/
cin >> expr;
strcat (expr, "#");
// cout << expr << endl;
}
precedence calc::get_token (char &symbol, int &n)
{
symbol = pointer[n++];
switch (symbol) {
case '(':
return lparen;
case ')':
return rparen;
case '+':
return plus;
case '-':
return minus;
case '*':
return times;
case '/':
return divide;
case '%':
return mod;
case '#':
return eos;
default:
return operand;
}
}
char
calc::print_token (precedence token)
{
char c;
switch (token) {
case lparen:
c = '(';
break;
case rparen:
c = ')';
break;
case plus:
c = '+';
break;
case minus:
c = '-';
break;
case times:
c = '*';
break;
case divide:
c = '/';
break;
case mod:
c = '%';
break;
case eos:
c = '#';
break;
}
// cout << c << ' ';
return c;
}
void
calc::postfix (void)
{
Stack < precedence > stack;
precedence token, y;
char symbol = ' ';
int i = 0, n = 0;
stack.Add (eos);
for (token = get_token (symbol, n); token != eos;
token = get_token (symbol, n)) {
if (token == operand) {
postfix_expr[i++] = symbol;
}
else if (token == rparen)
for (y = *stack.Delete (y); y != lparen; y = *stack.Delete (y))
postfix_expr[i++] = print_token (y);
else {
for (y = *stack.Delete (y); Isp (y) >= Icp (token);
y = *stack.Delete (y))
postfix_expr[i++] = print_token (y);
stack.Add (y);
stack.Add (token);
}
}
while (!stack.IsEmpty ())
postfix_expr[i++] = print_token (*stack.Delete (y));
postfix_expr[i] = '\0';
cout << "Postfix : " << postfix_expr << endl;
}
int
calc::eval (void)
{
Stack < int >stack;
precedence token;
char symbol = ' ';
int op1, op2;
int n = 0;
pointer = postfix_expr;
token = get_token (symbol, n);
while (token != eos) {
if (token == operand)
stack.Add (symbol - '0');
else {
stack.Delete (op2);
stack.Delete (op1);
switch (token) {
case plus:
stack.Add (op1 + op2);
break;
case minus:
stack.Add (op1 - op2);
break;
case times:
stack.Add (op1 * op2);
break;
case divide:
stack.Add (op1 / op2);
break;
case mod:
stack.Add (op1 % op2);
break;
} // end of switch
} // end of if-else
token = get_token (symbol, n);
} // end of while
return *stack.Delete (op1);
}
int
main (int argc, char *argv[])
{
calc a;
a.expression_input ();
a.postfix ();
cout << "= " << a.eval () << endl;
return 0;
}
1.5.2 ÄÄÆÄÀÏ[mwyun@iokorea calc]$ make calc3 g++ -c -g -Wno-deprecated calc3.cpp g++ -o calc3 calc3.o -lstdc++ [mwyun@iokorea calc]$ 1.5.3 calc3 ½ÇÇà[mwyun@iokorea calc]$ ./calc3 8-(4/2)+3 Postfix : 842/-3+# = 9 [mwyun@iokorea calc]$ 1.6 °è»ê±â ÇÁ·Î±×·¥ 41.6.1 calc4.cpp#include<iostream.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#include"stack.h"
#define max 100
#define null 0
#define underflow -1
char
order (int Operator)
{
switch (Operator) {
case '(':
return 0;
case ')':
return 0;
case '+':
return 1;
case '-':
return 1;
case '*':
return 2;
case '/':
return 2;
default:
return 3;
}
}
void
Postfix (char postfix[], char *infix)
{
Stack < char >stack;
char x, y;
int i = 0;
while (*infix != '\0') {
if (*infix == '(')
stack.Add (*infix++);
else if (*infix == ')') {
while ((y = *stack.GetStackTop (y)) != '(') {
stack.Delete (x);
postfix[i++] = x;
postfix[i++] = ' ';
}
stack.Delete (x);
infix++;
}
else if (strchr ("+ - * /", *infix) != NULL) {
while (stack.GetTop () >= 0 &
order ((y = *stack.GetStackTop (y))) >= order (*infix)) {
stack.Delete (x);
postfix[i++] = x;
postfix[i++] = ' ';
}
stack.Add (*infix++);
}
else if (isalnum (*infix)) {
while (isalnum (*infix))
postfix[i++] = *infix++;
if (*infix == '.')
postfix[i++] = *infix++;
while (isalnum (*infix))
postfix[i++] = *infix++;
postfix[i++] = ' ';
}
else
infix++;
}
while (stack.GetTop () >= 0) {
stack.Delete (x);
postfix[i++] = x;
postfix[i++] = ' ';
}
postfix[i--] = '\0';
}
float
eval (char *postfix)
{
Stack < float >stack;
char string[max];
float integer, result, op1, op2;
int i;
for (i = 0; i <= strlen (postfix); i++) {
int j = 0;
if (isdigit (postfix[i])) // 0 to 9
{
while (isdigit (postfix[i]) || postfix[i] == '.')
string[j++] = postfix[i++];
string[j] = '\0';
integer = atof (string);
stack.Add (integer);
}
else if (postfix[i] == ' ')
continue;
else {
stack.Delete (op2);
stack.Delete (op1);
switch (postfix[i]) {
case '+':
result = op1 + op2;
break;
case '-':
result = op1 - op2;
break;
case '*':
result = op1 * op2;
break;
case '/':
result = op1 / op2;
break;
}
stack.Add (result);
// cout << endl << op1 << postfix[i] << op2 << '=' << result << endl;
}
}
result = *stack.Delete (result);
return result;
}
int
main (int argc, char *argv[])
{
int i;
char postfix[max];
char infix[max];
cout << "\n *** Infix to Postfix ***\n";
cout << "\n # Infix : ";
cin >> infix;
Postfix (postfix, infix);
cout << " # Postfix : ";
for (i = 0; i < strlen (postfix); i++)
cout << postfix[i];
cout << "\n\n # Result :";
for (i = 0; i < strlen (infix); i++)
cout << infix[i];
cout << endl << "= " << eval (postfix) << endl;
}
1.6.2 ÄÄÆÄÀÏ[mwyun@iokorea calc]$ make calc4 g++ -c -g -Wno-deprecated calc4.cpp g++ -o calc4 calc4.o -lstdc++ 1.6.3 calc4 ½ÇÇà[mwyun@iokorea calc]$ ./calc4 *** Infix to Postfix *** # Infix : 10-(4/2)+3 # Postfix : 10 4 2 / - 3 + # Result :10-(4/2)+3 = 11 [mwyun@iokorea calc]$ ./calc4 *** Infix to Postfix *** # Infix : 10/(4-2)+3 # Postfix : 10 4 2 - / 3 + # Result :10/(4-2)+3 = 8 [mwyun@iokorea calc]$ ./calc4 *** Infix to Postfix *** # Infix : 10-4 # Postfix : 10 4 - # Result :10-4 = 6 [mwyun@iokorea calc]$ 1.7 °è»ê±â ÇÁ·Î±×·¥ 5
calc1.cppÀÇ °è»ê±â ¾Ë°í¸®Áò ¼Ò½º¸¦ ÂüÁ¶Çϰí list¿Í statck ÀڷᱸÁ¶¸¦ ÀÌ¿ëÇÏ¿© Á»´õ º¹ÀâÇÑ ÇüÅÂÀÇ °è»ê±â¸¦ ¸¸µé¾î º¸¾Ò´Ù. 1.7.1 calc5.c#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"
#include "stack.h"
#define MAX 100 // ¼ö½Ä ¹®ÀÚ¿ ÀúÀå ÃÖ´ë Å©±â
// node ŸÀÔ Á¤ÀÇ
typedef struct {
int select; // 0: int, operator, 1: float
double value;
char op;
} node;
int isp(char op)
{
switch (op)
{
case '#': return 0;
case '(': return 0;
case ')': return 19;
case '+': return 12;
case '-': return 12;
case '*': return 13;
case '/': return 13;
}
}
int icp(char op)
{
switch (op)
{
case '#': return 0;
case '(': return 20;
case ')': return 19;
case '+': return 12;
case '-': return 12;
case '*': return 13;
case '/': return 13;
}
}
// ½Ç¼ö°ªÀΰ¡ °Ë»ç
int is_float(char *buf)
{
int i;
for (i = 0; buf[i] != '\0'; i++)
if (buf[i] == '.') // dot(.)ÀÌ ÀÖÀ¸¸é
return i; // À妽º ¸®ÅÏ
return -1;
}
// Á¤¼öºÎ ÇÕ»ê
// ¿¹) 123.45À̸é Á¤¼öºÎ°¡ 3ÀÚ¸®À̹ǷΠ3¹ø 10À» °öÇÏ¿©(10*3) 100À» ¸®ÅÏ
double get_ten(int dot_index)
{
int i;
double value = 1;
for (i = 0; i < dot_index; i++)
value *= 10;
return value;
}
// ¼Ò¼öºÎ ÇÕ»ê
// ¿¹) 123.45ÀÌ¸é ¼Ò¼öºÎ°¡ 2ÀÚ¸®À̹ǷΠ2¹ø 0.1À» °öÇÏ¿© 0.01À» ¸®ÅÏ
double get_decimal(int dot_index)
{
int i;
double value = 0.1;
for(i = 0; i < dot_index; i++)
value *= 0.1;
return value;
}
// node Ãß°¡
int add_node(List *list, int select, double value, char op)
{
node *p;
// ¸Þ¸ð¸® ÇÒ´ç
if ((p = (node *)malloc(sizeof(node))) == NULL)
return 0;
p->select = select; // °ª ¶Ç´Â ¿¬»êÀÚ ¼±ÅÃ
p->value = value; // °ª=ÇÇ¿¬»êÀÚ(operand)
p->op = op; // ¿¬»êÀÚ(operator)
#ifdef __DEBUG__
printf("p->select = %d\t", p->select);
printf("p->value = %lf\t", p->value);
printf("p->op = %c\n", p->op);
#endif
// list¿¡ ÀúÀå
if (list_ins_next(list, list_tail(list), p) != 0)
return 0;
return 1;
}
// ÇÇ¿¬»êÀÚ list¿¡ Ãß°¡
void print_operand(List *list, char *buf, int i)
{
double sum1, sum2, real;
int dot_index;
int digit;
int sum;
int k;
// ½Ç¼öÀΰ¡ °Ë»ç
dot_index = is_float(buf);
if (dot_index > -1) // float value
{
// Á¤¼öºÎ °è»ê(¹®ÀÚ¿À» ¼ýÀÚ·Î º¯È¯)
sum1 = 0.0;
for (k = 0; k < dot_index; k++)
{
digit = buf[k] - '0';
sum1 = sum1 + (digit * get_ten(dot_index-k-1));
}
// ¼Ò¼öºÎ °è»ê(¹®ÀÚ¿À» ¼ýÀÚ·Î º¯È¯)
sum2 = 0.0;
for(k = dot_index + 1; k < i; k++)
{
digit = buf[k] - '0';
sum2 = sum2 + (digit * get_decimal(k-dot_index-1));
}
// Á¤¼öºÎ¿Í ¼Ò¼öºÎ ÇÕ»ê
real = sum1 + sum2;
// list¿¡ float value Ãß°¡
if (!add_node(list, 1, real, '\0'))
return;
#ifdef __DEBUG__
printf("%f", real);
#endif
}
else // integer value
{
// Á¤¼ö °è»ê
sum = 0;
for (k = 0; k < i; k++)
{
digit = buf[k] - '0';
sum = sum + (digit * get_ten(i-k-1));
}
// list¿¡ integer value Ãß°¡
if (!add_node(list, 1, sum, '\0'))
return;
#ifdef __DEBUG__
printf("%d", sum);
#endif
}
}
// infix ¹æ½ÄÀ¸·Î ¼ö½Ä ÀÔ·Â
int get_expr(List *list) // --> infix input
{
int i, j, ch;
char buf[MAX];
i = 0;
for (j = 0; j < MAX; j++) // ÃʱâÈ
buf[j] = '\0';
while((ch = getchar()) != '\n') // EnterÄ¥ ¶§±îÁö ÇÑ ¹®ÀÚ¾¿ ÀÔ·Â
{
if (('0' <= ch && ch <= '9') || (ch == '.'))
buf[i++] = ch; // ÇÇ¿¬»êÀÚ: ¼ýÀÚ(0~9)°Å³ª dot(.)À̸é buf¿¡ ÀúÀå
else // ¿¬»êÀÚ: '+', '-', '*', '/'
{
if (i != 0) // buf¿¡ ÀÔ·ÂÇÑ ¹®ÀÚµéÀÌ ÀÖÀ¸¸é
{
print_operand(list, buf, i); // list¿¡ buf Ãß°¡: ÇÇ¿¬»êÀÚ
i = 0;
for (j = 0; j < MAX; j++) // ÃʱâÈ
buf[j]='\0';
}
if (!add_node(list, 0, 0, ch)) // list¿¡ operator Ãß°¡
return 0;
#ifdef __DEBUG__
printf(" %c ", ch);
#endif
}
}
// buf¿¡ ÀÔ·ÂÇÑ ¹®ÀÚµéÀÌ ÀÖÀ¸¸é
if (strlen(buf) > 0)
{
print_operand(list, buf, i); // list¿¡ buf Ãß°¡: ÇÇ¿¬»êÀÚ
}
return 1;
}
// statck Ãâ·Â
void print_stack(const Stack *stack, int select)
{
ListElmt *element;
int size, i;
fprintf(stdout, "print_stack: Stack size is %d\n", size = stack_size(stack));
i = 0;
element = list_head(stack);
while (i < size)
{
if (select) // ÇÇ¿¬»êÀÚ(°ª) Ãâ·Â
{
double *data = list_data(element);
printf("val = stack[%03d] = %lf\n", i, *data);
}
else // ¿¬»êÀÚ Ãâ·Â
{
char *data = list_data(element);
printf("op = stack[%03d] = %c\n", i, *data);
}
element = list_next(element);
i++;
}
printf("\n\n");
}
// list Ãâ·Â
void print_list(const List *list)
{
int i;
ListElmt *element;
node *data;
#ifdef __DEBUG__
printf("list size = %d\n", list_size(list));
#endif
i = 0;
element = list_head(list);
while (1)
{
data = list_data(element);
#ifdef __DEBUG__
printf("%d :\t", i++);
printf("data->select = %d\t", data->select);
printf("data->value = %lf\t", data->value);
printf("data->op = %c\n", data->op);
#endif
if (data->select)
printf("%lf ", data->value);
else
printf("%c ", data->op);
if (list_is_tail(element)) // listÀÇ tailÀ̸é break
break;
else // ±×·¸Áö ¾ÊÀ¸¸é
element = list_next(element); // ´ÙÀ½ element·Î À̵¿
}
printf("\n");
}
// infix¹æ½ÄÀÇ ¼ö½ÄÀ» postfix¹æ½ÄÀ¸·Î º¯°æ
int infix_to_postfix(List *ie_list, List *pe_list)
{
Stack opstack;
ListElmt *element;
node *data;
node *p;
char *op;
element = list_head(ie_list);
stack_init(&opstack, free);
if ((op = (char *)malloc(sizeof(char))) == NULL)
return 0;
*op = '#';
if (stack_push(&opstack, op) != 0)
return 0;
while (1)
{
data = list_data(element);
switch (data->select)
{
case 0: // operator
{
if ((op = (char *)malloc(sizeof(char))) == NULL)
return 0;
*op = -1;
if (data->op == ')')
{
// operator => statck pop
while (stack_pop(&opstack, (void **)&op) == 0) // success
{
if (*op == '(') // not operation
{
free(op);
break;
}
else
{
if ((p = (node *)malloc(sizeof(node))) == NULL)
return 0;
p->select = 0;
p->value = 0;
p->op = *op;
#ifdef __DEBUG__
printf("[2] p->select = %d\t", p->select);
printf("p->value = %lf\t", p->value);
printf("p->op = %c\n", p->op);
#endif
if (list_ins_next(pe_list, list_tail(pe_list), p) != 0)
return 0;
}
}
}
else
{
// operator => statck pop
while (stack_pop(&opstack, (void **)&op) == 0) // success
{
#ifdef __DEBUG__
printf("stack_pop: %c\n", *op);
#endif
if (isp(*op) < icp(data->op))
break;
if ((p = (node *)malloc(sizeof(node))) == NULL)
return 0;
p->select = 0; // operator
p->value = 0;
p->op = *op;
if (list_ins_next(pe_list, list_tail(pe_list), p) != 0)
return 0;
}
#ifdef __DEBUG__
printf("1. op=%c,%x\n", *op, *op);
printf("2. op=%x\n", *op);
#endif
// operator => stack push
if (stack_push(&opstack, op) != 0)
return 0;
#ifdef __DEBUG__
printf("data->op=%c\n", data->op);
#endif
if ((op = (char *)malloc(sizeof(char))) == NULL)
return 0;
*op = data->op;
// operator => stack push
if (stack_push(&opstack, op) != 0) // stack push
return 0;
}
break;
}
case 1: // int, value value
{
if ((p = (node *)malloc(sizeof(node))) == NULL)
return 0;
p->select = data->select;
p->value = data->value;
p->op = data->op;
#ifdef __DEBUG__
printf("[3] p->select = %d\t", p->select);
printf("p->value = %lf\t", p->value);
printf("p->op = %c\n", p->op);
#endif
if (list_ins_next(pe_list, list_tail(pe_list), p) != 0)
return 0;
break;
}
default:
{
printf("Wrong Input!\n"); // ÀÔ·ÂÇÑ ¼ö½ÄÀÌ Æ²¸° °æ¿ì
break;
}
}
if (list_is_tail(element)) // listÀÇ tailÀ̸é break
break;
else // ±×·¸Áö ¾ÊÀ¸¸é
element = list_next(element); // ´ÙÀ½ element·Î À̵¿
#ifdef __DEBUG__
printf("%03d\n", __LINE__);
print_stack(&opstack, 0);
#endif
}
// opstack¿¡ ³²¾ÆÀÖ´Â operator pop => postfix ¼ö½Ä list
if ((op = (char *)malloc(sizeof(char))) == NULL)
return 0;
while (stack_pop(&opstack, (void **)&op) == 0) // success
{
if (*op == '#')
{
free(op);
break;
}
if ((p = (node *)malloc(sizeof(node))) == NULL)
return 0;
p->select = 0;
p->value = 0;
p->op = *op;
#ifdef __DEBUG__
printf("[4] p->select = %d\t", p->select);
printf("p->value = %lf\t", p->value);
printf("p->op = %c\n", p->op);
#endif
if (list_ins_next(pe_list, list_tail(pe_list), p) != 0)
return 0;
}
stack_destroy(&opstack);
return 1;
}
// ¼ö½Ä °è»ê
double calc_expr(List *list)
{
double result;
double *val1;
double *val2;
ListElmt *element;
node *data;
double *db;
Stack valstack;
stack_init(&valstack, free);
element = list_head(list);
while (1)
{
data = list_data(element);
//printf("data->select = %d\tdata->value = %lf\tdata->op = %c\n", data->select, data->value, data->op);
if (data->select) // int, float
{
if ((db = (double *)malloc(sizeof(double))) == NULL)
return 0;
*db = data->value;
#ifdef __DEBUG__
printf("*db = %lf\n", *db);
#endif
if (stack_push(&valstack, db) != 0)
return 0;
#ifdef __DEBUG__
printf("added number\n");
print_stack(&valstack, 1);
#endif
}
else // operator
{
// µÎ°³ÀÇ °ªÀ» statk¿¡¼ pop
if (stack_pop(&valstack, (void **)&val2) != 0) // success
return 0;
if (stack_pop(&valstack, (void **)&val1) != 0) // success
return 0;
// operator¿¡ µû¶ó µÎ°³°ª ¿¬»ê
switch (data->op)
{
case '+':
result = *val1 + *val2;
#ifdef __DEBUG__
printf("%lf + %lf = %lf\n", *val1, *val2, result);
#endif
break;
case '-':
result = *val1 - *val2;
#ifdef __DEBUG__
printf("%lf - %lf = %lf\n", *val1, *val2, result);
#endif
break;
case '*':
result = *val1 * *val2;
#ifdef __DEBUG__
printf("%lf * %lf = %lf\n", *val1, *val2, result);
#endif
break;
case '/':
result = *val1 / *val2;
#ifdef __DEBUG__
printf("%lf / %lf = %lf\n", *val1, *val2, result);
#endif
break;
default:
printf("Wrong Input!\n");
exit(0);
}
free(val1);
free(val2);
// °è»êÇÑ °á°ú¸¦ stack¿¡ ÀúÀå
if ((db = (double *)malloc(sizeof(double))) == NULL)
return 0;
*db = result;
if (stack_push(&valstack, db) != 0)
return 0;
#ifdef __DEBUG__
printf("added result\n");
print_stack(&valstack, 1);
#endif
}
if (list_is_tail(element))
break;
else
element = list_next(element);
}
// ¸ðµç °è»êÀÌ ³¡³ ÈÄ ½ºÅÿ¡ ³²¾ÆÀÖ´Â °ª(ÃÖÁ¾°á°ú°ª)À» pop
if (stack_pop(&valstack, (void **)&db) != 0) // success
return 0;
result = *db;
#ifdef __DEBUG__
printf("result=%lf\n", result);
#endif
stack_destroy(&valstack);
return result;
}
// main ÇÔ¼ö
int main(int argc, char *argv[])
{
List infix_expr_list;
List postfix_expr_list;
// list ÃʱâÈ
list_init(&infix_expr_list, free);
// infix¹æ½ÄÀÇ ¼ö½Ä ÀÔ·Â
get_expr(&infix_expr_list);
printf("infix expr list\n");
print_list(&infix_expr_list);
// list ÃʱâÈ
list_init(&postfix_expr_list, free);
// infix¹æ½ÄÀÇ ¼ö½ÄÀ» postfix¹æ½ÄÀ¸·Î º¯
if (infix_to_postfix(&infix_expr_list, &postfix_expr_list))
{
printf("postfix expr list\n");
print_list(&postfix_expr_list);
// postfix exprÀ» ÀÌ¿ëÇÑ °ª °è»ê
printf("=%lf\n", calc_expr(&postfix_expr_list));
}
// list Á¦°Å
list_destroy(&infix_expr_list);
list_destroy(&postfix_expr_list);
return 0;
}
1.7.2 ÄÄÆÄÀÏ[mwyun@iokorea calc5]$ make clean rm -rf calc5 calc5.o list.o stack.o core [mwyun@iokorea calc5]$ make gcc -c calc5.c ../linkedlist_ex/list.c ../stack/stack.c -I../linkedlist_ex -I../stack gcc -o calc5 calc5.o list.o stack.o [mwyun@iokorea calc5]$ 1.7.3 calc5 ½ÇÇà[mwyun@iokorea calc5]$ ./calc5 10/(4-2)+3 infix expr list 10.000000 / ( 4.000000 - 2.000000 ) + 3.000000 postfix expr list 10.000000 4.000000 2.000000 - / 3.000000 + =8.000000 [mwyun@iokorea calc5]$ ./calc5 10-(4/2)+3-5 infix expr list 10.000000 - ( 4.000000 / 2.000000 ) + 3.000000 - 5.000000 postfix expr list 10.000000 4.000000 2.000000 / - 3.000000 + 5.000000 - =6.000000 [mwyun@iokorea calc5]$ 1.8 °è»ê±â ÇÁ·Î±×·¥ ¿¡·¯Àâ±â 1
´ÙÀ½Àº ¿¡·¯°¡ ¹ß»ýÇÏ´Â °è»ê±â ÇÁ·Î±×·¥ µÎ°¡Áö¸¦ ¼Ò°³ÇÑ´Ù. postfix·Î ¹Ù²Ù´Â °úÁ¤¿¡¼ isp, icp °ªÀ» ÀÌ¿ëÇØ¼ ¿¬»êÀÚ ¿ì¼±¼øÀ§¸¦ ºñ±³ÇÏ¿© ½ºÅÿ¡ °ªÀ» ³Ö°Å³ª postfix ¹®ÀÚ¿¿¡ Æ÷ÇÔ½ÃÄÑ´Â°Ô °ü°ÇÀÌ´Ù. ¿©·¯ºÐµéÀÌ Á÷Á¢ ¹ö±×¸¦ ÀâÀ¸¸é¼ °è»ê±â ÇÁ·Î±×·¥À» ¿Ï¼ºÇر⠹ٶõ´Ù. ¹°·Ð ÀÌ¹Ì ¿Ï¼ºµÈ ¼Ò½º¸¦ ÃÖ´ëÇÑ ÀÌ¿ëÇÏ´Â °Íµµ ÁÁÀº ¹æ¹ýÀÌ´Ù. Çà¿îÀÌ Àֱ⸦...
ù¹øÂ° ¹ö±×ÀÖ´Â ÇÁ·Î±×·¥ 1.8.1 calc_report1.cpp#include <iostream.h>
#include <string.h>
#include <conio.h>
//#include "stack.cpp"
typedef int BOOLEAN;
class Stack {
private:
char *stack;
int isp;
int index;
int top_of_stack;
int STK_SIZ;
char *postfix;
public:
Stack(int stk_siz);
~Stack();
void push (char new_data);
int isempty();
char pop();
char Select_stack(char str,BOOLEAN isp );
void POSTFIX(char str[]);
void print();
void RESult();
};
Stack::Stack(int stk_siz)
{
stack = new char[STK_SIZ = stk_siz];
postfix = new char[80];
top_of_stack = -1;
index = 0;
for(int j=0; j < STK_SIZ; j++)
{ stack[j] = postfix[j]= '\0';}
}
Stack::~Stack()
{
delete []stack;
delete []postfix;
}
int Stack::isempty()
{
if (top_of_stack == -1) return 1;
else return 0;
}
void Stack::print()
{ cout<<"# is ends print";
cout<<"\npostfix output > " << postfix << endl;
}
void Stack::push(char new_data)
{
++top_of_stack;
stack[top_of_stack] = new_data;
}
char Stack::pop()
{
char popped_data;
if (isempty()) return NULL;
popped_data=stack[top_of_stack--];
return popped_data;
}
char Stack::Select_stack(char str,BOOLEAN isp)
{
int icp;
switch(stack[top_of_stack])
{
case '+': case '-':
icp=1;
if(isp<=icp) {
pop();
push(str);
}
else if(isp>icp)
push(str);
break;
case '*': case '/':
icp=2;
if(isp<=icp){
pop();
push(str);
}
else if(isp>icp)
push(str);
break;
default :
push(str);
break;
}
return(top_of_stack);
}
void Stack::POSTFIX(char str[])
{ int i=0;
while(str[i] != '#')
{
switch(str[i])
{
case '+': case '-':
Select_stack(str[i++],isp=1);
break;
case '*': case '/':
Select_stack(str[i++],isp=2);
break;
case '(':
Select_stack(str[i++],isp=10);
break;
case ')':
while(stack[top_of_stack]!='(')
postfix[index++] = pop();
if(stack[top_of_stack]=='(')
pop();
str[i++];
break;
default :
postfix[index++] = str[i++];
break;
}
}
while(!isempty()) postfix[index++] = pop();
strcat(postfix, "#");
}
void Stack::RESult()
{
int op1=0, op2=0, r, j;
for (j = 0; j < STK_SIZ; j++) stack[j] = ' ';
top_of_stack = -1;
j = 0;
while (postfix[j] != '#')
{
if(postfix[j] >= '0' && postfix[j] <= '9')
push(postfix[j]);
else
{
op2 = pop()-'0';
op1 = pop()-'0';
switch(postfix[j])
{
case '+':
r = op1 + op2;
break;
case '-':
r = op1 - op2;
break;
case '*':
r = op1 * op2;
break;
case '/':
r = op1 / op2;
break;
}
cout << op1 << postfix[j] << op2 << '=' << r << endl;
push(r+'0');
}
j++;
}
cout << "\noutput result :> ";
cout << pop();
}
void main()
{ clrscr();
Stack NEW_Stack(40);
static char str[80];
cout<<"infix input >";
cin>>str;
strcat(str, "#");
NEW_Stack.POSTFIX(str);
NEW_Stack.print();
NEW_Stack.RESult();
getch();
}
1.8.2 ÄÄÆÄÀÏ[mwyun@iokorea calc]$ make calc_report1 g++ -c -g -Wno-deprecated calc_report1.cpp g++ -o calc_report1 calc_report1.o -lstdc++ [mwyun@iokorea calc]$ 1.8.3 calc_report1 ½ÇÇà1.9 °è»ê±â ÇÁ·Î±×·¥ ¿¡·¯Àâ±â 2
µÎ¹øÂ° ¹ö±×ÀÖ´Â ÇÁ·Î±×·¥ 1.9.1 calc_report2.cpp#include <stdio.h> #include <conio.h> #include <stdlib.h> #include <ctype.h> /* isdigit()ÇÔ¼ö -> ÀÔ·ÂµÈ ¹®ÀÚ°¡ '0' - '9'Àΰ¡ °Ë»ç */ const int STACKSIZE = 100; const int MAXCOLS = 80; enum Boolean { FALSE = 0, TRUE = 1 }; class stack { private: int top; /* ½ºÅÃÀÇ ÇöÀ§Ä¡ ÁöÁ¤ */ float items[STACKSIZE]; /* float ÇüÀ¸·Î 100°³ÀÇ ¿ä¼Ò È®º¸ */ public: friend class calc; stack() { top = -1; } Boolean empty(); float pop(); void push(char x); int gettop() { return top; } float getitems(int i) { return items[i]; } }; Boolean stack::empty() /* ½ºÅÃÀÌ ºñ¾ú´Â°¡ °Ë»ç */ { if (top == -1) /* ºñ¾úÀ¸¸é Âü(1) ¹Ýȯ */ return (TRUE); else return ( FALSE); /* ¾Æ´Ï¸é °ÅÁþ(0) ¹Ýȯ */ } float stack::pop() /* ½ºÅÃÀÇ ³»¿ë ²¨³¿ */ { /* ºñ¾úÀ¸¸é "Stack Underflow" Ãâ·Â */ if(empty()) { printf("Stack Underflow"); exit(1); /* ¾Æ´Ï¸é ½ºÅà ³»¿ë ¹Ýȯ -> top °¨¼Ò */ } return (items[top--]); } void stack::push(char x) /* ½ºÅÿ¡ ¿ä¼Ò »ðÀÔ */ { if(top == STACKSIZE-1) { /* ½ºÅÃÀÌ ´Ù Â÷ ÀÖÀ¸¸é "Stack Overflow" Ãâ·ÂÈÄ Å»Ãâ */ printf("Stack Overflow"); exit(1); } else /* ¾Æ´Ï¸é top Áõ°¡ÈÄ ¿ä¼Ò »ðÀÔ */ items[++top] = x; } class calc { private: char infix[MAXCOLS]; char postr[MAXCOLS]; int pos; public: calc() { pos = 0; } void getinfix(); void output(); void popandtest(stack& ps, char& px,int& pund); void postfix(); float eval(); float oper(char symb, float op1, float op2); Boolean prcd (char topsymb, char symb); }; void calc::getinfix() { clrscr(); printf("INPUT STRING : "); while((infix[pos++] = getchar()) != '\n'); /* ¼ö½Ä ÀÔ·Â ¹ÞÀ½ */ infix[--pos] = '\0'; /* ¹®ÀÚ¿ÀÇ ³¡¿¡ NULL ÀÔ·Â */ printf("%s%2s", "The Original Infix Expression Is %s", infix); } void calc::output() { printf("\n-------------------------------------------------"); printf("\n symb opnd1 opnd2 value postr"); printf("\n-------------------------------------------------"); printf("\n\nThe Value Is: %6.3f\n", eval()); /* ¿¬»ê °á°ú Ãâ·Â */ } void calc::popandtest(stack& ps, char& px, int& pund) /* ¿¬»êÀÚ ½ºÅà ³»¿ë ¹Ýȯ */ { if(ps.empty()) { /* ºñ¾úÀ¸¸é pund¿¡ Âü(1) ÇÒ´çÈÄ ¹Ýȯ */ pund = TRUE; return; } pund = FALSE; /* ¾Æ´Ï¸é pund¿¡ °ÅÁþ(0) ÇÒ´çÇϰí, px¿¡ ½ºÅó»¿ë ÇÒ´ç -> top °¨¼Ò */ px = ps.items[ps.top--]; return; } void calc::postfix() /* ÈÄÀ§ ¿¬»ê Ç¥±â ÇÔ¼ö */ /* °¡ÀμöÀÇ µ¥ÀÌŸÇüÀ» ¹®ÀÚÇü ¹è¿·Î ¹ÞÀ½ */ { int position, und; /* position -> infix[]ÀÇ ÇöÀ§Ä¡ ÁöÁ¤ */ int outpos = 0, j=0; /* outpos -> postfix[]ÀÇ ÇöÀ§Ä¡ ÁöÁ¤ */ char topsymb ='+'; /* opstk.items[](¿¬»êÀÚ ½ºÅÃ)ÀÇ Á¦ÀÏ ³¡ÀÇ ¿¬»êÀÚ */ char symb; stack opstk; printf("\n-------------------------------------"); printf("\n symb postr opstk "); printf("\n-------------------------------------"); for(position = 0; (symb = infix[position]) != '\0'; position++) /* ÁßÀ§ Ç¥±âÀÇ ³¡('\0') À϶§°¡Áö */ if(isdigit(symb)) { /* ¼ýÀÚ³Ä ? */ postr[outpos++] = symb; /* ÈÄÀ§ Ç¥±â ³»¿ë¿¡ »ðÀÔ */ printf("\n %c %s ", symb, postr); for(j=0;j<=opstk.gettop();j++) /* ¿¬»êÀÚ ½ºÅÃÀÇ ³»¿ë Ãâ·Â */ printf(" %c ", opstk.getitems(j)); } else { /* ¿¬»êÀÚ³ª ¶Ç´Â ´Ù¸¥ ¹®ÀÚ¸é */ popandtest(opstk,topsymb,und); /* ¿¬»êÀÚ ½ºÅà ³»¿ë Á¶»ç */ while(!und && prcd(topsymb,symb)) { /* ºñ¾îÀÖÁö ¾Ê°í ¿¬»êÀÚ ¼ø¼°¡ ¸ÂÀ¸¸é */ postr[outpos++] = topsymb; /* ¿¬»êÀÚ ½ºÅÃÀÇ ³»¿ë ÈÄÀ§ Ç¥±â ³»¿ë¿¡ »ðÀÔ */ popandtest(opstk,topsymb,und); } if(!und) /* ½ºÅÿ¡ ³»¿ëÀÌ ÀÖÀ¸¸é */ opstk.push(topsymb); /* ½ºÅÿ¡ ¿¬»êÀÚ »ðÀÔ */ if(und || (symb != ')')) /* ½ºÅÃÀÌ ºñ¾îÀÖ°í ¿¬»êÀÚ°¡ ')'°¡ ¾Æ´Ï¸é */ opstk.push(symb); /* ½ºÅÿ¡ ¿¬»êÀÚ »ðÀÔ */ else /* ¾Æ´Ï¸é ½ºÅÃÀÇ ³»¿ë ²¨³¿ -> ¿¬»êÀÚ ºñ±³¸¦ À§ÇØ */ topsymb = opstk.pop(); printf("\n %c %s ", symb, postr); for(j=0;j<=opstk.gettop();j++); printf(" %c ", opstk.getitems(j)); } while(!opstk.empty()) /* ¿¬»êÀÚ ½ºÅÃÀÇ ³»¿ë ÈÄÀ§ Ç¥±â¿¡ ÇÒ´ç */ postr[outpos++] = opstk.pop(); postr[outpos] = '\0'; /* NULL »ðÀÔ */ printf("\n %s ", postr); /* ÃÖÁ¾ ÈÄÀ§ ¿¬»ê Ç¥±â¹ý ³»¿ë Ãâ·Â */ printf("\n%s%2s", "\nThe Postfix Expression Is ", postr); /* ÈÄÀ§ Ç¥±âµÈ ³»¿ë Ãâ·Â */ return; } float calc::eval() /* ÈÄÀ§ Ç¥±â¹ýÀ¸·Î Ç¥±âµÈ ¿¬»ê½Ä °è»ê */ /* ÈÄÀ§ Ç¥±â ¿¬»ê½Ä ³»¿ë */ { int position,i; char c; float opnd1=0,opnd2=0,value=0; /* op1°ú op2 ±×¸®°í ¿¬»ê°á°ú °ª */ stack opndstk; for(position = 0; (c = postr[position]) != '\0'; position++) {if(isdigit(c)) /* ¼ýÀÚ¸é */ { opndstk.push((float) (c - '0')); /* ¹®ÀÚÇüÀ» floatÇüÀ¸·Î Çü ÀüȯÈÄ ½ºÅÿ¡ »ðÀÔ */ printf("\n %c %6.2f %6.2f %6.2f ",c,opnd1,opnd2,value); /* ¿¬»êÀÚ,op1,op2,°á°ú°ª Ãâ·Â */ for(i=0; i<= opndstk.gettop();i++) /* ¿ÀÆÛ·£µå ½ºÅÃÀÇ ³»¿ë Ãâ·Â */ printf("%5.1f",opndstk.getitems(i)); } else { /* ¹®ÀÚ¸é */ opnd2 = opndstk.pop(); /* ³ªÁß¿¡ PUSHµÈ ¼ö°¡ op2( LIFO) */ opnd1 = opndstk.pop(); value = oper(c,opnd1,opnd2); /* ¿¬»ê */ /* push(&opndstk,value); ¿¬»ê °á°ú ¿ÀÆÛ·£µå ½ºÅÿ¡ »ðÀÔ */ printf("\n %c %6.2f %6.2f %6.2f ",c,opnd1,opnd2,value); opndstk.push(value); for(i=0;i<=opndstk.gettop();i++) printf("%5.1f",opndstk.getitems(i)); } opnd1 = 0; opnd2 = 0; } return (value); /* ÃÖÁ¾ ¿¬»ê °á°ú ¹Ýȯ */ } float calc::oper(char symb, float op1, float op2) /* op1, op2¸¦ ¿¬»êÀÚ·Î ¿¬»ê */ { switch(symb) { case '+' : return(op1+op2); case '-' : return(op1-op2); case '*' : return(op1*op2); case '/' : return(op1/op2); default : printf("Illegal Opration"); /* ¿¬»êÀÚ°¡ ¾Æ´Ï¸é ERROR */ exit(1); } return 0; } Boolean calc::prcd (char topsymb, char symb) /* ¿¬»êÀÚÀÇ ¼ø¼°¡ ¸Â´ÂÁö Á¶»ç */ { if(topsymb == '(') return FALSE; else if(topsymb != ')' && symb == '(') return FALSE; /* °ýÈ£ »çÀÌ¿¡ ¿¬»êÀÚ°¡ ¾øÀ½ */ else if(topsymb != '(' && symb == '(') return TRUE; /* '((' ÇüÅ */ else if(topsymb == ')') { /* ')'´Â opstk.items[]ÀÇ ¸¶Áö¸·¿¡ ¿À¸é ¾ÈµÊ */ return TRUE; /*printf("\nERROR"); exit(0); */ }; if(topsymb == '(' && symb == ')') return TRUE; else if(topsymb == '+' && symb == ')') return TRUE; else if(topsymb == '-' && symb == ')') return TRUE; else if(topsymb == '-' || symb == ('+'||'-')) return TRUE; else if(topsymb == '*' || symb == ('*'||'/'||'+'||'-')) return TRUE; else if(topsymb == '/' || symb == ('/'||'*'||'+'||'-')) return TRUE; else return FALSE; /* ¿¬»êÀÚ ¿ì¼±¼øÀ§°¡ ³ôÀº ¿¬»êÀÚ°¡ ³·Àº ¿¬»êÀÚ º¸´Ù ¾Õ¿¡ ¿Â´Ù */ /* ¿ì¼±¼øÀ§°¡ ³ôÀº ¿¬»êÀÚ°¡ ³·Àº ¿¬»êÀÚ µÚ¿¡ ¿À¸é ³ôÀº ¿¬»êÀÚ¸¦ ¸ÕÀú ¿ÀÆÛ·£µå ½ºÅÿ¡ »ðÀÔ */ } void main() { calc a; a.getinfix(); a.postfix(); /* ÁßÀ§ Ç¥±â¹ýÀ» ÈÄÀ§ Ç¥±â¹ýÀ¸·Î Àüȯ */ a.output(); } 1.9.2 ÄÄÆÄÀÏ[mwyun@iokorea calc]$ make calc_report2 g++ -c -g -Wno-deprecated calc_report2.cpp g++ -o calc_report2 calc_report2.o -lstdc++ [mwyun@iokorea calc]$ 1.9.3 calc_report6 ½ÇÇà1.10 Âü Á¶ 1
1.11 Âü Á¶ 2
#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, eos, operand
} precedence;
precedence pstack[MAX_STACK_SIZE];
int stack[MAX_STACK_SIZE];
char expr[MAX_EXPR_SIZE];
static int isp[ ] = { 0, 19, 12, 12, 13, 13, 13, 0};
static int icp[ ] = {20, 19, 12, 12, 13, 13, 13, 0};
void add(int *top, int item); //stack¿¡ »ðÀÔ
void padd(int *top, precedence item); //pstack¿¡ »ðÀÔ
int delete1(int *top); //stack¿¡¼ »èÁ¦
precedence pdelete(int *top); //pstack¿¡¼ »èÁ¦
precedence get_token(char *symbol, int *n); //¹®ÀÚ¸¦ ÅäÅ«À¸·Î
int eval(void); //ÈÄÀ§Ç¥±â½Ä °è»ê
char print_token(precedence token); //ÅäÅ«À» ¹®ÀÚ·Î
void postfix(void); //ÁßÀ§¸¦ ÈÄÀ§·Î
void main()
{
printf("¼ö½ÄÀ» ÀÔ·ÂÇϽÿÀ [ÁßÀ§Ç¥±â] = ");
scanf("%s",expr);
strcat(expr," "); //¼ö½Ä¿¡ eos ¿¬°á (°ø¹é »ðÀÔ)
printf("[ÁßÀ§Ç¥±â] %s\n",expr);
postfix( );
printf("[ÈÄÀ§Ç¥±â] %s\n",expr);
printf("°è»ê°á°ú = %d\n",eval( ));
}
void add(int *top, int item)
{
if(*top >= MAX_STACK_SIZE-1)
{
fprintf(stderr,"\n½ºÅÃÀÌ ²Ë á½À´Ï´Ù.\n"); /* print error message */
exit(1);
}
stack[++*top]=item;
}
void padd(int *top, precedence item)
{
if(*top >= MAX_STACK_SIZE-1)
{
fprintf(stderr,"\n½ºÅÃÀÌ ²Ë á½À´Ï´Ù.\n"); /* print error message */
exit(1);
}
pstack[++*top]=item;
}
int delete1(int *top)
{
if(*top == -1)
{
fprintf(stderr,"\n½ºÅÃÀÌ ºñ¾ú½À´Ï´Ù.\n");
exit(1);
}
return stack[(*top)--];
}
precedence pdelete(int *top)
{
if(*top == -1)
{
fprintf(stderr,"\n½ºÅÃÀÌ ºñ¾ú½À´Ï´Ù.\n");
exit(1);
}
return pstack[(*top)--];
}
precedence get_token(char *symbol, int *n)
{
*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 ' ' : return eos;
default : return operand;
}
}
int eval(void)
{
precedence token;
char symbol;
int op1, op2;
int n=0; //¼ö½Ä ¹®ÀÚ¿À» À§ÇÑ Ä«¿îÅÍ
int top=-1;
token =get_token(&symbol, &n);
while (token != eos)
{
if(token == operand)
add(&top, symbol-'0'); //½ºÅà »ðÀÔ
else
{
//µÎ ÇÇ¿¬»êÀÚ¸¦ »èÁ¦ÇÏ¿© ¿¬»êÀ» ¼öÇàÇÑ ÈÄ, ±× °á°ú¸¦ ½ºÅÿ¡ »ðÀÔÇÔ
op2 = delete1(&top); //½ºÅà »èÁ¦
op1 = delete1(&top); //½ºÅà »èÁ¦
switch(token)
{
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); break;
}
}
token = get_token(&symbol, &n);
}
return delete1(&top); //°á°ú¸¦ ¹Ýȯ
}
char print_token(precedence token)
{
switch (token)
{
case lparen : return '(';
case rparen : return ')';
case plus : return '+';
case minus : return '-';
case divide : return '/';
case times : return '*';
case mod : return '%';
case eos : return ' ';
default : return ' ';
}
}
void postfix(void)
{ //¼ö½ÄÀ» ÈÄÀ§ Ç¥±â½ÄÀ¸·Î Ãâ·ÂÇÑ´Ù.
precedence token;
char symbol, pexpr[MAX_EXPR_SIZE];
int pn=0,n=0, top=0;
pstack[0]=eos;
token = get_token(&symbol, &n);
while (token != eos)
{
if(token == operand)
{
pexpr[pn++]=symbol;
}
else if (token == rparen)
{ //¿ÞÂÊ °ýÈ£°¡ ³ª¿Ã¶§±îÁö ÅäÅ«µéÀ» Á¦°ÅÇØ¼ Ãâ·Â½ÃÅ´
while(pstack[top] != lparen)
pexpr[pn++]=print_token(pdelete(&top));
pdelete(&top);
}
else
{
//simbolÀÇ isp°¡ tokenÀÇ icpº¸´Ù Å©°Å³ª °°À¸¸é symbolÀ» Á¦°ÅÇϰí Ãâ·Â½ÃÅ´
while(isp[pstack[top]] >= icp[token])
pexpr[pn++]=print_token(pdelete(&top));
padd(&top,token);
}
token = get_token(&symbol, &n);
}
while( (token=pdelete(&top)) != eos )
pexpr[pn++]=print_token(token);
pexpr[pn++]=' ';
pexpr[pn]='\0';
strcpy(expr,pexpr);
}
|
|
|
|
EmailÀ» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù. |
|