进制转换
栈先进后出的特性刚好符合十进制转二进制的方法:
#include <stdio.h>
#include <stdbool.h>
#define OK true
#define ERROR false
typedef bool STATUS;
#define MAX_SIZE 100
typedef char Elem_Type;
#define SYS 2 // 进制
typedef struct SQ_Stack
{
Elem_Type data[MAX_SIZE];
int top;
} SQ_Stack;
SQ_Stack stack;
STATUS init_stack(SQ_Stack *s)
{
s->top = -1;
return OK;
}
STATUS pop(SQ_Stack *s, Elem_Type *e)
{
if(s->top <= -1)
return ERROR;
*e = s->data[s->top];
(s->top)--;
return OK;
}
STATUS push(SQ_Stack *s, Elem_Type e)
{
if(s->top >= (MAX_SIZE - 1))
return ERROR;
(s->top)++;
s->data[s->top] = e;
return OK;
}
int main()
{
int num = 0;
Elem_Type temp;
printf("decimal numeral(num > 0): ");
scanf("%d",&num);
init_stack(&stack);
while(num != 0)
{
push(&stack, (num % SYS) + '0');
num /= SYS;
}
/* 打印结果 */
printf("binary number: ");
while(pop(&stack, &temp))
{
printf("%c",temp);
}
}
RPN(逆波兰)计算
早期计算机无法计算复杂的算式(对我们来说很简单),因此有了逆波兰计算:首先是中缀表达式转化为后缀表达式,然后计算机通过后缀表达式计算结果。
例:1+2*3
-->123*+
,(1+2)*3
-->12+3*
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define OK true
#define ERROR false
typedef bool STATUS;
typedef float Elem_Type;
#define INPUT_MAX_SIZE 100
typedef struct Node
{
Elem_Type data;
struct Node *prior;
}Node;
typedef struct CH_Stack
{
Node *top;
int size;
} CH_Stack;
CH_Stack stack;
STATUS init_stack(CH_Stack *s)
{
s->top = NULL;
s->size = 0;
return OK;
}
bool stack_is_empty(CH_Stack s)
{
if(s.size == 0)
return true;
return false;
}
STATUS pop(CH_Stack *s, Elem_Type *e)
{
if(s->size <= 0)
return ERROR;
Node *temp = s->top;
*e = temp->data;
s->top = s->top->prior;
(s->size)--;
free(temp);
return OK;
}
STATUS push(CH_Stack *s, Elem_Type e)
{
Node *temp = NULL;
if(!(temp = (Node *)malloc(sizeof(Node))))
return ERROR;
temp->data = e;
temp->prior = s->top;
s->top = temp;
(s->size)++;
return OK;
}
/*****************************************************************************
* @brief 中缀转后缀
*
* @param in 中缀表达式
* @param ch 后缀表达式
* @return STATUS
****************************************************************************/
STATUS change(char in[], char ch[])
{
int cur_i = 0;
int cur_c = 0;
Elem_Type temp = 0;
while(in[cur_i] != '\0')
{
if(in[cur_i] == '.' || ('0' <= in[cur_i] && in[cur_i] <= '9'))
{
ch[cur_c++] = in[cur_i];
cur_i++;
if(!(in[cur_i] == '.' || ('0' <= in[cur_i] && in[cur_i] <= '9')))
ch[cur_c++] = '#'; // 数字间隔
}
else if(in[cur_i] == '*' || in[cur_i] == '/' || in[cur_i] == '(')
{
push(&stack, in[cur_i]);
cur_i++;
}
else if(in[cur_i] == '+' || in[cur_i] == '-')
{
pop(&stack, &temp);
if((char)temp == '*' || (char)temp == '/') // 优先级
{
ch[cur_c++] = (char)temp;
}
else
{
push(&stack, temp);
}
push(&stack, in[cur_i]);
cur_i++;
}
else if(in[cur_i] == ')')
{
pop(&stack, &temp);
while((char)temp != '(')
{
ch[cur_c++] = (char)temp;
pop(&stack, &temp);
}
cur_i++;
}
else
{
return ERROR;
}
}
/* 清空栈 */
while(pop(&stack, &temp))
{
ch[cur_c++] = (char)temp;
}
ch[cur_c] = '\0';
return OK;
}
/*****************************************************************************
* @brief 后缀表达式计算
*
* @param ch 后缀表达式
* @return STATUS
****************************************************************************/
STATUS compute(char ch[])
{
int cur = 0;
char n[INPUT_MAX_SIZE];
int cur_n = 0;
Elem_Type temp = 0;
Elem_Type n1 = 0;
Elem_Type n2 = 0;
while(ch[cur] != '\0')
{
/* 字符串转数字 */
while (ch[cur] == '.' || ('0' <= ch[cur] && ch[cur] <= '9'))
{
n[cur_n++] = ch[cur++];
}
n[cur_n] = '\0';
temp = strtof(n,NULL);
cur_n = 0;
/* 计算 */
switch(ch[cur])
{
case '+' :
pop(&stack, &n1);
pop(&stack, &n2);
push(&stack, n2 + n1);
break;
case '-' :
pop(&stack, &n1);
pop(&stack, &n2);
push(&stack, n2 - n1);
break;
case '*' :
pop(&stack, &n1);
pop(&stack, &n2);
push(&stack, n2 * n1);
break;
case '/' :
pop(&stack, &n1);
pop(&stack, &n2);
push(&stack, n2 / n1);
break;
case '#' :
push(&stack, temp);
temp = 0;
break;
}
cur++;
}
pop(&stack,&temp);
printf("%.2f\n",temp);
return OK;
}
int main()
{
char in[INPUT_MAX_SIZE] = "";
char ch[INPUT_MAX_SIZE * 2] = "";
printf("What do you want to compute:\n");
scanf("%s",&in);
if(!change(in, ch))
printf("CHANGE ERROR!\n");
printf("postfix expression : %s\n",ch);
if(!compute(ch))
printf("COMPUTE ERROR!\n");
return 0;
}
测试集:
1)in:8 out:8
2)in:10+20 out:10#20#+
3)in:5+20*3 out:5#20#3#*+
4)in:80/5-10 out:80#5#/10#-
5)in:6-(23+4)*(40-25) out:6#23#4#+40#25#-*-
6)in:50/8-(60/2-3*(40-25)) out:50#8#/60#2#/3#40#25#-*--