| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3748 人关注过本帖, 2 人收藏
标题:如果检验一个输入的"常量表达式"是否合法~
取消只看楼主 加入收藏
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
结帖率:99.25%
收藏(2)
已结贴  问题点数:100 回复次数:7 
如果检验一个输入的"常量表达式"是否合法~
现在有一个表达式(里面都是合法运算符合常量而且可能会有括号和浮点数)
现在需要一个程序来判断该表达式是否合法~

表达式运算符只有'+','-''*','/','(',')'和小数点'.'
数字以十进制0-9的形式输入~

所谓合法就是指能在编译器正常通过编译的表达式~

例如:
1+2+3---合法
2.2+3*4---合法
-5+6*(4+1)/3+2---合法(最前一位可以是负号)
((4+3)+2---非法(左右括号不匹配)
4.65**2--非法(运算符号问题)
.45+1和45.和5.666.7---非法(小数点不合法)
45+22+   ---非法(最后一个运算符号找不到数字匹配)
56#33    ---非法(含有非法运算符)
777+()/3 ---非法(括号内容不能为空)
12+(34)3 ---非法(括号右端必须跟运算符)

PS:3+-4或者3-+4也是合法表达式,但3--4和3++4就是非法表达式了(不能正常通过编译)~

总之~能通过编译器编译的常量表达式都是合法表达式~
否则就不是合法表达式~

输入一串字符串,判断该表达式是否是合法表达式(字符串长度在100以内)~

感觉要考虑的情况很多的样子~看看有没有高手能给些高见?~感觉数据结构很冷清啊~还是发在人气较旺的C论坛比较好~希望有高手能做出来~~~



[此贴子已经被作者于2017-3-22 23:03编辑过]

搜索更多相关主题的帖子: 编译器 表达式 十进制 小数点 
2017-03-22 22:55
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
公测一下这个~~~
检查表达式是否正确是实现四则混合运算的基础~
这段代码只是完善了检查表达式是否合法的功能~暂时还没有检查出BUG(除了前导0这个问题可以忽略)~~~

程序代码:
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>

#define LEN_Node sizeof (Node)
#define LEN_Single sizeof (Single)

typedef enum COM
{

 
    NUMBER,             //数字 
    SINGLE,             //运算符号(加减乘除)

    ADD,                //加号
    SUB,                //减号
    MUL,                //乘号
    DIV,                //除法
    POINT,              //小数点
    LEFT_PARENTHESES,   //左括号
    RIGHT_PARENTHESES,  //右括号

    WAIT_USE,           //等待使用(对于小数点处理)
    CAN_USE,            //可以使用
    CANNOT_USE,         //不能使用
    OK,                 //正常
    ERROR,              //出错
}COM;

typedef struct Single    //运算符号
{
    char c;              //符号标记
    int level;           //符号运算优先等级
}Single;

Single single[]={'(',1,')',1,'*',2,'/',2,'+','3','-',3,'.',4};

typedef struct Single_Style
{
    COM num;                      //检查能否使用数字
    COM add;                      //加法状态
    COM sub;                      //减法状态
    COM mul;                      //乘法状态
    COM div;                      //除法状态
    COM point;                    //小数点状态
    COM left_parentheses;         //左括号状态
    COM right_parentheses;        //右括号状态

}Single_Style;

Single_Style com={0};

typedef struct Node  
{
    char c;
    struct Node* next;
}Node,*PNode;

char Num_Buff[100]={0};                          //数据缓冲空间

PNode New_Node(PNode head,int size);             //创建一个头节点
PNode Init(PNode head);                          //创建一个表达式

COM Find_Single(char c,char*ch ,int* level);     //查找是否存在符号
void Single_CAN_USE();                           //运算符可以使用
void Single_CANNOT_USE();                        //运算符不可以使用
 
COM Check(PNode head);                           //检查表达式输入是否合法
void Print(PNode p);                             //输出数据

int main()
{
    PNode head=NULL;

    head=New_Node(head,LEN_Node);

    head=Init(head);

    if (Check(head)==ERROR)
    {
        puts("输入表达式有误!");
        exit(0);
    }

    Print(head);

    return 0;
}

PNode New_Node(PNode p,int Size)  //创建一个头节点
{
    p=(PNode)malloc(Size);

    if (p==NULL)
    {
        puts("创建失败!");
        exit(0);
    }
    memset(p,0,Size);

    return p;
}

PNode Init(PNode head)   //创建一个表达式
{
    PNode p=head;
    char ch=0;

    while (p->next)      //把指针移到尾部
        p=p->next;

    puts("请输入表达式:");
    while ((ch=getchar())!='\n')
    {
        p=p->next=New_Node(p,LEN_Node);
        p->c=ch;
    }

    return head;
}

void Print(PNode p)      //输出数据
{
    puts("输入表达式如下:");
    for (;p=p->next;printf("%c",p->c));
    puts("");
}

int Find_Single(char c,char*ch ,int* level)    //查找是否存在符号
{
    int i=0;
    if (isdigit(c))
        return NUMBER;  //返回数字

    for (i=0;c!=single[i].c&&i<sizeof(single)/sizeof(*single);++i);

    if (i==sizeof(single)/sizeof(*single))  //如果找不到运算符号,则显示出错
        return ERROR;

    *ch=single[i].c;
    *level=single[i].level;

    switch (single[i].c)  
    {
        case '(':
            return LEFT_PARENTHESES;
        case ')':
            return RIGHT_PARENTHESES;
        case '+':
            return ADD;
        case '-':
            return SUB;
        case '*':
            return
                MUL;
        case '/': 
            return DIV;
        case '.':
            return POINT;

        default :
            return ERROR;
    }
}

void Single_CAN_USE()        
{
    com.add=CAN_USE;               //可以使用加法
    com.sub=CAN_USE;               //可以使用减法
    com.mul=CAN_USE;               //可以使用乘法
    com.div=CAN_USE;               //可以使用除法
}

void Single_CANNOT_USE()
{
    com.add=CANNOT_USE;              //不可以使用加法
    com.sub=CANNOT_USE;              //不可以使用减法
    com.mul=CANNOT_USE;              //不可以使用乘法
    com.div=CANNOT_USE;              //不可以使用除法
    com.point=CAN_USE;
    com.left_parentheses=CAN_USE;    //可以使用左括号
    com.right_parentheses=CANNOT_USE;//不可以使用右括号
}

COM Check(PNode head)
{
    PNode p=head;

    COM cc=0;
    int parentheses=0;          //判断括号是否合理,初始记录括号数目为0
    int point=WAIT_USE;         //判断小数点是否合理  
    char ch=0;
    char t_ch=0;                //暂存单元
    int level=0;                //运算符优先等级记录(初始化暂不需要)

    com.num=CAN_USE;
    com.add=CAN_USE;                  //初始化加号可以用
    com.sub=CAN_USE;                  //初始化减号可以用
    com.mul=CANNOT_USE;               //初始化乘号可以用
    com.div=CANNOT_USE;               //初始化除号可以用
    com.point=WAIT_USE;               //初始化小数点等待使用
    com.left_parentheses=CAN_USE;     //初始化左括号可以使用
    com.right_parentheses=CANNOT_USE; //初始化右括号不可以使用

    while (p=p->next)                //判断所有字符输入都是合法数据
    {
        switch (Find_Single(p->c,&ch,&level))
        {
            case NUMBER:   //数字
                if (com.num==CANNOT_USE) 
                    return ERROR;

                Single_CAN_USE();         //运算符号可以使用
                if (com.point==WAIT_USE)
                    com.point=CAN_USE;

                com.right_parentheses=CAN_USE;  //数字后面可以跟右括号
                break;

            case ADD:
                if (com.add==CANNOT_USE)
                    return ERROR;

                Single_CANNOT_USE();        //不可以连续使用运算符号
                com.point=WAIT_USE;         //小数点可以等待使用
                com.sub=CAN_USE;             //加号后面可以跟减号
                com.num=CAN_USE;            //符号右边可以使用数字
                break;

            case SUB:
                if (com.sub==CANNOT_USE)
                    return ERROR; 

                Single_CANNOT_USE();        //不可以连续使用运算符号
                com.point=WAIT_USE;
                com.add=CAN_USE;            //可以使用加号
                com.num=CAN_USE;
                break;

            case MUL:
                if (com.mul==CANNOT_USE)
                    return ERROR;
            case DIV:
                if (com.div==CANNOT_USE)
                    return ERROR;

                Single_CANNOT_USE();        //如果遇到乘除运算符号,则该符号不能连续使用
                com.point=WAIT_USE;
                com.num=CAN_USE;
                break;

            case POINT:
                if (com.point==CAN_USE)
                {
                    Single_CANNOT_USE();                //小数点后面不能直接跟运算符号
                    com.left_parentheses=CANNOT_USE;    //左括号不能使用
                    com.right_parentheses=CANNOT_USE;   //右括号不能使用
                    com.point=CANNOT_USE;

                }
                else 
                    return ERROR;
                break;

            case LEFT_PARENTHESES:
                if (com.left_parentheses==CANNOT_USE)
                    return ERROR;

                ++parentheses;                         //记录括号标记个数+1
                Single_CANNOT_USE();                   //不可以使用运算符号
                com.right_parentheses=CANNOT_USE;      //右括号不能使用
                com.add=CAN_USE;                       //重置可以使用加号
                com.sub=CAN_USE;                       //重置可以使用减号
                break;

            case RIGHT_PARENTHESES:
                if (com.right_parentheses==CANNOT_USE)
                    return ERROR;

                --parentheses;                         //记录括号标记个数-1
                if (parentheses<0)                     //如果括号标记小于0
                    return ERROR;

                Single_CAN_USE();                      //可以使用运算符号
                com.num=CANNOT_USE;                    //右括号右端不能使用数字
                break;

            case ERROR:
                return ERROR;

            default :
                return ERROR;
        } 

        t_ch=p->c;   //记录暂存单元
    }
    
    cc=Find_Single(t_ch,&ch,&level);

    if (t_ch!='\0'&&cc!=NUMBER&&cc!=RIGHT_PARENTHESES)  //考虑尾数不是数字和右括号的情况
        return ERROR;

    if (parentheses!=0)         //如果括号不匹配
        return ERROR;

    return OK;
}




[此贴子已经被作者于2017-3-23 05:26编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-03-23 00:43
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
更新完毕~可以实现四则混合运算功能~还没有去优化~感觉还可以~试试效果如何~

程序代码:
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<conio.h>
#include<string.h>

#define LEN_Node sizeof (Node)
#define LEN_Single sizeof (Single)
#define LEN_Ltem sizeof (Ltem)

typedef enum COM
{

 
    NUMBER,             //数字 
    SINGLE,             //运算符号(加减乘除)

    ADD,                //加号
    SUB,                //减号
    MUL,                //乘号
    DIV,                //除法
    POINT,              //小数点
    LEFT_PARENTHESES,   //左括号
    RIGHT_PARENTHESES,  //右括号

    WAIT_USE,           //等待使用
    CAN_USE,            //可以使用
    CANNOT_USE,         //不能使用

    OK,                 //正常
    ERROR,              //出错
}COM;

typedef struct Single    //运算符号
{
    char c;              //符号标记
    int level;           //符号运算优先等级
}Single;

Single single[]={'(',1,')',1,'*',2,'/',2,'+','3','-',3,'.',4};

typedef struct Single_Style
{
    COM num;                      //检查能否使用数字
    COM add;                      //加法状态
    COM sub;                      //减法状态
    COM mul;                      //乘法状态
    COM div;                      //除法状态
    COM point;                    //小数点状态
    COM left_parentheses;         //左括号状态
    COM right_parentheses;        //右括号状态

}Single_Style;

Single_Style com={0};

typedef struct Node  
{
    char c;
    struct Node* next;
}Node,*PNode;

typedef union Date            //用共用体储存数据
{
    double num;
    Single single;
}Date;

typedef struct Ltem
{
    COM com;
    Date date;
    struct Ltem* next;

}Ltem,*PLtem;

PNode New_Node(int size);                        //创建一个头节点
PNode Init(PNode head);                          //创建一个表达式
PNode Del_Node(PNode p);                         //删除一个节点            

COM Find_Single(char c,char*ch ,int* level);     //查找是否存在符号
void Single_CAN_USE();                           //运算符可以使用
void Single_CANNOT_USE();                        //运算符不可以使用
 
COM Check(PNode head);                           //检查表达式输入是否合法
void Print(PNode p);                             //输出数据

PLtem New_Ltem();                                //创建一个项
PLtem Push_Ltem(PLtem h_ltem,PNode h_node);      //插入一个项
PLtem Del_Ltem(PLtem p);                         //删除一个项
void Print_Ltem(PLtem p);                        //输出一个项

PLtem Del_Parentheses(PLtem h_ltem);              //消去括号(原理:括号里面只有一个常数项就可以消除)
PLtem Count_Mul_Div(PLtem h_ltem);                //计算乘除法运算
PLtem Count_Add_Sub(PLtem h_ltem);                //计算加减法运算

int main()
{
    puts("说明:输入表达式只含有+-*/四种运算符号,支持括号和浮点数运算,按ESC键退出");

    while (1)
    {
        PNode head=NULL;
        PLtem h_ltem=NULL;

        head=New_Node(LEN_Node);
        head=Init(head);

        if (head->next==NULL)
        {
            free(head);
            continue;
        }

        if (Check(head)==ERROR)
        {
             puts("输入表达式有误!");
            free(head);
             continue;
        }

        h_ltem=New_Ltem(h_ltem);
        h_ltem=Push_Ltem(h_ltem,head);

        free(head);
        head=NULL;

        Print_Ltem(h_ltem);

        while (h_ltem->next&&h_ltem->next->next)
        {
            h_ltem=Del_Parentheses(h_ltem);        //去除括号处理
            h_ltem=Count_Mul_Div(h_ltem);          //计算乘除法运算
            h_ltem=Count_Add_Sub(h_ltem);          //计算加减运算
        }      

        printf("运算结果是:%g\n",h_ltem->next->date.num);

        free(h_ltem->next);
        free(h_ltem);
        h_ltem=NULL;

        puts("按ESC键退出,其余键继续");

        if (getch()==27)
            break;
    }

    return 0;
}

PNode New_Node(int Size)  //创建一个头节点
{
    PNode p=(PNode)malloc(Size);

    if (p==NULL)
    {
        puts("创建失败!");
        exit(0);
    }
    memset(p,0,Size);

    return p;
}

PNode Init(PNode head)   //创建一个表达式
{
    PNode p=head;
    char ch=0;

    while (p->next)      //把指针移到尾部
        p=p->next;

    puts("请输入表达式:");
    while ((ch=getchar())!='\n')
    {
        p=p->next=New_Node(LEN_Node);
        p->c=ch;
    }

    return head;
}

PNode Del_Node(PNode p)            //删除一个节点,并把链表指针移动向下一个节点(相当于出队功能) 
{
    PNode tp=NULL;
    PNode ttp=p;    

    if (p==NULL||p->next==NULL)
        return NULL;

    tp=p->next;
    p=tp->next;
    free(tp);

    ttp->next=p;

    return ttp;
}

void Print(PNode p)      //输出数据
{
    puts("输入表达式如下:");
    for (;p=p->next;printf("%c",p->c));
    puts("");
}

int Find_Single(char c,char*ch ,int* level)    //查找是否存在符号
{
    int i=0;

    if (isdigit(c))
        return NUMBER;  //返回数字

    for (i=0;c!=single[i].c&&i<sizeof(single)/sizeof(*single);++i);

    if (i==sizeof(single)/sizeof(*single))  //如果找不到运算符号,则显示出错
        return ERROR;

    *ch=single[i].c;
    *level=single[i].level;

    switch (single[i].c)  
    {
        case '(':
            return LEFT_PARENTHESES;
        case ')':
            return RIGHT_PARENTHESES;
        case '+':
            return ADD;
        case '-':
            return SUB;
        case '*':
            return
                MUL;
        case '/': 
            return DIV;
        case '.':
            return POINT;

        default :
            return ERROR;
    }
}

void Single_CAN_USE()        
{
    com.add=CAN_USE;               //可以使用加法
    com.sub=CAN_USE;               //可以使用减法
    com.mul=CAN_USE;               //可以使用乘法
    com.div=CAN_USE;               //可以使用除法
}

void Single_CANNOT_USE()
{
    com.add=CANNOT_USE;              //不可以使用加法
    com.sub=CANNOT_USE;              //不可以使用减法
    com.mul=CANNOT_USE;              //不可以使用乘法
    com.div=CANNOT_USE;              //不可以使用除法
    com.point=CAN_USE;
    com.left_parentheses=CAN_USE;    //可以使用左括号
    com.right_parentheses=CANNOT_USE;//不可以使用右括号
}

COM Check(PNode head)
{
    PNode p=head;

    COM cc=0;
    int parentheses=0;          //判断括号是否合理,初始记录括号数目为0
    int point=WAIT_USE;         //判断小数点是否合理  
    char ch=0;
    char t_ch=0;                //暂存单元
    int level=0;                //运算符优先等级记录(初始化暂不需要)

    com.num=CAN_USE;
    com.add=CAN_USE;                  //初始化加号可以用
    com.sub=CAN_USE;                  //初始化减号可以用
    com.mul=CANNOT_USE;               //初始化乘号可以用
    com.div=CANNOT_USE;               //初始化除号可以用
    com.point=WAIT_USE;               //初始化小数点等待使用
    com.left_parentheses=CAN_USE;     //初始化左括号可以使用
    com.right_parentheses=CANNOT_USE; //初始化右括号不可以使用

    while (p=p->next)                //判断所有字符输入都是合法数据
    {
        switch (Find_Single(p->c,&ch,&level))
        {
            case NUMBER:   //数字
                if (com.num==CANNOT_USE) 
                    return ERROR;

                Single_CAN_USE();         //运算符号可以使用
                if (com.point==WAIT_USE)
                    com.point=CAN_USE;

                com.right_parentheses=CAN_USE;  //数字后面可以跟右括号
                break;

            case ADD:
                if (com.add==CANNOT_USE)
                    return ERROR;

                Single_CANNOT_USE();        //不可以连续使用运算符号
                com.point=WAIT_USE;         //小数点可以等待使用
                com.sub=CAN_USE;             //加号后面可以跟减号
                com.num=CAN_USE;            //符号右边可以使用数字
                break;

            case SUB:
                if (com.sub==CANNOT_USE)
                    return ERROR; 

                Single_CANNOT_USE();        //不可以连续使用运算符号
                com.point=WAIT_USE;
                com.add=CAN_USE;            //可以使用加号
                com.num=CAN_USE;
                break;

            case MUL:
                if (com.mul==CANNOT_USE)
                    return ERROR;
            case DIV:
                if (com.div==CANNOT_USE)
                    return ERROR;

                Single_CANNOT_USE();        //如果遇到乘除运算符号,则该符号不能连续使用
                com.point=WAIT_USE;
                com.num=CAN_USE;
                break;

            case POINT:
                if (com.point==CAN_USE)
                {
                    Single_CANNOT_USE();                //小数点后面不能直接跟运算符号
                    com.left_parentheses=CANNOT_USE;    //左括号不能使用
                    com.right_parentheses=CANNOT_USE;   //右括号不能使用
                    com.point=CANNOT_USE;

                }
                else 
                    return ERROR;
                break;

            case LEFT_PARENTHESES:
                if (com.left_parentheses==CANNOT_USE)
                    return ERROR;

                ++parentheses;                         //记录括号标记个数+1
                Single_CANNOT_USE();                   //不可以使用运算符号
                com.right_parentheses=CANNOT_USE;      //右括号不能使用
                com.sub=CAN_USE;                       //重置可以使用加号
                com.add=CAN_USE;                       //重置可以使用减号
                break; 

            case RIGHT_PARENTHESES:
                if (com.right_parentheses==CANNOT_USE)
                    return ERROR;

                --parentheses;                         //记录括号标记个数-1
                if (parentheses<0)                     //如果括号标记小于0
                    return ERROR;

                Single_CAN_USE();                      //可以使用运算符号
                com.num=CANNOT_USE;                    //右括号右端不能使用数字
                break;

            case ERROR:
                return ERROR;

            default :
                return ERROR;
        } 

        t_ch=p->c;   //记录暂存单元
    }
    
    cc=Find_Single(t_ch,&ch,&level);

    if (t_ch!='\0'&&cc!=NUMBER&&cc!=RIGHT_PARENTHESES)  //考虑尾数不是数字和右括号的情况
        return ERROR;

    if (parentheses!=0)         //如果括号不匹配
        return ERROR;

    return OK;
}

PLtem New_Ltem()        //创建一个项
{
    PLtem p=(PLtem)malloc(LEN_Ltem);

    if (p==NULL)
    {
        puts("创建失败!");
        exit(0);
    }
    memset(p,0,LEN_Ltem);

    return p;
}

PLtem Push_Ltem(PLtem h_ltem,PNode h_node)   //把合法表达式的储存数据转化为浮点型和保存运算符号
{
    PLtem ltem=h_ltem;
    PNode node=h_node;
    int i=0;
    int flag=0;

    char Num_Buff[100]={0};                   //数据缓冲空间

    for (;node->next;i=0)
    {
        while (node->next->next&&isdigit(node->next->c)||(node->next->c=='.'))
        {
            Num_Buff[i++]=node->next->c;
            node=Del_Node(node);
        }

        Num_Buff[i]=node->next->c;
        if (i)
        {
            ltem=ltem->next=New_Ltem();
            ltem->com=NUMBER;
            ltem->date.num=atof(Num_Buff);
            flag=1;
        }
        else if (isdigit(node->next->c)&&flag==0)   //处理尾部读取数据情况
        {
                ltem=ltem->next=New_Ltem();
                ltem->com=NUMBER;
                ltem->date.num=atof(Num_Buff);
                node=Del_Node(node);
        }
        else if (!isdigit(node->next->c))
        {
            ltem=ltem->next=New_Ltem();
            ltem->com=SINGLE;
            Find_Single(node->next->c,&ltem->date.single.c,&ltem->date.single.level);

            node=Del_Node(node);
            flag=0;
        }
        else
            node=Del_Node(node);

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

    return h_ltem;
}

PLtem Del_Ltem(PLtem p)     //删除一个项
{
    PLtem tp=NULL;
    PLtem ttp=p;    

    if (p==NULL||p->next==NULL)
        return NULL;

    tp=p->next;
    p=tp->next;
    free(tp);

    ttp->next=p;

    return ttp;
}

void Print_Ltem(PLtem p)
{
    puts("您输入的表达式为:");

    while (p=p->next)
    {
        if (p->com==NUMBER)
            printf("%g",p->date.num);
        else
            printf("%c",p->date.single.c);
    }

    puts("");
}

PLtem Del_Parentheses(PLtem h_ltem)  //去括号
{
    PLtem p1=h_ltem->next;
    PLtem p2=h_ltem->next;

    double temp=0;

    int this_single=0;          //判断正负号
    COM flag=WAIT_USE;
    COM flag2=WAIT_USE;

    while (p1=p2=h_ltem->next)
    {
        flag2=WAIT_USE;            //判断有没有消除括号
        while (p1&&p2)
        {
            p1=p2;                //每次p1和p2两个指针对齐
            this_single=0;        //判断正负号标记初始化为0
            flag=WAIT_USE;        //消除括号条件待定成立
            
            if (p2->com==NUMBER)  //如果是数字就继续移动
            {
                 p2=p2->next;
                continue;
            }

            if (p2->date.single.c!='(')  //如果是运算符号但不是左括号也继续移动
            {
                p2=p2->next;
                continue;
            }

            while (p1->com!=SINGLE||p1->date.single.c!=')')  //当遇到左括号时,要判断里面是否只有一个常数
            {
                p1=p1->next;

                if (p1->com==SINGLE&&p1->date.single.c=='-')  //用来判断正负号
                    this_single=!this_single;

                if (p1->com==SINGLE&&p1->date.single.c=='(')  //意味着这里面不是最内层括号
                    break;

                if (p1->com==NUMBER&&flag==WAIT_USE)
                {
                    temp=p1->date.num;
                    flag=CAN_USE;
                }
                else if (p1->com==NUMBER&&flag!=WAIT_USE)
                    flag=CANNOT_USE;
            }

            if (p1->com==SINGLE&&p1->date.single.c=='(')
            {
                p2=p1;
                continue;
            }

            if (flag!=CAN_USE)   //如果里面不只一个常数意味着不可以删除可以删除
            {
                p2=p1;
                continue;
            }

            if (this_single)   //这条件成立意味着里面是一个负数
                temp=-temp;

            p2->com=NUMBER;    //把左括号的位置换成数字    
            p2->date.num=temp; //赋值给这个位置

            while (p2->next!=p1)
                p2=Del_Ltem(p2);

            p2=Del_Ltem(p2);
            p1=p2;

            flag2=CAN_USE;
        }

        if (flag2!=CAN_USE)
            break;
    }

    return h_ltem;
}

PLtem Count_Mul_Div(PLtem h_ltem)                //计算乘除运算
{
    PLtem p1=h_ltem->next;

    while (p1->next)
    {
        if (p1->com==NUMBER&&p1->next->com==SINGLE&&p1->next->date.single.c=='*'&&p1->next->next->com==NUMBER)
        {
            p1->date.num*=p1->next->next->date.num;
            p1=Del_Ltem(p1);
            p1=Del_Ltem(p1);

            continue;
        }

        if (p1->com==NUMBER&&p1->next->com==SINGLE&&p1->next->date.single.c=='/'&&p1->next->next->com==NUMBER)
        {
            p1->date.num/=p1->next->next->date.num;
            p1=Del_Ltem(p1);
            p1=Del_Ltem(p1);

            continue;
        }

        p1=p1->next;
    }

    return h_ltem;
}

PLtem Count_Add_Sub(PLtem h_ltem)                //计算加减法运算
{

    PLtem p1=h_ltem->next;

    int flag=0;

     while (p1->next)      
    {
        if (p1->com==NUMBER||p1->next->com==NUMBER)  
        {
            p1=p1->next;
            continue;
        }

        if (p1->date.single.c!='+'&&p1->date.single.c!='-')
        {
            p1=p1->next;
            continue;
        }

        while (p1->next->com==SINGLE&&(p1->next->date.single.c=='+'||p1->next->date.single.c=='-'))
        {
            if (p1->next->date.single.c=='-')
                flag=!flag;

            p1=Del_Ltem(p1);
        }

        if (flag&&p1->date.single.c=='+')
            p1->date.single.c='-';
        else if (flag)
            p1->date.single.c='+';

        p1=p1->next;

    }

    p1=h_ltem->next;

    while (p1->next)
    {

        if (p1->com==NUMBER&&p1->next->com==SINGLE&&p1->next->date.single.c=='+'&&p1->next->next->com==NUMBER)
        {
            p1->date.num+=p1->next->next->date.num;
            p1=Del_Ltem(p1);
            p1=Del_Ltem(p1);

            continue;
        }

        if (p1->com==NUMBER&&p1->next->com==SINGLE&&p1->next->date.single.c=='-'&&p1->next->next->com==NUMBER)
        {
            p1->date.num-=p1->next->next->date.num;
            p1=Del_Ltem(p1);
            p1=Del_Ltem(p1);

            continue;
        }

        p1=p1->next;
    }

    return h_ltem;
}


[此贴子已经被作者于2017-3-24 12:46编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-03-23 05:26
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
回复 4楼 rjsp
我还是尴尬一下那个网址我不知道什么原因用手机和电脑均不能链接上去啊~不知道有没有人上过去了~~

不过无论如何还是感谢大佬~~~

[此贴子已经被作者于2017-3-23 13:13编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-03-23 13:11
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
回复 6楼 rjsp
这个要慢慢消化才行~先收藏~

顺便也回xzlxzlxzl感觉有很大的优化空间~看来还要学的东西还有很多~

[此贴子已经被作者于2017-3-24 00:46编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-03-24 00:37
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
二楼已经更新完整~第一次做~没咋参考资料自己想的~感觉还好~到时看了相关算法后感觉还有很大的提升空间~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-03-24 00:39
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
回复 10楼 邹特强
typedef enum COM这只是一个自定义的变量类型~名称可以自己改的~就是看过有些程序那些菜单命令用COM变量名我就跟着用了~没啥特别的含义~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-03-24 13:13
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
回复 12楼 Alien_Lee
我的做法比较直接~没咋技术含量就是考虑各种可能出错的情况然后进行条件约~感觉没什么好说的~

因为规矩不是现成可以提供直接判断的~只能自己写规矩~具体点就是判断每个运算符后面跟什么是合法的什么是非法的~进行条件一一约束就行了~

[此贴子已经被作者于2017-3-24 23:52编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-03-24 23:49
快速回复:如果检验一个输入的"常量表达式"是否合法~
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.031973 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved