| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1084 人关注过本帖
标题:练习题6
只看楼主 加入收藏
lz1091914999
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:四川
等 级:贵宾
威 望:37
帖 子:2011
专家分:5959
注 册:2010-11-1
结帖率:94.64%
收藏
已结贴  问题点数:100 回复次数:17 
练习题6
在stdin输入一行数字表达试,写代码计算这个表达式的值,可以有 '+' '-' '*' '/' 四种运算,没有优先级,也就是从左往右计算。
如:
输入:3 * 4 / 2 + 9
输出:15.000000

输入:-1 + 3 - 4 * 9
输出:-18.000000

不知道voidx去干什么了,练习5的贴也没有结,现在我出一道题吧。

参考答案:
程序代码:
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <float.h>

#ifndef NULL
#define NULL ((void *)0)
#endif

#define EXP_LENGTH          102         /* 表达式的长度 */
#define SUB_EXP_DIG         LDBL_DIG    /* 子表达式结果的有效位数 */
#define is_operator(ch)     ((ch) == '+' || (ch) == '-' || (ch) == '*' || (ch) == '/')

typedef double element_type;            /* 元素值类型 */
typedef long double result_type;        /* 结果值类型 */

static char      exp[EXP_LENGTH];
static int       exp_offset = 0;

typedef struct {
    element_type    left_val;           /* 操作数左值 */
    char            op;                 /* 操作符 */
    element_type    right_val;          /* 操作数右值 */
} sub_exp;

void read(void);

result_type calcing(void);

sub_exp * next_exp(sub_exp * pse);

result_type exp_val(sub_exp * pse);

void read(void) {
    fgets(exp, EXP_LENGTH, stdin);
}

result_type calcing(void) {
    result_type result = 0.0L;
    sub_exp se = {0.0L, '\0', 0.0L}, * pse;
    result = next_exp(&se) ? exp_val(&se) : se.left_val;
    while(pse = next_exp(&se)) {
        switch (pse->op) {
        case '+':
            result += pse->right_val;
            break;
        case '-':
            result -= pse->right_val;
            break;
        case '*':
            result *= pse->right_val;
            break;
        case '/':
            result /= pse->right_val;
            break;
        }
    }
    return result;
}

sub_exp * next_exp(sub_exp * pse) {
    int i = exp_offset, j;
    char left_str[SUB_EXP_DIG + 2];
    char right_str[SUB_EXP_DIG + 2];
    for (j = 0; j < SUB_EXP_DIG + 1; i++)
        if (isdigit(exp[i]) || (exp[i] == '.' && j))
            left_str[j++] = exp[i];
        else if ((exp[i] == '-' || exp[i] == '+') && !j)
            left_str[j++] = exp[i];
        else if (isspace(exp[i]) && exp[i] != '\n' && !j)
            continue;
        else
            break;
    left_str[j] = '\0';
    pse->left_val = atof(left_str);
    for (; ; i++)
        if(isspace(exp[i]) && exp[i] != '\n')
            continue;
        else if(is_operator(exp[i]))
            break;
        else
            return NULL;
    pse->op = exp[i++];
    exp_offset = i;
    for (j = 0; j < SUB_EXP_DIG + 1; i++)
        if (isdigit(exp[i]) || (exp[i] == '.' && j))
            right_str[j++] = exp[i];
        else if ((exp[i] == '-' || exp[i] == '+') && !j)
            right_str[j++] = exp[i];
        else if (isspace(exp[i]) && exp[i] != '\n' && !j)
            continue;
        else if ((exp[i] == '\n' || exp[i] == '\0') && !j)
            return NULL;
        else
            break;
    right_str[j] = '\0';
    pse->right_val = atof(right_str);
    return pse;
}

result_type exp_val(sub_exp * pse) {
    result_type result = 0.0L;
    switch (pse->op) {
    case '+':
        result = pse->left_val + pse->right_val;
        break;
    case '-':
        result = pse->left_val - pse->right_val;
        break;
    case '*':
        result = pse->left_val * pse->right_val;
        break;
    case '/':
        result = pse->left_val / pse->right_val;
        break;
    }
    return result;
}

int main(void) {
    read();
    printf("%Lf", calcing());
    return 0;
}

数字之间可能会有空格,所以有些朋友的答案不对,不过参与就有分。


[ 本帖最后由 lz1091914999 于 2011-7-3 16:38 编辑 ]
搜索更多相关主题的帖子: 回到过去 表达式 优先级 
2011-07-02 15:27
hjywyj
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:3
帖 子:1114
专家分:2611
注 册:2010-4-14
收藏
得分:0 
额,要是没有优先级,那用字符串就可以。
2011-07-02 15:41
刘定邦
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
帖 子:687
专家分:1570
注 册:2010-9-21
收藏
得分:5 
不会。来学习一下。
2011-07-02 16:56
loveshuang
Rank: 9Rank: 9Rank: 9
来 自:湖北武汉
等 级:蜘蛛侠
帖 子:270
专家分:1198
注 册:2010-11-14
收藏
得分:5 
      这个的话栈都不需要了,直接一个字符串加保存结果的浮点型数组就OK了
2011-07-02 17:09
q279838089
Rank: 2
等 级:论坛游民
帖 子:16
专家分:21
注 册:2011-6-22
收藏
得分:5 
可以限制输入多少个运算符吗?
2011-07-02 17:19
夜叶
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:104
专家分:189
注 册:2011-5-7
收藏
得分:5 
有点像简单的计算器原理,每次判断字符是不是运算符号,是就跳转到相应的开关语句进行运算。保存结果继续。
2011-07-02 17:28
oszc
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:111
专家分:154
注 册:2011-4-15
收藏
得分:20 
以前编的,稍微改改又能拿分了,真爽
P.S. gcc里面要链接-lm, e.g. gcc bccn.c -lm

程序代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#include<math.h>
struct stackNode {
    char data;
    struct stackNode *nextPtr;
};            

typedef struct stackNode StackNode;
typedef StackNode *StackNodePtr;

void luanlai(StackNodePtr *topPtr , char infix[],int j,char postfix[]) ;

void convertToPostfix(char infix[], char postfix[]);
int isOperator (char c);
int isNumber (char c);
int precedence (char operator1, char operator2);
void push(StackNodePtr *topPtr, char value);  
char pop (StackNodePtr *topPtr); 

 int isEmpty (StackNodePtr topPtr);
void pushNum(StackNodePtr *head, StackNodePtr *tailer, char value); 
int popNum(StackNodePtr *head, StackNodePtr *tailer);
void printArray ( char a[]);  /*打印数列*/

struct stackPostfix {
    double data;
    struct stackPostfix *nextPtr;
};            

typedef struct stackPostfix StackPostfix; 
typedef StackPostfix * StackPostfixPtr;

void pushPostfix(StackPostfixPtr *headPtr, double value); 
double popPostfix(StackPostfixPtr *headPtr ); 
double evaluatePostfixExpression ( char a[]);
double calculate ( double op1 , double op2 , char operate);
void print(StackPostfixPtr headPtr); 
int normal;//正常计算期值为1,无优先级为2
void whichCalculator(int *a);

int main(void)
{
    int c;
    int counter = 1;    //fllush (stdin)
    whichCalculator(&normal);

    while(1)
    {  
    char infix[1001]={'\0'},postfix[1001]={'\0'};    
    printf("\n> ");

    if(counter==1){
    while( (c=getchar() ) !='\n' && c!= EOF);
    counter++;
    } 


    gets(infix);

    convertToPostfix( infix, postfix);  
    
    // printArray (postfix); 输出逆波兰表达式

    printf("\t%lf",evaluatePostfixExpression(postfix));  
    printf("\n");
    }
    return 0;

}

void convertToPostfix(char infix[], char postfix[])
{
    int i; 
    int j;
    StackNodePtr head=NULL;             
    StackNodePtr tailer=NULL;             
    StackNodePtr topPtr=NULL;            
    char forPop[2]={0};                        
    char forPopNum[2]={0};                
    

    for(i = 0; infix[i]!='\0' ; i++);            
    infix[i]=')';
    infix[i+1] = '\0';                            
    push(&topPtr,'(');

    for (j=0; infix[j]!='\0'; j++)
    {
        if(isNumber(infix[j]))            
            pushNum(&head, &tailer, infix[j]);
         
        else if(infix[j]=='(')
        {
            push(&topPtr,'(');
            pushNum(&head,&tailer,'0');
        }
        
         
        else if(isOperator(infix[j])) 
                                            
        {
            while(head != NULL)
            {
                forPopNum[0] = popNum(&head,&tailer);
                forPopNum[1] = '\0';
                strcat( postfix,forPopNum );
            }
            strcat( postfix," ");            

             luanlai(&topPtr ,  infix,j,postfix) ;
    
            push(&topPtr, infix[j]);            
        }

               else if(infix[j]==')')  
        {
            while(head!=NULL)
                {
                    forPopNum[0] = popNum(&head,&tailer);
                    forPopNum[1] = '\0';
                    strcat( postfix,forPopNum);
                }
            strcat( postfix," ");
            
            
            while( (forPop[0] = pop(&topPtr) )!= '(')
            {
                forPop[1]='\0';
                strcat( postfix,forPop );
                strcat( postfix," " );
            }            
    }
    }
}

int isOperator (char c)
{
    if ( c == 43 || c == 45 || c == 42 || c ==  47 || c == 94 || c == 37 )
        return 1;
    else
        return 0;
}

int isNumber (char c)
{
    if( isdigit(c) ||c==46 )
        return 1;
    else 
        return 0;
}

int precedence (char operator1, char operator2)
{
    int i;
    int temp[2][2]={{operator1, operator2},{0}};

    for(i = 0;i<2 ; i ++)
    {
        switch (temp[0][i])
        {
            case 43:
            case 45:
                temp[1][i]=normal; //normal =1
                break;
            case 42:
            case 47:
            case 94:
            case 37:
                temp[1][i]=2;
                break;
            case 40:
            case 41:
                temp[1][i]=-1;
                break;

        }
    }
    return temp[1][1]-temp[1][0];
}

void push(StackNodePtr *topPtr, char value)
{
    StackNodePtr newPtr;
    if( (newPtr=(StackNodePtr) malloc (sizeof( struct stackNode) ) )!= NULL)
    {
        newPtr->data=value;
        newPtr->nextPtr=NULL;

        if( *topPtr ==NULL)
        {
            *topPtr=newPtr;    
        }
        else
        {
            newPtr->nextPtr=*topPtr;
            *topPtr=newPtr;
        }
    }
    else
    {
        printf("NOT ENOUGH MEMORY\n");
    }
}

char pop (StackNodePtr *topPtr)
{
    StackNodePtr tempPtr;
    char value;

    if(*topPtr ==NULL)
    {
        printf("EMPTY\n");
        exit(1);
    }
    else
    {
        tempPtr = (*topPtr);
        value= tempPtr->data;
        (*topPtr)=(*topPtr)->nextPtr;
        free(tempPtr);
        return value;
    }
}
void pushNum(StackNodePtr *head, StackNodePtr *tailer, char value)
{
    StackNodePtr newPtr;
    if( (newPtr=(StackNodePtr) malloc (sizeof( struct stackNode) ) )!= NULL)
    {
        newPtr->data=value;
        newPtr->nextPtr=NULL;
        if( *head==NULL)
        {
            (*head) = newPtr;
        }
        else
        {
            (*tailer)->nextPtr= newPtr;
        }
        (*tailer)= newPtr;
    }
}
int popNum(StackNodePtr *head, StackNodePtr *tailer)
{
    int value;
    StackNodePtr tempPtr;

    if( head !=NULL)
    {
        value = (*head)->data;
        tempPtr = *head;
        *head = (*head)->nextPtr;
        free(tempPtr);
        if(*head ==NULL)
            *tailer=NULL;
        return value;
    }
}
int isEmpty (StackNodePtr topPtr)
{
    if (topPtr==NULL)
        return 1;
    else 
        return 0;
}
void printArray ( char a[])
{
    int i;
    for (i=0; a[i]!='\0'; i++ )
        printf("%c", a[i]);
}
double evaluatePostfixExpression ( char a[])
{
    char b[]=" "; 
    char *token;
    StackPostfixPtr headPtr=NULL;
    double x=0.00;
    double y=0.00;

    token = strtok( a, b);

    while (token != NULL)
    {
        if(isNumber( *token ) )
        {
            pushPostfix( &headPtr, atof(token) );
        }
        else 
        {
            x=popPostfix( &headPtr );

            y=popPostfix( &headPtr );
    
            pushPostfix(&headPtr,calculate( x , y , (*token) ) );    
        }
        token =strtok (NULL , b);
    }
    return popPostfix(&headPtr);
}

void pushPostfix(StackPostfixPtr *headPtr, double value)
{
    StackPostfixPtr newPtr;
    if( (newPtr=(StackPostfixPtr) malloc (sizeof( struct stackPostfix) ) )!= NULL)
    {
        newPtr->data=value;
        newPtr->nextPtr= *headPtr;
        *headPtr = newPtr;
    }
    else
    {
        printf("NOT ENOUGH MEMORY\n");
    }
}
double popPostfix(StackPostfixPtr *headPtr )
{
    StackPostfixPtr tempPtr;
    double value;

    if( (*headPtr)  ==NULL)
    {
        return 0;
    }
    else
    {
        tempPtr = (*headPtr);
        value= tempPtr->data;
        (*headPtr)=(*headPtr)->nextPtr;
        free(tempPtr);
        return value;
    }
}

double calculate ( double op1 , double op2 , char operate)
{
    switch (operate)
    {
    case 43:
        return op1+op2;
    case 45:
        return op2-op1;
    case 42:
        return op2*op1;
    case 47:
        return (double)op2/op1;
    case 94:
        return pow(op2,op1);
    case 37:
        return (int)(op2)%(int)(op1);
    }
    return 0;
}
void luanlai(StackNodePtr *topPtr , char infix[],int j,char postfix[]) 
{
    char forPop[2]={'\0'};

     forPop[0] = pop(topPtr);  
     forPop[1]='\0';
    if( (precedence(infix[j], forPop[0]))==1  || (precedence(infix[j], forPop[0]))==0) 
        {
            strcat( postfix,forPop );
            strcat( postfix," ");
        
             luanlai(topPtr ,  infix,j,postfix) ;
            }
        else 
            push( topPtr, forPop[0]);        
}
void print(StackPostfixPtr headPtr)
{
    if(headPtr ==NULL)
    {
        printf("empty");
    }
    else
    {
        printf("\nthe stack is:\n");

        while(headPtr !=NULL)
        {
            printf( "%lf-->", headPtr->data);
            headPtr=headPtr->nextPtr;
        }
    }
    printf("NULL\n\n");
}
void whichCalculator(int *a)
{
    int c;

    while(*a!=1 && *a!=2)
    {
        printf("Select:\n");
        printf("1. normal calculator\n");
        printf("2. ignore precedence\n? ");
        scanf("%d",a);
        if(     (!    (isdigit(*a) ) ) && (*a!=1 &&*a!=2) )
        {
            printf("\n*** Error: select 1 or 2! ***\n\n"    );
            while( (c=getchar() ) !='\n' && c!=EOF);
            whichCalculator(a);
            break;
        }
    }
}
calculator.rar (3.31 KB)
calculator.zip (3.42 KB)


[ 本帖最后由 oszc 于 2011-7-3 00:55 编辑 ]
2011-07-03 00:39
hjywyj
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:3
帖 子:1114
专家分:2611
注 册:2010-4-14
收藏
得分:5 
#include<stdlib.h>
int main()
{system("start calc");
return 0;}
来接分


2011-07-03 06:40
周1992
Rank: 2
等 级:论坛游民
帖 子:70
专家分:60
注 册:2011-3-18
收藏
得分:5 
#include "stdio.h"
char x;
void main()
{
   int n;float sum;
   scanf ("%f",&sum);
   for (;;)
   {
           scanf ("%c",&x);
           if (x=='\n') break;
           scanf ("%d",&n);
           switch (x)
           {
               case ('+'): sum=sum+n;break;
               case ('-'): sum=sum-n;break;
               case ('*'): sum=sum*n;break;
               case ('/'): sum=sum/n;break;
           }
   }
   printf ("%.6f\n",sum);
}
2011-07-03 10:59
周1992
Rank: 2
等 级:论坛游民
帖 子:70
专家分:60
注 册:2011-3-18
收藏
得分:0 
[quote]以下是引用hjywyj在2011-7-3 06:40:22的发言:

#include<stdlib.h>
int main()
{system("start calc");
return 0;}
  
system("start calc")请问这个是什么意思?
2011-07-03 11:00
快速回复:练习题6
数据加载中...
 
   



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

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