QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: whlvme

编程大赛(试刊号)——计算器出来啦

[复制链接]
发表于 2003-7-11 10:54:30 | 显示全部楼层
Dev-C++
I like it
I use it 
回复

使用道具 举报

发表于 2003-7-11 21:40:43 | 显示全部楼层
[quote:4c5ffade3d="Kan"]实现256位的2个数相加?各位试试![/quote]
这有点简单
只要设定两个257的数组就可以了的,
甚至可以用汇编来实现,效率更高
还是相加的
我做过一道题目
求一个数的阶乘
这个数要大于1000
不如试一试我这道?
回复

使用道具 举报

发表于 2003-7-12 23:21:02 | 显示全部楼层
有谁把计算器做出来的?
whlvme
什么时候写出来啊,我可等着看呢
我看我明天能不能完成了
后天就要回家避暑了
就没有时间上网了
回复

使用道具 举报

发表于 2003-7-13 00:16:29 | 显示全部楼层
So easy function, use C++? My god!

[quote:0a30851cf4="sjinny"]晕,竟然没法上传附件,我把代码贴出来吧:
[code:1]
#include <iostream>
#include <stdlib.h>

using namespace std;

int main(int argc, char *argv[])
{
    double a,b,s=0.0;
    int state=1;
    char m='e';
   
    cout<<"请输入:"<<endl;
    cin>>a;
    s=a;
   
    while(state==1){
        cin>>m;
        switch(m){
                case '=':
                                cout<<"计算结果为: "<<s<<endl<<endl;
                                cout<<"请输入:"<<endl;
                                cin>>a;
                                s=a;
                                continue;
                                break;
                case 'e':
                                cout<<"计算结果为: "<<s<<endl;
                                cout<<"Bye~  ^_^"<<endl<<endl;
                                state=0;
                                continue;
                                break;
                default:
                                break;
        }
        cin>>b;
        switch(m){
                case '+':
                                s=a+b;
                                a=s;
                                break;
                case '-':
                                s=a-b;
                                a=s;
                                break;
                case '*':
                                s=a*b;
                                a=s;
                                break;
                case '/':
                                s=a/b;
                                a=s;
                                break;
                default:
                                break;
        }
    }

  system("PAUSE");       
  return 0;
}
[/code:1][/quote]
回复

使用道具 举报

 楼主| 发表于 2003-7-13 09:58:50 | 显示全部楼层
我的正在写呢。表达式检查和二叉树计算已写,就剩下将表达式装入二叉树了。

atfa也写一个啊。
回复

使用道具 举报

 楼主| 发表于 2003-7-13 12:23:42 | 显示全部楼层
简单算术计算器[code:1]
/***Simple Calculater
*Author:whlvme
*Version:0.1
*Copyleft(GPL)linuxfans.org
***/
#include <stdio.h>
#include <stdlib.h>

struct st_calc_node
{
        char calc_method;/*运算类型:'+','-','*','/' */
        struct st_calc_node * left;
        struct st_calc_node *right;
        double result;
        int calculated;/*是否已经计算*/
};
typedef struct st_calc_node calc_node;

calc_node * root_node;

int IsValidChar(char ch)
{
        if(isdigit(ch))return(1);
        if(isalpha(ch))return(0);
        if(ch=='+') return(1);
        if(ch=='-') return(1);
        if(ch=='*') return(1);
        if(ch=='/') return(1);
        if(ch=='(') return(1);
        if(ch==')') return(1);
        if(ch=='.') return(1);
        return(0);
}

int IsFormularValid(char * fmlr)
{
        char *ptr;
        int i=0;

/*字符检查:限定数字、运算符、括号、小数点*/
        ptr=fmlr;
        while(ptr[i])
        {
                if(!IsValidChar(ptr[i]))
                        return(0);
                else
                        i++;
        }

/*将表达式装入二叉树:中间出错返回0*/
/*这段代码,我不会啦,哪位加上?*/
        return(1);
}

int node_calculate(calc_node *nd)
{
        /*如果节点是单纯的操作数,则其左右子节点为空,无需计算,直接返回*/
        if(nd->left==NULL||nd->right==NULL) return(1);
        /*计算子节点:出错则返回0*/
        if(!nd->calculated)
        {
                if(!node_calculate(nd->left))return(0);
                if(!node_calculate(nd->right))return(0);
        }

        switch(nd->calc_method)
        {
                case '+':nd->result=nd->left->result+nd->right->result;
                        nd->calculated=1;
                        break;
                case '-':nd->result=nd->left->result-nd->right->result;
                        nd->calculated=1;
                        break;
                case '*':nd->result=nd->left->result*nd->right->result;
                        nd->calculated=1;
                        break;
                case '/':if(nd->right==0)return(0);/*若除数为0则返回0,代表计算出错*/
                        nd->result=nd->left->result/nd->right->result;
                        nd->calculated=1;
        }
        return(1);
}

double FormularCalc(char * fmlr)
{
        return strlen(fmlr)*3.14156;/*for test*/
/*
        if(!node_calculate(root_node))
        {
                printf("\nError ocurs during calculating:divive by zero");
                return(-1);
        }
        return(nd->result);
*/
}

main()
{
        char * fml;
        printf("Welcomt to Simple Calculater!\n");
        while(1)
        {
                printf("\nInput a formular(\"exit\" to exit):");
                scanf("%s",fml);
                if(!strcmp(fml,"exit"))
                        break;
                else if(!IsFormularValid(fml))
                        printf("Invalid formular.");
                else
                        printf("%f",FormularCalc(fml));
        }
        printf("\nGood bye!\n");
}

[/code:1]
以上程序在Magic Linux 1.1Final+gcc 3.2.2 20030313上编译通过。将表达式装入二叉树的代码没有写,所以计算结果用表达式长度乘圆周率代替。
以上程序有什么问题?请大家评评。
哪位高手把表达式装入二叉树的代码写出来萨。
回复

使用道具 举报

发表于 2003-7-13 13:01:37 | 显示全部楼层
char * fml;
......
scanf("%s",fml);

不会出问题吗?
回复

使用道具 举报

 楼主| 发表于 2003-7-13 13:24:40 | 显示全部楼层
没问题,经过运行测试了的。

scanf本来就是使用指针作为参数的。而fml也定义的是指针啊。

int num;

scanf("%d",&num);

这里也是使用指针,因为num不是用指针方式定义的,所以要取其地址。
回复

使用道具 举报

发表于 2003-7-13 15:57:06 | 显示全部楼层
[code:1]
/*......calculator.......
   author:hibernate
   compile:in visual c++ and pass
   input:illegal expression,including '+','-','*','/','sin','cos','tan' and 'ctg'
   output:the result
   ......addition:It is a simple calculator,and there must be many bugs
         If you find,please point them out.And you can email me:
         My email:[email protected]
   ......ends........
*/
#include"math.h"
#include"stdlib.h"
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#define Size 50
#define sm 200
int Error1=0;
int precedent(char op);
int judge2(char ch);
double change(char* s1, char* s2);
//定义一个栈类,实现一个基本功能
template <typename T>
class Stack  
{
private:
                int size;
                int top;
                T* list;
        public:
                Stack()
                {
                        size=sm;top=0;list=new T[size];
                }
                ~Stack(){delete []list;}
                void push(const T &item)
                {
                        list[top++]=item;
                }
                bool isempty()
                {
                        return top==0;
                }
                T pop()
                {
                        return list[--top];
                }
                T topvalue()
                {
                        return list[top-1];
                }
                void clean()
                {
                        top=0;
                }

};
/*
功能描述:计算出操作数的值
参数说明:为操作数的原始字符串
返回值:操作数的值,double类型
*/
double compute1(char *a)
{
        bool sign=false;
    bool point=false;
        int i=0;
        int type;
        int power=0;
        double reval=0;
        char *temp=(char *)calloc(Size,sizeof(char));
        char *temp1=(char *)calloc(Size,sizeof(char));
        if(a[i]=='-')
        {
                sign=true;
                i++;
        }
        for(;i<(int)strlen(a);i++)
        {
                type=judge2(a[i]);
                if(type==1)
                        if((a[0]=='-'&&i==1)||i==0)
                        {
                                Error1=-1;
                                printf("Error1: some '.' shouldn't be placed there!Please check it!\n");
                                return -1;
                        }
                        else
                                point=true;
                else if(type==2)
                {
                        reval=reval*10+(a[i]-'0');
                        if(point)
                                power++;
                }
                else if(type==3)
                {
            if((a[i+1]=='i'||a[i+1]=='I')&&(a[i+2]=='n'||a[i+2]=='N')&&a[i+3]=='(')
                        {
                                i=i+4;
                                int left=1,right=0;
                                double value;
//                                char *temp=(char *)calloc(Size,sizeof(char));
//                                char *temp1=(char *)calloc(Size,sizeof(char));
                                for(int j=0;j<Size;j++)
                                {
                                        if(a[i]=='(')
                                                left++;
                                        else if(a[i]==')')
                                                right++;
                                        if(right==left)
                                                break;
                                        temp[j]=a[i++];
                                }
                                temp[j++]='@';
                                temp[j]='\0';
                                if(j>Size)
                                {
                                        Error1=-2;
                                        printf("Error1:in the sin insides is too long!\n");
                                        return -1;
                                }
                                value=change(temp,temp1);
                                reval=sin(value);
                        }
                        else
                        {
                                Error1=-1;
                                printf("Error1:no sign like this:%c%c%c!\n",a[i],a[i+1],a[i+2]);
                                return -1;
                        }
                }
                else if(type==4)
                {
            if(((a[i+1]=='o'||a[i+1]=='O')&&(a[i+2]=='s'||a[i+2]=='S')&&a[i+3]=='(')||
                           ((a[i+1]=='t'||a[i+1]=='T')&&(a[i+2]=='g'||a[i+2]=='G')&&a[i+3]=='('))
                        {
                                char ch=a[i+1];
                                i=i+4;
                                int left=1,right=0;
                                double value;
//                                char *temp=(char *)calloc(Size,sizeof(char));
//                                char *temp1=(char *)calloc(Size,sizeof(char));
                                for(int j=0;j<Size;j++)
                                {
                                        if(a[i]=='(')
                                                left++;
                                        else if(a[i]==')')
                                                right++;
                                        if(right==left)
                                                break;
                                        temp[j]=a[i++];
                                }
                                temp[j++]='@';
                                temp[j]='\0';
                                if(j>=Size)
                                {
                                        Error1=-2;
                                        if(ch=='o'||ch=='O')
                                                printf("Error1:in the cos insides is too long!\n");
                                        else
                                                printf("Error1:in the ctg insides is too long!\n");
                                        return -1;
                                }
                                value=change(temp,temp1);
                                if(ch=='o'||ch=='O')
                                        reval=cos(value);
                                else
                                {
                                        value=tan(value);
                                        if(value==0)
                                        {
                                                Error1=3;
                                                printf("Error1:the ctg argument value shouldn't be 0!\n");
                                                return -1;
                                        }
                                        else
                                                reval=1/value;
                                }

                        }
                        else
                        {
                                Error1=-1;
                                printf("Error1:no sign like this:%c%c%c\n",a[i],a[i+1],a[2]);
                                return -1;
                        }
                }
                else if(type==5)
                {
            if((a[i+1]=='a'||a[i+1]=='A')&&(a[i+2]=='n'||a[i+2]=='N')&&a[i+3]=='(')
                        {
                                i=i+4;
                                int left=1,right=0;
                                double value;
//                                char *temp=(char *)calloc(Size,sizeof(char));
//                                char *temp1=(char *)calloc(Size,sizeof(char));
                                for(int j=0;j<Size;j++)
                                {
                                        if(a[i]=='(')
                                                left++;
                                        else if(a[i]==')')
                                                right++;
                                        if(right==left)
                                                break;
                                        temp[j]=a[i++];
                                }
                                temp[j++]='@';
                                temp[j]='\0';
                                if(j>=Size)
                                {
                                        Error1=-2;
                                        printf("Error1:int the tan insides is too long!\n");
                                        return -1;
                                }
                                value=change(temp,temp1);
                                reval=tan(value);
                        }
                        else
                        {
                                Error1=-1;
                                printf("Error1:no sign like this:%c%c%c!\n",a[i],a[i+1],a[2]);
                                return -1;
                        }
                }
                else
                {
                        Error1=4;
                        printf("Error1:some sign like %c can't be recognized!\n",a[i]);
                        return -1;
                }
        }
        reval/=pow(10,power);
        if(sign)
                reval=-reval;
        free(temp);
        free(temp1);
        return reval;
};
/*功能说明:用来判别字符的类型
参数说明:传入要判断的字符
返回类型:返回字符的类型(自己定义)int类型
*/
int judge2(char ch)
{

        if(ch=='.')
                return 1;
        else if(ch>='0'&&ch<='9')
                return 2;
        else if(ch=='s'||ch=='S')
                return 3;
        else if(ch=='c'||ch=='C')
                return 4;
        else if(ch=='t'||ch=='T')
                return 5;
        else return 6;
}
/*功能说明:表达式的计算,实现主要的功能
参数说明:s1 原始表达式字符串,s2 临时字符数组,用来保存后序表达式
返回类型:返回表达式的值 double类型
*/
double change(char* s1, char* s2)
{
        Stack <char> p;
        Stack <double>data1;
        Stack <double>data2;
        p.push('@');//做标记
        double result=-1;
        int i=0,j=0;
        int left,right;
        int n=strlen(s1);
        s2=(char*)malloc(sizeof(char)*n);
        char* temp=(char *)malloc(sizeof(char)*Size);
        int m=0;
        double value;
        char ch=s1[i];
        //......将中序表达式化成后序表达式.......
        if(ch=='-')
        {
                m=0;
                temp[m++]=ch;
                left=right=0;
                while(true)
                {
                        ch=s1[++i];
                        if(left==right&&(ch=='*'||ch=='/'||ch=='+'||ch=='-'))
                                break;
                        else
                                temp[m++]=ch;
                }
                temp[m]='\0';
                value=compute1(temp);
                s2[j++]='#';
                data1.push(value);
        }
        while(i<n-1)
        {
                if(ch==' ')//忽略空格
                        ch=s1[++i];
                else if(ch=='(')//如果是左括号
                {
                        if(s1[i+1]=='-')
                        {
                                left=1;
                                right=0;
                                while(left>right)
                                {
                                        ch=s1[++i];
                                        if(ch=='(')
                                                left++;
                                        else if(ch==')')
                                                right++;
                                        temp[m++]=ch;
                                }
                                temp[m-1]='\0';
                                value=compute1(temp);
                                data1.push(value);
                                s2[j++]='#';
                        }
                        else
                        {
                                p.push(ch);//压栈
                                ch=s1[++i];//继续向后
                        }
                }
                else if(ch==')')//如果是右括号
                {
                        while(p.topvalue()!='(')
                        s2[j++]=p.pop();//把左括号之前的全弹出并加入到后序数组中
                        p.pop();
                        ch=s1[++i];
                }
                else if(ch=='+'||ch=='-'||ch=='*'||ch=='/')//如果是运算符
                {

                        char w=p.topvalue();
                        while(precedent(w)>=precedent(ch))//判断符号的优先级
                        {//如果比栈顶元素的优先级高
                                s2[j++]=w;//把栈顶弹出并加入后序数组
                                p.pop();
                                w=p.topvalue();
                        }
                        p.push(ch);
                        ch=s1[++i];
                }
                else
                {//如果是是操作数
                                m=0;
                                temp[m++]=ch;
                        if(ch<='9'&&ch>='0')
                        {
                                while(true)
                                {
                                        ch=s1[++i];
                                        if(ch==' ')
                                                i++;
                                        else if((ch<='9'&&ch>='0')||ch=='.')
                                                {
                                                       
                                                        temp[m++]=ch;
                                                }
                                                else
                                                        break;
                                }
                        }
                        else
                        {
                                left=right=0;
                                while(true)
                                {
                                        if(ch=='(')left++;
                                        else if(ch==')')right++;
                                       
                                        ch=s1[++i];
                                        if(left==right&&left>0)
                                                break;
                                        temp[m++]=ch;
                                }
                        }
                        temp[m]='\0';
                        printf(".................%s\n",temp);
                        value=compute1(temp);
                        data1.push(value);
                        s2[j++]='#';//直接加入后序数组
                }
               
        }
                ch=p.pop();
               
                while(ch!='@')//把栈内剩余的运算符都弹出并加入后序数组
                {
                    if(ch=='(')
                        {
                 
                                return -1;
                        }
                        else
                        {
                                s2[j++]=ch;
                                ch=p.pop();
                        }
                }
                s2[j]='\0';
                while(!data1.isempty())
                {
                        data2.push(data1.pop());
                }
//......中序表达式计算.......
                {
                        double op1,op2;
                        p.clean();
                        data1.clean();
                        int k=0;
                        for(k=j-1;k>=0;k--)
                                p.push(s2[k]);

                        while(!p.isempty())
                        {
                                ch=p.pop();
                                if(ch=='#')
                                        data1.push(data2.pop());
                                else
                                {
                                        op1=data1.pop();
                                        op2=data1.pop();
                                        switch (ch)
                                        {
                                        case '+': result=op1+op2;break;
                                        case '-': result=op2-op1;break;
                                        case '*': result=op1*op2;break;
                                        case '/': {
                                                if(op1==0)
                                                {
                                                        printf("Error:the divident shouldn't be 0\n");
                                                        Error1=-1;
                                                        return -1;
                                                }
                                                else
                                                        result=op2/op1;
                                                        break;
                                                          }
                                        default: printf("Error:not the recognized operator %c\n",ch);
                                               
                                        }
                                        data1.push(result);
                                }
                        }

                }
                return result;
                               
};

/*功能说明:判断操作符号的优先级别
  参数说明:操作符号字符
  返回值:优先级别 int
*/
int precedent(char op)
{
switch(op)
        {
        case '+':
        case '-':return 1;
        case '*':
        case '/':return 2;
        default:return 0;
        }
};

void main()//测试
{
        double result;
       
        char exp[200];
        char exp1[200];
        char ch;
        for(int m=0;m<20;m++)
        {
                printf("input the expression:");
        for(int i=0;i<200;i++)
        {
                ch=getchar();
                if(ch=='\n')
                        break;
                else
                        exp[i]=ch;
        }
        exp[i++]='@';
        exp[i]='\0';
        result=change(exp,exp1);
        if(Error1<0)
                printf("Error occurs! no rusult,please check......\n");
        else
                printf("the result is %f :\n",result);
        }

}
[/code:1]
回复

使用道具 举报

发表于 2003-7-13 16:50:46 | 显示全部楼层
至少得考虑运算优先级和括号的问题吧
回复

使用道具 举报

发表于 2003-7-13 16:55:56 | 显示全部楼层

Re: 编程大赛(试刊号)——计算器出来啦

对不起,您是南京大学的吗?

[quote:252c4dd609="whlvme"]有人建议组织编程大赛,我就先来出一个题目给大家,作为活动的实验吧。为提高参与性,我出的这个题目相对比较简单,同时也具有一定的应用价值。不知大家对它感不感兴趣。

题目如下:
大家都用过P2P软件吧?这类软件为我们提供了一个分布式文件资源系统,我们可以方便地用它来共享软件、电影、音乐、电子书等等。如果用做分布式协同开发小组,协同开发小组可以不使用集中管理的CVS服务器就可以进行良好地合作。
好了,闲话少说。现在,我们来做一个通信决策程序,现在已经提供一个类CPPComm,封装了UDP协议和数据打包、数据压缩、加密等细节操作,参赛者不需要了解其内部技术细节,只需要设置回调函数指针和调用其方法即可。类的定义如下:
class CPPComm
{
private:
   .....
public:
    int SendMsg(int TargetAddr[4],char * msg);//阻塞模式。成功返回发送的字节数,失败返回0。
  int GetMsg(int FromAddr[4],char * msg);//阻塞模式。成功返回收到的字节数,失败返回0;
  int WriteMsg(int TargetAddr[4],char * msg);//非阻塞模式。成功返回发送的字节数,失败返回0。
  int ReadMsg(int FromAddr[4],char * msg);//阻塞模式。成功返回收到的字节数,失败返回0;   
   void (*OnGotMsg)(int FromAddr[4],char * msg);//收到数据后的响应事件,使用时用自己定义的函数指针设置它。
}
//以上int[4]均为目标主机的IP地址,例如202.101.102.103存储为数组{202,101,102,103}.假设用户的机器都直接和Internet连接,有独立的静态或动态IP.

编程要求:写一个程序,通过调用上面的CPPComm类来模拟P2P软件实现文件共享传输功能(提交共享、搜索文件、下载文件、查询对方资源情况)。可使用但不必编写文件信息索引服务器,只需定义数据和命令格式即可。参赛者主要任务是根据对方机器资源情况和文件存放位置来确定从哪些机器上下载或者自动分布到其他机器上。可以使用也可以不使用多线程。如果需要也可以使用CPPComm的派生类。程序的其他方面设计可以自由发挥。参赛的主题是算法的实现,对有关API不熟者可以使用定义了接口而未实现的类来代替。

欢迎大家讨论和参赛! [/quote]
回复

使用道具 举报

 楼主| 发表于 2003-7-13 18:06:09 | 显示全部楼层

Re: 编程大赛(试刊号)——计算器出来啦

[quote:ef999d3db4="超级用户"]对不起,您是南京大学的吗?[/quote]
我從哪裡可以看出像南京大學的?哈哈,我是公社服務器上的PHP代碼哦,專門負責登陸驗證和智能發帖,就像公社IRC中的fans機器人一樣。
回复

使用道具 举报

发表于 2003-7-13 18:31:43 | 显示全部楼层
我的程序已经考虑到了括号和运算优先级别了
呵呵
回复

使用道具 举报

发表于 2003-7-13 22:15:34 | 显示全部楼层

  这样很不好,不是说比赛的形式不好,这种规划不好!这样一是老是底水平的重复,搞了些低档的东西出来,二是杂乱无张,漫我目的!
   我提议:
    一:问题应分低,中,高三等,用明显的标志标出来,这样可以加快问题的处理速度,速度对我们来说也很重要。
    二;初级的以学习为主,这里主要帮他们学习,中级的通过比赛学习,高级的应该搞项目,创造性的发挥
    三:比赛的内容应该整体规划,争取从中得出成果,比如吧,我们可以编写库函数,在linux下搞个matlab那样功能的库(好象现在还没自由的库),如果一个算法解决了,这个结果就有用了,我们就不再比赛这个题目了,那下个算法再来。。。。。。。其它的库,也可以这样搞,当然要高手规划
回复

使用道具 举报

 楼主| 发表于 2003-7-13 22:33:17 | 显示全部楼层
Good idea.
Thanks!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-15 06:16 , Processed in 0.112598 second(s), 12 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表