十进制 N 和 其他进制 d 之间的转换 公式:
N = ( N ÷ d ) ∗ d + N % d N=(N\div d)*d+N\%d N=(N÷d)∗d+N%d
例: ( 1348 ) 10 = ( 2504 ) 8 (1348)_{10}=(2504)_8 (1348)10=(2504)8 运算过程如下:
示例:
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include "LinkStack.h"
//进制转换
int main()
{
LinkStack * stack = NULL;
stack = LinkStack_Create();
int arr[30] = {
0 };
int i = 0;
int sys = 0;
int num = 0;
printf("请输入进制:\n");
scanf("%d", &sys);
printf("请输入待转换的数字:\n");
scanf("%d", &num);
printf("\n\n");
while (num)
{
arr[i] = num%sys;
LinkStack_Push(stack, &arr[i]);
num = num / sys;
i++;
}
printf("转换 %d 进制结果= ",sys);
while (LinkStack_Size(stack) > 0)
{
int *n = (int*)LinkStack_Pop(stack);
if (sys==16)
{
printf("%X", *n);
}
else
{
printf("%d", *n);
}
}
printf("\n\n");
LinkStack_Destroy(stack);
system("pause");
return 0;
}
使用的栈结构见博客:数据结构:栈(Stack 链式存储结构) C语言版
基于栈的特性和就近匹配原则
符合我们习惯的数学表达式叫做中缀表达式 ,例如: 9 + ( 3 − 1 ) ∗ 5 + 8 / 2 9 + (3 - 1) * 5 + 8 / 2 9+(3−1)∗5+8/2 ,等这种日常表达式。
明显特正就是运算符号在数字中间
后缀表达式是一种不需要括号的后缀表达法,也称逆波兰表示。
例如:
明显特征就是运算符号在数字后面,后缀表达式更符合计算机运算习惯。
栈数据结构对于中缀转后缀规则:
遍历中缀表达式中的数字和符号
对于数字:直接输出
对于符号:
遍历结束:将栈中的所有符号弹出并输出。
运算符的优先关系:
任意两个相继出现的算符 θ 1 \theta_1 θ1 和 θ 2 \theta_2 θ2 之间的优先关系之多是下面3中关系之一。
示例:
基于栈的后缀表达式计算方法:
例: 8 + ( 3 − 1 ) ∗ 5 = = > 831 − 5 ∗ + 8+(3-1)*5==>831-5*+ 8+(3−1)∗5==>831−5∗+
1:括号匹配
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include "LinkStack.h"
int isLeft(char c)
{
int ret = 0;
switch (c)
{
case '<':
case '(':
case '[':
case '{':
case '\'':
case '\"':
ret = 1;
break;
default:
ret = 0;
break;
}
return ret;
}
int isRight(char c)
{
int ret = 0;
switch (c)
{
case '>':
case ')':
case ']':
case '}':
case '\'':
case '\"':
ret = 1;
break;
default:
ret = 0;
break;
}
return ret;
}
int match(char left, char right)
{
int ret = 0;
switch (left)
{
case '<':
ret = (right == '>');
break;
case '(':
ret = (right == ')');
break;
case '[':
ret = (right == ']');
break;
case '{':
ret = (right == '}');
break;
case '\'':
ret = (right == '\'');
break;
case '\"':
ret = (right == '\"');
break;
default:
ret = 0;
break;
}
return ret;
}
int scanner(const char* code)
{
LinkStack* stack = LinkStack_Create();
int ret = 0;
int i = 0;
while (code[i] != '\0')
{
if (isLeft(code[i]))
{
LinkStack_Push(stack, (void*)(code + i)); //&code[i]
}
if (isRight(code[i]))
{
char* c = (char*)LinkStack_Pop(stack);
if ((c == NULL) || !match(*c, code[i]))
{
printf(" 【%c】 错误匹配 【%c】 , \n", code[i],*c);
ret = 0;
break;
}
}
i++;
}
if ((LinkStack_Size(stack) == 0) && (code[i] == '\0'))
{
printf("合格代码!\n");
ret = 1;
}
else
{
printf("错误代码!\n");
ret = 0;
}
LinkStack_Destroy(stack);
return ret;
}
void main()
{
const char* code = "#include int main() { int a[4][4]; int (*p)[4]; p = a[0; return 0;} " ;
scanner(code);
system("pause");
return;
}
下面这段代码 a[0 少了一个 ] 号,进行测试括号匹配
#include int main() { int a[4][4]; int (*p)[4]; p = a[0; return 0;} "
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "linkstack.h"
int isNumber(char c)
{
return ('0' <= c) && (c <= '9');
}
int isOperator(char c)
{
return (c == '+') || (c == '-') || (c == '*') || (c == '/');
}
int isLeft(char c)
{
return (c == '(');
}
int isRight(char c)
{
return (c == ')');
}
int priority(char c)
{
int ret = 0;
if ((c == '+') || (c == '-'))
{
ret = 1;
}
if ((c == '*') || (c == '/'))
{
ret = 2;
}
return ret;
}
void output(char c)
{
if (c != '\0')
{
printf("%c", c);
}
}
void transform(const char* exp)
{
int i = 0;
LinkStack* stack = LinkStack_Create();
while (exp[i] != '\0')
{
if (isNumber(exp[i]))
{
output(exp[i]);
}
else if (isOperator(exp[i]))
{
while (priority(exp[i]) <= priority((char)(int)LinkStack_Top(stack)))
{
output((char)(int)LinkStack_Pop(stack));
}
LinkStack_Push(stack, (void*)(int)exp[i]);
}
else if (isLeft(exp[i]))
{
LinkStack_Push(stack, (void*)(int)exp[i]);
}
else if (isRight(exp[i]))
{
//char c = '\0';
while (!isLeft((char)(int)LinkStack_Top(stack)))
{
output((char)(int)LinkStack_Pop(stack));
}
LinkStack_Pop(stack);
}
else
{
printf("Invalid expression!");
break;
}
i++;
}
while ((LinkStack_Size(stack) > 0) && (exp[i] == '\0'))
{
output((char)(int)LinkStack_Pop(stack));
}
LinkStack_Destroy(stack);
}
int main()
{
transform("8+(3-1)*5");
printf("\n");
system("pause");
return 0;
}
#include "stdio.h"
#include "stdlib.h"
#include "linkstack.h"
int isNumber3(char c)
{
return ('0' <= c) && (c <= '9');
}
int isOperator3(char c)
{
return (c == '+') || (c == '-') || (c == '*') || (c == '/');
}
int value(char c)
{
return (c - '0');
}
int express(int left, int right, char op)
{
int ret = 0;
switch (op)
{
case '+':
ret = left + right;
break;
case '-':
ret = left - right;
break;
case '*':
ret = left * right;
break;
case '/':
ret = left / right;
break;
default:
break;
}
return ret;
}
int compute(const char* exp)
{
LinkStack* stack = LinkStack_Create();
int ret = 0;
int i = 0;
while (exp[i] != '\0')
{
if (isNumber3(exp[i]))
{
LinkStack_Push(stack, (void*)value(exp[i]));
}
else if (isOperator3(exp[i]))
{
int right = (int)LinkStack_Pop(stack);
int left = (int)LinkStack_Pop(stack);
int result = express(left, right, exp[i]);
LinkStack_Push(stack, (void*)result);
}
else
{
printf("Invalid expression!");
break;
}
i++;
}
if ((LinkStack_Size(stack) == 1) && (exp[i] == '\0'))
{
ret = (int)LinkStack_Pop(stack);
}
else
{
printf("Invalid expression!");
}
LinkStack_Destroy(stack);
return ret;
}
int main()
{
printf("8 + (3 - 1) * 5 = %d\n", compute("831-5*+"));
system("pause");
return 0;
}