刘赟锋

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

题目如上:

 

第一次的功能实现我是用C++写的,队友用的java,后来考虑到UI界面的实现,感觉java比C++更方便,于是转到java,由于对java并不是特别熟悉,所以这次作业也是做的比较艰难。

 

分别负责验证码和UI界面,然后交换查看代码,修改合并

因为都比较菜,所以这个项目算是很艰难,但最后还是完成了。

 

第一点:注册码及向用户手机发送验证码。

 

这个功能需要实现:UI界面,UI界面中文本框数据读取,按钮的监听,验证码生成,向用户发送

 

1.登录界面、文本读取、按钮监听:

 

package uitest;

import java.awt.FlowLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.IOException;

import java.awt.Dimension;

import javax.swing.ImageIcon;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPasswordField;

import javax.swing.JTextField;

 

public class sign extends JFrame implements ActionListener {

String name;

String pswd;

JButton bu=new JButton("登录");//元件的定义

JButton pu=new JButton("注册");

JTextField nametext=new JTextField();

JPasswordField passwordtext=new JPasswordField();

 

 

public sign() {

 

................//界面设计

 

frame.setVisible(true);

 

pu.addActionListener(this);//监听器的添加

bu.addActionListener(this);

 

 

}

 

public void actionPerformed(ActionEvent e) {

// 判断是那个按钮被点击

if (e.getActionCommand().equals("登录")) {

..................................

 

name=nametext.getText();

pswd=passwordtext.getText();//getText()实现文本框数据读取

 

}

 

if (e.getActionCommand().equals("注册")) {

....................

}

跳转

}

 

这部分代码实现登录界面的设计,其中利用getText()实现文本框数据读取,实现按钮监听,关键是需要实现ActionListener接口,调用其中的addActionListener(),如果按钮被按下,则转到另一个界面,或者发送验证码(即运行下一个函数)。

 

2.验证码生成,及发送:

 

服务器我们选择的阿里云,送了100条短信,还算是很良心。阿里云的具体的操作见https://help.aliyun.com/document_detail/55284.html?spm=5176.11065259.1996646101.searchclickresult.5dd24c6cK7cj4l

 

代码如下

 

package uitest;

import com.aliyuncs.DefaultAcsClient;

import com.aliyuncs.IAcsClient;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;

import com.aliyuncs.exceptions.ClientException;

import com.aliyuncs.profile.DefaultProfile;

import com.aliyuncs.profile.IClientProfile;

 

 

public class message {

// 产品名称:云通信短信API产品,开发者无需替换

static final String product = "Dysmsapi";

// 产品域名,开发者无需替换

static final String domain = "dysmsapi.aliyuncs.com";

 

// TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)

static final String accessKeyId = "。。。。。。。。。。";

static final String accessKeySecret = "。。。。。。。。。";

public static SendSmsResponse sendSms(String telephone, String code) throws ClientException {

 

// 可自助调整超时时间

System.setProperty("sun.net.client.defaultConnectTimeout", "10000");

System.setProperty("sun.net.client.defaultReadTimeout", "10000");

 

// 初始化acsClient,暂不支持region化

IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);

DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);

IAcsClient acsClient = new DefaultAcsClient(profile);

 

// 组装请求对象-具体描述见控制台-文档部分内容

SendSmsRequest request = new SendSmsRequest();

// 必填:待发送手机号

request.setPhoneNumbers(telephone);

// 必填:短信签名-可在短信控制台中找到

request.setSignName("小初高数学试卷系统"); // TODO 改这里

// 必填:短信模板-可在短信控制台中找到

request.setTemplateCode("SMS_147196340"); // TODO 改这里

// 可选:模板中的变量替换JSON串,如模板内容为"亲爱的用户,您的验证码为${code}"时,此处的值为

request.setTemplateParam("{\"code\":\"" + code + "\"}");

 

// 选填-上行短信扩展码(无特殊需求用户请忽略此字段)

// request.setSmsUpExtendCode("90997");

 

// 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者

request.setOutId("yourOutId");

 

// hint 此处可能会抛出异常,注意catch

SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);

if(sendSmsResponse.getCode()!= null && sendSmsResponse.getCode().equals("OK")){

System.out.println("短信发送成功!");

}else {

System.out.println("短信发送失败!");

}

return sendSmsResponse;

}

 

//以下为测试代码,随机生成验证码

public static int newcode;

public static int getNewcode() {

return newcode;

}

public static void setNewcode(){

newcode = (int)(Math.random()*9999)+100; //每次调用生成一次四位数的随机数

}

public static void send(String nub) throws Exception {

setNewcode();

String code = Integer.toString(getNewcode());

SendSmsResponse sendSms =sendSms(nub,code);//填写你需要测试的手机号码

System.out.println("短信接口返回的数据----------------");

System.out.println("Code=" + sendSms.getCode());

System.out.println("Message=" + sendSms.getMessage());

System.out.println("RequestId=" + sendSms.getRequestId());

System.out.println("BizId=" + sendSms.getBizId());

 

}

}

 

关键是申请 签名 和模板 ,通过使用 accessKeyId和accessKeySecret访问阿里服务,将电话和验证码发送到服务器上,服务器再发给用户。

 

题目生成及题目答案计算算法

 

首先是题目生成,参数SchoolSeclect代表选择的学校,每一项的产生都会进行随机选择,这里是生成一个函数项,常数项,还是一个括号项(把括号里面的部分当成对象处理)

public class School {

    public int school=0; //项的种类选择

    private double Answer=0;

    private String LIST;

    public double []Aa=new double [20];

        void Vector(int SchoolSeclect)

        {

            int Length=(int)(2+Math.random()*2); 

            Function f=new Function();

            String str="";

            String str1="";

            for(int i=0;i<20;i++)

            {

                Aa[i]=0;

            }

             

                for(int i=0;i<Length;i++)

                {

                  

                  

                       int SecBra=(int)(Math.random()*2);//这一项是否设置为括号项

                       if(SecBra==0)

                           {

                           if(SchoolSeclect==0)

                               school=0;

                           if(SchoolSeclect==1)

                               school=(int)(Math.random()*2);

                           if(SchoolSeclect==2)

                               school=(int)(Math.random()*3);

                          

                               f.Vector(school);

                               str+=f.getFUNCTION();

                               Aa[i]=f.getVALUEOFFUNCTION();

                           }

                       else

                           {

                            

                               Bracket b=new Bracket();

                               b.Vector(SchoolSeclect);

                               str+=b.getBt();

                               Aa[i]=b.getAnswer();

                              

                           }

                      

                    

                   if(i<Length-1)

                   {

                       f.Vector(school);

                       str+=f.getOPERATOR();

                       str1+=f.getOPERATOR();

                   }

                  

                        

                }

                LIST=str;

                 

                Answer a=new Answer();

                a.Compute(str1,Aa);

                Answer= Math.round(a.getanswer()*1000)/1000.0 ;

               

        }

        String getLIST() {

            return LIST;

        }

        double getAnswer()

        {

            return Answer;

        }

}

 

括号对象生成

public class Bracket  {

    private double Answer=0;

    private String Bt;

    public int school=0;

    public double []B=new double [20];

    private int LENGTH;    //括号内操作数数量

    void Vector(int School)

    {

       

        Function  F=new Function ();

        int LenInBra=2;//括号内操作数为2个

        String bt="(";

        String str="";

        for(int i=0;i<20;i++)

        {

            B[i]=0;

        }

            for(int i=0;i<LenInBra;i++)   

               

            {

                if(School ==0)

                   school=0;

                if(School ==1)

                   school=(int)(Math.random()*2);

                if(School ==2)

                   school=(int)(Math.random()*3);

               

                F.Vector(school);

                bt+=F.getFUNCTION();

                B[i]=F.getVALUEOFFUNCTION();

                if(i!=LenInBra-1)

                {

                   bt+=F.getOPERATOR();

                   str+=F.getOPERATOR();

                }

               

            }

            bt+=")";

           

            Bt=bt;

       

        LENGTH=LenInBra;

       

        Answer  a=new Answer ();

        a.Compute(str, B);

        Answer=  a.getanswer()  ;

       

    }

    int getLENGTH() {

        return LENGTH;

    }

    String getBt() {

        return Bt;

    }

    double getAnswer() {

    return Answer;

    }

   

   

}

题目答案的计算

 

网上类似问题一般采用逆波兰算法,但由于每一个操作数不止一个字符,采用逆波兰算法需要将把每一项当作对象处理,而且这个对象需要进行运算符重载,所以这里采用的是自己设计的算法,同样把每一项当作对象处理

//一道题目至多有俩括号,

import java.util.*;

import java.math.*;

public class Answer  {

         private double answer=0;

         void Compute(String args,double []a)

         {

                 

                  int length=args.length();

                  String  []str0=new String[20];

                   

                  int j=0;

                  for(int i=0;i<length;i++)

                  {

                         

                          if(args.charAt(i)=='+')

                          {

                                  str0[j]="+"       ;j++;

                          }

                          if(args.charAt(i)=='-')

                          {

                                  str0[j]="-"        ;j++;

                          }

                          if(args.charAt(i)=='*')

                          {

                                  str0[j]="*"       ;j++;

                          }

                          if(args.charAt(i)=='/')

                          {

                                  str0[j]="/"        ;j++;

                          }

                  }

                  //先计算*/

                  for(int i=0;i<j+2;i++)

                  {

                          if(str0[i]=="*")

                          {

                                   a[i+1]=a[i]*a[i+1];

                                   a[i]=0;

                           }

                          if(str0[i]=="/")

                          {

                                   a[i+1]=a[i]/a[i+1];

                                   a[i]=0;

                          }

                         

                         

                  }

                  //再计算-

                  for(int i=0;i<j+2;i++)

                  {

                          if(str0[i]=="-")

                          {

                                   for(int k=i+1;k<j+2;k++)

                                   {

                                            if(a[k]!=0)

                                            {

                                                     a[k]=a[i]-a[k];

                                                     a[i]=0;

                                                     break;

                                            }

                                   }

                          }

                         

                  }

                  //取和

                  for(int i=0;i<j+2;i++)

                          answer+=a[i];

                 

                   

         }

         double getanswer()

         {

                  return answer;

         }

 

 

}

每一项的产生

 

public class Function {    

     private String TriSin[]

             = {    "sin<pi/6>",

                    

                    "sin<pi/2>",

                    

                    "sin<5pi/6>" };

     

     private String TriCos[]

             = {    "cos0",

                    

                    "cos<pi/3>",

                    "cos<2pi/3>",

                      };

     

     private String TriTan[]

             = { 

                 "tan<pi/4>",

                 "tan<3pi/4>",

                 };

     

     private String PowFunc[]=

             {

                    "^0.5","^2"

             };

     private String Operator[]=

         {

                    "+","-","*","/"

         };

    private double ValueOfSin[]= {

            0.5,

           

            1,

           

            0.5

    };

   

     private double ValueOfCos[]= {

             1,

             0.5,

             -0.5,

             

     };

     

     private double ValueOfTan[]= {

             

              1,

              -1,

             

     };

     

     private String FUNCTION;

     private String OPERATOR;

     private double VALUEOFFUNCTION;

     

    void Vector(  int OperandOrTriOrPow  )

    {

         int OperatorSet=(int)(Math.random()*4);

         int OperandSet1=(int)(1+Math.random()*100);//随机常数生成

         int OperandSet=(int)(1+Math.random()*10);     

         int FuncSetT=(int)(Math.random()*3);          //三角函数选择

         int ValSetSandC=(int)(Math.random()*3);     //三角函数sin,cos带具体参数选择

         int ValSetT=(int)(Math.random()*2);         //三角函数tan带具体参数选择

         int FuncSetP=(int)(Math.random()*2);        //幂函数选择

         //运算符生成

         OPERATOR=Operator[OperatorSet];

         

         if(OperandOrTriOrPow==0) {

        //常数项生成模块

                FUNCTION=String.valueOf(OperandSet1);   //常数项字符串

                VALUEOFFUNCTION=OperandSet1;              //常数项数学值     

                }                 

         //幂函数生成模块

         if(OperandOrTriOrPow==1) {

                if(FuncSetP==0) {

                    FUNCTION=String.valueOf(OperandSet)+PowFunc[0];  //幂函数字符串

                    VALUEOFFUNCTION=Math.pow(OperandSet, 0.5);              //幂函数数学值

                                }

                else {

                    FUNCTION=String.valueOf(OperandSet)+PowFunc[1];  //幂函数字符串

                    VALUEOFFUNCTION=Math.pow(OperandSet, 2);                //幂函数字符串

                     }

                  }

         //三角函数生成模块

         if(OperandOrTriOrPow==2) {

             if(FuncSetT==2)

             {

                 FUNCTION=TriTan[ValSetT];                        //三角函数字符串

                 VALUEOFFUNCTION=ValueOfTan[ValSetT];                      //三角函数数学值

             }

             if(FuncSetT==1) {

                 FUNCTION=TriCos[ValSetSandC];                    //三角函数字符串

                 VALUEOFFUNCTION=ValueOfCos[ValSetSandC];                 //三角函数数学值

                }

             if(FuncSetT==0) {

                 FUNCTION=TriSin[ValSetSandC];                    //三角函数字符串

                 VALUEOFFUNCTION=ValueOfSin[ValSetSandC];                 //三角函数数学值

                }

         }

          

         OperandOrTriOrPow=(int)(Math.random()*2);//重置选择

    }

    //返回字符串

     String getFUNCTION()

     {

         return FUNCTION;

     }

    //返回字符串

     

    //返回数学值

     double getVALUEOFFUNCTION()

     {

         return VALUEOFFUNCTION;

     }

    //返回数学值

     //返回运算符

     String getOPERATOR()

     {

         return OPERATOR;

     }

    //返回运算符

     

}

 

 

School类,Bracket类中,每一项都从Function对象中产生,并产生这一项的一个double值;

School类中,产生Bracket对象同时会产生这个Bracket对象经过Answer类中的Compute方法得到的括号内式子的值,

最终得到的School对象同样经过Answer类中的Compute方法式子的值

School类,Bracket类的代码本质上是一样的,只是括号内的式子和括号外式子的限定条件不同,为了算法调试时更方便,并没用在School类中引用School类,而是直接复制粘贴新生成一个Bracket类

 

具体计算部分

//一道题目至多有俩括号,

import java.util.*;

import java.math.*;

public class Answer  {

         private double answer=0;

         void Compute(String args,double []a)

         {

                 

                  int length=args.length();

                  String  []str0=new String[20];

                   

                  int j=0;

                  for(int i=0;i<length;i++)

                  {

                         

                          if(args.charAt(i)=='+')

                          {

                                  str0[j]="+"       ;j++;

                          }

                          if(args.charAt(i)=='-')

                          {

                                  str0[j]="-"        ;j++;

                          }

                          if(args.charAt(i)=='*')

                          {

                                  str0[j]="*"       ;j++;

                          }

                          if(args.charAt(i)=='/')

                          {

                                  str0[j]="/"        ;j++;

                          }

                  }

                  //先计算*/

                  for(int i=0;i<j+2;i++)

                  {

                          if(str0[i]=="*")

                          {

                                   a[i+1]=a[i]*a[i+1];

                                   a[i]=0;

                          }

                          if(str0[i]=="/")

                          {

                                   a[i+1]=a[i]/a[i+1];

                                   a[i]=0;

                          }

                         

                         

                  }

                  //再计算-

                  for(int i=0;i<j+2;i++)

                  {

                          if(str0[i]=="-")

                          {

                                   for(int k=i+1;k<j+2;k++)

                                   {

                                            if(a[k]!=0)

                                            {

                                                     a[k]=a[i]-a[k];

                                                     a[i]=0;

                                                     break;

                                            }

                                   }

                          }

                         

                  }

                  //取和

                  for(int i=0;i<j+2;i++)

                          answer+=a[i];

                 

                   

         }

         double getanswer()

         {

                  return answer;

         }

 

 

}

Answer的Compute方法中需要传入两个参数,一个字符串(每一项间的运算符)和一个double数组;

数组记录了每一项的值,由字符串获取一个String数组,记录了每一项间的运算符

然后遍历这个String数组,先进行乘除,后进行减,最后进行加,得出答案;

除运算中不能出现除数为零的情况,所以我在产生每一项时会避免产生值为0的项

 

以下为运行时的情况:

 

 

注册之后

 

 

选择学校后进入试卷界面

 

 

做了一定数量的题后显示得分,题目数量我预设默认的是10题,

 

 

退出后在选择界面处重新选择,再次进入试卷界面

 

 

在此,我们向助教和老师表达歉意

在结对编程中由于我个人的疏忽误删几行代码,导致整个工程无法正常运行,因此在规定时间内未能提交工程代码,且延期上交的工程代码亦不能正常运行。我们再次为此次结对编程中给老师助教带来的不便表示歉意。

在这两天,我们熬夜修改,终于找到的错误所在,并开始认真地总结结对编程中的经验和教训

再次上交工程代码,我们只是为了表达我们的歉意和态度,希望老师和助教在看到这些文字后能有所释怀

posted on 2018-10-12 17:47  刘赟锋  阅读(207)  评论(1编辑  收藏  举报