#include <stdio.h>
#include <malloc.h>
#define MAXNUM 100
//栈最大元素个数
#define MAXEXP 30
//允许用户输入的表达式最大字符数
#include "bintree.h"
#include "stack.cpp"
const char and = '&', or = '|', then = '-';
bool InOpt(char c)
{
return (c == '&' || c == '|' || c == '-' || c == '#');
}
bool IsNum(char c)
{
return (c >= '0' && c <= '9');
}
bool IsAlp(char c)
{
return ((c <= 'z' && c >= 'a') || (c >= 'A' && c <= 'Z'));
}
bool CheckSyntax(char* exp)
{
char* cp = exp;
while (*cp != '\0')
{
if (!(IsNum(*cp) || IsAlp(*cp) || InOpt(*cp) || *cp == '(' || *cp == ')'))
return FALSE;
cp++;
}
if (*(--cp) != '#')
return FALSE;
return TRUE;
}
PBinTree TransferTree(char *exp)
{
PBinTreeNode pbt = CrtBinTree();
Stack<BinTreeNode*> st;
Stack<char> sc;
char* ch = exp,c;
sc.Push('#');
while (!(sc.GetTop()== '#' && *ch == '#'))
{
if (IsAlp(*ch))
{
PBinTreeNode t = CrtBinTree();
t->data = *ch;
st.Push(t);
}
else if (IsNum(*ch))
{
while (IsNum(*ch))
{
ch++;
}
ch--;
PBinTreeNode t = CrtBinTree();
t->data = *ch;
st.Push(t);
}
else
{
switch (*ch)
{
case '(':
sc.Push(*ch);
break;
case ')':
{
c = sc.Pop();
while (c != '(')
{
PBinTreeNode t = CrtBinTree();
t->data = c;
t->rChild = st.Pop();
t->lChild = st.Pop();
st.Push(t);
c = sc.Pop();
}
break;
}
default:
{
while (sc.GetTop() != '#' && sc.GetTop() != '(')
{
PBinTreeNode t = CrtBinTree();
c = sc.Pop();
t->data = c;
t->rChild = st.Pop();
t->lChild = st.Pop();
st.Push(t);
}
if (*ch != '#')
sc.Push(*ch);
break;
}
}
}
if (!sc.IsEmpty() && *ch != '#')
ch++;
}
pbt = st.Pop();
return pbt;
}
void GetVariable(PBinTree pbt)
{
PBinTree vpt = pbt;
if ((pbt->data >= 'a' && pbt->data <= 'z') || (pbt->data >= 'A' && pbt->data <= 'Z'))
{
printf ("请输入%c的值(1或0):\n",vpt->data);
scanf ("%c",&vpt->data);
getchar();
}
if (vpt->lChild != NULL)
GetVariable(vpt->lChild);
if (vpt->rChild != NULL)
GetVariable(vpt->rChild);
}
char Caculate(PBinTree pbt)
{
PBinTree vpt = pbt;
if (vpt == NULL)
{
printf("没有任何表达式可计算!");
return FALSE;
}
if (vpt->lChild == NULL)
//找到叶子结点
return vpt->data;
if (InOpt(vpt->data) && Caculate(vpt->lChild) && Caculate(vpt->rChild))
{
switch(vpt->data)
{
case and:
if (Caculate(vpt->lChild) == '1' && Caculate(vpt->rChild) == '1')
vpt->data = '1';
else vpt->data = '0';
break;
case or:
if (Caculate(vpt->lChild) == '0' && Caculate(vpt->rChild) == '0')
vpt->data = '0';
else vpt->data = '1';
break;
case then:
if (Caculate(vpt->lChild) == '1' && Caculate(vpt->rChild) == '0')
vpt->data = '0';
else vpt->data = '1';
break;
}
}
return vpt->data;
}
void main()
{
char* exp = (char*) malloc (sizeof(char)*MAXEXP);
printf("****************************************************************************\n");
printf("**
逻辑表达式计算器1.10
**\n");
printf("**
Created by YangPengfei(pkusocold@)
**\n");
printf("**
本计算器前只支持或(|)、与(&)、非(!)以及蕴涵(-)运算
**\n");
printf("****************************************************************************\n");
printf("\n");
printf("请输入需要计算的逻辑表达式(需要在表达式后加一个\"#\"号):\n");
gets(exp);
while (!CheckSyntax(exp))
{
printf("表达式输入错误,请重新输入:\n");
gets(exp);
}
PBinTree pbt = TransferTree(exp);
GetVariable(pbt);
printf ("这个逻辑表达式的值为:
%c
\n",Caculate(pbt));
}
[
本帖最后由 vandychan 于 2010-10-23 20:43 编辑 ]