NYOJ 128 前缀式计算

来源:互联网 发布:编程自学 编辑:程序博客网 时间:2024/04/27 22:45

 
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define MAXSIZE 1010

typedef struct stack
{
 double data[MAXSIZE];
 int top;
}Stack;

void init_stack(Stack *s);
int stack_full(Stack *s);
int stack_empty(Stack *s);
void push_stack(Stack *s, double x);
void pop_stack(Stack *s);
double operrate(double a, double b, double c);
char*  strrev(char *string);

int main(void)
{

 Stack s;
 init_stack(&s);
 char str[MAXSIZE];
//freopen("in.txt", "r", stdin);
 while( gets(str) )
 {
  int i, j = 0;
  int len = strlen(str);
  char string[20];
  i = len;
  double number[MAXSIZE];
  for(i = len - 1; i >= 0; i --)
  {
   if(str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')
   {
    switch(str[i])
    {
     case '+':
        number[j ++] = -1;
        break;
     case '-':
        number[j ++] = -2;
        break;
     case '*':
        number[j ++] = -3;
        break;
     case '/':
        number[j ++] = -4;
        break;
    }
   }
   else if( str[i] != ' ' && ( str[i] >= 48 || str[i] == 46) )
   {
    int k = 0;
    while(str[i] != ' ' && ( str[i] >= 48 || str[i] == 46) )
    {
     string[k ++] = str[i --];
    }
    string[k] = 0;
    number[j ++] = atof(strrev(string));
   }
  }
  for(i = 0; i < j; i ++)
  {
   if(number[i] >= 0)
   {
    push_stack(&s, number[i]);
   }
   else if(number[i] < 0)
   {
    number[i] = operrate(s.data[s.top], s.data[s.top - 1], number[i]);
    pop_stack(&s);
    pop_stack(&s);
    push_stack(&s, number[i]);
   }
  }
  printf("%.2lf\n", number[i - 1]);

  memset(str, 0, sizeof(str));
 }

 return 0;
}

void init_stack(Stack *s)
{
 s->top = -1;
}
int stack_full(Stack *s)
{
 return s->top == MAXSIZE - 1;
}
int stack_empty(Stack *s)
{
 return s->top == -1;
}
void push_stack(Stack *s, double x)///
{
 if(stack_full(s))//
  exit(EXIT_FAILURE);
 s->data[++s->top] = x;
}
void pop_stack(Stack *s)
{
 if(stack_empty(s))
  exit(EXIT_FAILURE);
 s->top--;
}
double operrate(double a, double b, double c)
{
 if( fabs(c -(-1) ) < 0.000001 )
  return a + b;
 else if( fabs(c -(-2) ) < 0.000001)
  return a - b;
 else if(fabs( c -(-3)) < 0.000001)
  return a * b;
 else if(fabs (c -(-4)) < 0.000001)
  return a / b;
}
char*  strrev(char *string)
{

 char ch[MAXSIZE];
 int i = 0, j = 0, k = 0;
 while(string[i] != '\0')
 {
  ch[i] = string[i];
  i ++;
 }
 for(k = i - 1; k >= 0; k --)
 {
  string[j ++] = ch[k];
 }
 string[j] = '\0';
 return string;
}        

 

思路:(l利用顺序栈的知识, 从前缀式的后面开始读)

1.先将全部字符(除了空格)转换成数字存到一个数组number里面 ,其中‘+’:-1, ‘-’:-2, ‘*’:-3, ‘/’:-4;对于正整数和小数的字符,先将其存放到一个字符数组中,然后再利用串逆转函数strrev,将其逆转,再利用atof函数将其转化成浮点数存到number中;比如:+ 2 * + 3 4 5转换成数字并存到number中为5 4 3 -1 -3 2 -1

2.再将number中的数字压栈,当遇到负数的时候,取出栈中的两个数,进行运算,number[i]保存计算结果,两次pop_stack(&s), 一次push_stack(&s, number[i]),

3.清空接收字符串的数组str;

注意:

1.while(gets(str)), gets,从stdin流中读多个字符,并且把这些字符存储到s指向的数组中。当遇到第一个换行符(丢弃该换行符)或到达文件末尾时停止读。gets会在字符串的组后附加一个空字符。

2.strrev函数的书写;

3.学会进行模块化设计,每个模块要专一于实现某一功能;

4.switch代替if - else语句

错误思路下的代码:

http://paste.ubuntu.com/6191377/

原创粉丝点击