软件工程概论作业03--将随机产生的表达式导入数据库

Posted 账号你好

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软件工程概论作业03--将随机产生的表达式导入数据库相关的知识,希望对你有一定的参考价值。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;


public class Size {
	public static void main(String[] args) throws ClassNotFoundException, SQLException{
		Scanner sc = new Scanner (System.in);
		System.out.println("请选择    1.整数运算    2.分数运算");
		int t = sc.nextInt();
		switch(t)
		{
			case 1:
			{
				Integer(sc);
				break;
			}
			case 2:
			{
				fenshu(sc);
			}
		}
		
	}
	
	
	public static int simple(int a,int b)    //求最大公约数
	{
		int c=0;
		if(a>b)
		{		
			while(a!=b)
			{
				c=a-b;
				if(b>=c)
				{
					a=b;
					b=c;
				}
				if(c>b)
				{
					a=c;
				}
			}
			return a;
		}
		else
		{
			while(a!=b)
			{
				c=b-a;
				if(a>=c)
				{
					b=a;
					a=c;
				}
				if(c>a)
				{
					b=c;
				}
				
			}
			return a;
		}
	}
	
	
	public static int gongbei(int a,int b)      //求最小公倍数
	{
		int t=simple(a,b);
		return a*b/t;
	}			
		
	public static String liangfenshujisuan(String a,String b,char c)          //两个真分数的计算
	{
		int t=0;
		int t1=0,t2=0;
		int p1=0,p2=0;
		String s="";
		String d[]=a.split("\\\\/");
		String d1[]=b.split("\\\\/");
		int da[]=new int [d.length];
		int db[]=new int [d1.length];
		for(int i=0;i<d.length;i++)
		{
			da[i]=Integer.parseInt(d[i]);
		}
		for(int i=0;i<d1.length;i++)
		{
			db[i]=Integer.parseInt(d1[i]);
		}
		
		if(c==\'+\')
		{
			t=gongbei(da[1],db[1]);        //两数分母同分
			t1=t/da[1];
			da[0]*=t1;                   //分子与分母相匹配
			t2=t/db[1];
			db[0]*=t2;
			p1=da[0]+db[0];
			s+=p1+"/"+t;
		}
		if(c==\'-\')
		{
			t=gongbei(da[1],db[1]);        //两数分母同分
			t1=t/da[1];
			da[0]*=t1;                   //分子与分母相匹配
			t2=t/db[1];
			db[0]*=t2;
			p1=da[0]-db[0];
			if(p1<=0)
			{
				return "error";
			}	
			else
			{
				s+=p1+"/"+t;
			}		
		}
		if(c==\'*\')
		{
			p1=da[0]*db[0];
			p2=da[1]*db[0];
			s+=p1+"/"+p2;
		}
		if(c==\'/\')
		{
			p1=da[0]*db[1];
			p2=da[1]*db[0];
			s+=p1+"/"+p2;
		}
		return s;
	}

	public static String fenshujisuan(String a)                       //分数表达式计算
	{
		Stack <String>num=new Stack <String>();
		Stack <String>fuhao=new Stack<String>();
		a+="#";
		fuhao.push("#");
		char ch;
		int i=0;
		int s=0;
		int y=0;
		ch=a.charAt(i);
		while(!(ch+"").equals("#")||(!(fuhao.peek().equals("#"))))
		{
			if(ch==\' \')          //如果ch=" ",则说明接下来是数字
			{
				String rn="";
				while(true)
				{
					ch=a.charAt(++i);
					if(ch==\' \')
					{
						break;
					}
					rn+=ch;
				}
				if((i+1)<a.length())
				{
					ch=a.charAt(++i);
				}
				num.push(rn);
			}
			else           //遇到的是字符
			{
				char comp=youxian(fuhao.peek(),ch+"");  //比较两个字符的优先级
				if(comp==\'=\')                          //说明遇到右括号
				{                 
					fuhao.pop();
					if((i+1)<a.length())
					{
						ch=a.charAt(++i);
					}
				}
				else if(comp==\'>\')                   //优先级高,弹出两个数和一个运算符,进行运算
				{
					String st1=num.pop();
					String st2=num.pop();
					String fuh1=fuhao.pop();
					char fuh2=fuh1.charAt(0);        //将String类型转为char类型
					String sz=""; 
					sz=liangfenshujisuan(st2,st1,fuh2);
					if(sz.equals("error"))                     //如果运算中有问题,就结束运算
					{
						return "error";
					}
					else
					{
						num.push(sz+"");             //将两数结果压入栈中
					}
				}
				else                                  //优先级比较低,把运算符压入栈中
				{
					fuhao.push(ch+"");
					if((i+1)<a.length())
					{
						ch=a.charAt(++i);
					}
				}
			}
		}
		return num.pop();
	}
	
	public static String fenshuchansheng(int n1,int t1)           //生成真分数的字符串表达式  n1=2,3,4
	{
		Scanner sc=new Scanner(System.in);
		String s=" ";
		String a[]={"+","-","*","/"};
		int a1[]=new int [n1-1];
		int b[]=new int [2*n1];                  //生成的随机数是操作数的2倍
		for(int i=0;i<2*n1;i=i+2)
		{
			b[i]=(int)(Math.random()*t1);         //随机产生第一个操作数的分子分母
			b[i+1]=(int)(Math.random()*t1);
			if((b[i]>=b[i+1])||(b[i+1]==0)||(b[i]==0))           //如果分子大于分母或分子、分母为0,重新赋值
			{
				i=i-2;
			}			
		}		
		for(int j=0;j<n1-1;j++)
		{
			a1[j]=(int)(Math.random()*4);          //随机产生运算符的位置
		}
		int i=0;
		for(int j=0;j<2*n1;j+=2)
		{
			int t=simple(b[j],b[j+1]);       //第1,2个数是第一个操作数的分子分母,以此类推
			b[j] /=t;                       //化简分子分母
			b[j+1] /=t;
		}
		for(int j=0;j<2*(n1-1);j+=2)
		{	
			s+=b[j]+"/"+b[j+1]+" "+a[a1[i]]+" ";
			i++;
		}
		s+=b[2*(n1-1)]+"/"+b[2*(n1-1)+1]+" ";
		return s;	
	}
	
	public static String fenshuchanshengkuohao(int n1,int t1)     //生成带括号的真分数的字符串表达式  n1=2,3,4
	{
		Scanner sc=new Scanner(System.in);
		String s=" ";
		String a[]={"+","-","*","/"};
		int a3[]=new int [n1];                   //记录括号产生的位置
		String a5[]=new String [n1];
		a3=chansheng(n1);
		int a1[]=new int [n1-1];
		int b[]=new int [2*n1];                  //生成的随机数是操作数的2倍
		for(int i=0;i<2*n1;i=i+2)
		{
			b[i]=(int)(Math.random()*t1);         //随机产生第一个操作数的分子分母
			b[i+1]=(int)(Math.random()*t1);
			if((b[i]>=b[i+1])||(b[i+1]==0))           //如果分子大于分母或分母为0,重新赋值
			{
				i=i-2;
			}			
		}		
		for(int j=0;j<n1-1;j++)
		{
			a1[j]=(int)(Math.random()*4);          //随机产生运算符的位置
		}
		int i=0;
		for(int j=0;j<2*n1;j+=2)            //化简真分数
		{
			int t=simple(b[j],b[j+1]);       //第1,2个数是第一个操作数的分子分母,以此类推
			b[j] /=t;                       //化简分子分母
			b[j+1] /=t;
		}
		
		for(int j=0;j<2*(n1-1);j+=2)
		{	
			s+=b[j]+"/"+b[j+1]+" "+a[a1[i]]+" ";
			i++;
		}
		s+=b[2*(n1-1)]+"/"+b[2*(n1-1)+1]+" ";
		return s;	
	}
	public static char youxian(String f,String s)                //计算两个符号的优先级
	{
		char a1[][]={
				{\'>\',\'>\',\'<\',\'<\',\'<\',\'>\',\'>\'},
				{\'>\',\'>\',\'<\',\'<\',\'<\',\'>\',\'>\'},
				{\'>\',\'>\',\'>\',\'>\',\'<\',\'>\',\'>\'},
				{\'>\',\'>\',\'>\',\'>\',\'<\',\'>\',\'>\'},
				{\'<\',\'<\',\'<\',\'<\',\'<\',\'=\',\' \'},
				{\'>\',\'>\',\'>\',\'>\',\' \',\'>\',\'>\'},
				{\'<\',\'<\',\'<\',\'<\',\'<\',\' \',\'=\'}
		};
		String a="+-*/()#";
		int a11=a.indexOf(f);   //找出运算符在表格中的行坐标
		int a12=a.indexOf(s);   //找出运算符在表格中的行坐标
	//	System.out.println(f+"     "+s);
		return a1[a11][a12];
	}	
	public static int [] chansheng(int num)                    //随机产生括号
	{
		int []b=new int[num];
		for(int i=0;i<b.length;i++)
		{
			b[i]=0;
		}
		Random rd=new Random();
		for(int i=2;i<num;i++)
		{
			for(int j=0;j<num-i+1;j++)
			{
				int t=rd.nextInt(2);
				if(t==1)
				{
					if(b[j]>=0&&b[j+i-1]<=0)
					{
						int c=0;
						for(int k=j;k<j+i;k++)
						{
							c+=b[k];
						}
						if(c==0)
						{
							b[j]++;
							b[j+i-1]--;
						}
					}
					
				}
			}
		}
		return b;
	}
	
	public static String chanshengbiaodashi(int num,int t1)       //产生带括号的表达式
	{
		int a1[]=new int[num];
		int a2[]=new int[num-1];
		int a3[]=new int[num];
		String[]a5=new String[num];
		String[] a4={"+","-","*","/"};
		for(int i=0;i<num;i++)
		{
			a1[i]=(int) (Math.random()*t1);
		}
		for(int i=0;i<num-1;i++)
		{
			a2[i]=(int) (Math.random()*4);
		}
		a3=chansheng(num);
		for(int i=0;i<num;i++)
		{
			a5[i]="";
			if(a3[i]<0)
			{
				int c=0-a3[i];
				for(int j=0;j<c;j++)
				{
					a5[i]+=")";
				}
			}
			else
			{
				for(int j=0;j<a3[i];j++)
				{
					a5[i]+="(";
				}
			}
		}
		String t="";
		for(int i=0;i<num-1;i++)
		{
			if(a3[i]>0)
			{
				t+=a5[i]+" "+a1[i]+" "+a4[a2[i]];
			}
			else
			{
				t+=" "+a1[i]+" "+a5[i]+a4[a2[i]];
			}
		}
		if(a3[num-1]>0)
		{
			t+=a5[num-1]+" "+a1[num-1]+" ";
		}
		else
		{
			t+=" "+a1[num-1]+" "+a5[num-1];
		}
		return t;
	}
	
	public static int[] tys(int a,int b,char c)   //两个数的运算
	{
		int []a1=new int [2];            //a1[0]用来记录两数运算结果,a1[1]用来记录两数能否继续算下去
		a1[0]=a1[1]=0;
		int d=0;
		if(c==\'+\')
		{
			d=a+b;
		}
		else if(c==\'-\')
		{
			if(a<b)
			{
				a1[1]=1;
			}
			else
			{
				d=a-b;
			}
		}
		else if(c==\'*\')
		{
			d=a*b;
		}
		else
		{
			if((b==0)||(a%b!=0)||(a<b))
			{
				a1[1]=1;
			}
			else
			d=a/b; 
		}
		a1[0] = d;
		return a1;
	}
	
	public static String jisuan(String a)     //整数表达式的运算
	{
		Stack <String>num=new Stack <String>();
		Stack <String>fuhao=new Stack<String>();
		a+="#";
		fuhao.push("#");
		char ch;
		int i=0;
		int s=0;
		int y=0;
		ch=a.charAt(i);
		while(!(ch+"").equals("#") || !fuhao.peek().equals("#"))
		{
			if(ch==\' \')              //如果遇到字符为空,说明遇到数字
			{
				String rn="";        //用来记录数据
				while(true)
				{
					ch=a.charAt(++i);
					if(ch==\' \')
					{
						break;
					}
					rn+=ch;
				}
				if((i+1)<a.length()){
					ch=a.charAt(++i);
				}
				num.push(rn);
			}
			else//遇到的是字符
			{
				char comp=youxian(fuhao.peek(),ch+"");  //比较两个字符的优先级
				if(comp==\'=\')                          //说明遇到右括号
				{                 
					fuhao.pop();
					if((i+1)<a.length()){
						ch=a.charAt(++i);
					}
				}
				else if(comp==\'>\')                   //优先级高,弹出两个数和一个运算符,进行运算
				{
					String st1=num.pop();
					String st2=num.pop();
					int ai1 = Integer.parseInt(st1);
					int ai2 = Integer.parseInt(st2);
					String fuh1=fuhao.pop();
					char fuh2=fuh1.charAt(0);        //将String类型转为char类型
					int []sz=new int[2]; 
					sz=tys(ai2,ai1,fuh2);
					if(sz[1]==1)                     //如果运算中有问题,就结束运算
					{
						return "error";
					}
					else
					{
						num.push(sz[0]+"");          //将两数结果压入栈中
					}
				}
				else                                  //优先级比较低,把运算符压入栈中
				{
					fuhao.push(ch+"");
					if((i+1)<a.length())
					{
						ch=a.charAt(++i);
					}
				}
			}
		}
		return num.pop();
	}
	
	//整数运算
	public static void Integer(Scanner sc) throws ClassNotFoundException, SQLException
	{
		System.out.println("请选择    1.不含括号    2.含有括号");
		int t = sc.nextInt();
		switch(t)
		{
			case 1:
			{
				int numr=0;
				int numw=0;
				System.out.println("请输入操作数的最大范围:");
				int t1 = sc.nextInt();
				
				System.out.println("请输入题目数量:");
				int n=sc.nextInt();
				
				String s1[]=new String [n];
				String str[] = new String [n];
				String str1[] = new String [n];	
				String a[]={"+","-","*","/"};
				int b[][] = new int [n][];            //用二维表存储操作数
				for(int i=0;i<n;i++)                 //生成表达式并输出
				{
					str[i] = "第"+(i+1)+"题: ";
					str1[i] = " ";
					s1[i]="";
					int n1=(int) (Math.random()*3);            //随机生成操作数的个数
					b[i]=new int[n1+2];   
					for(int j=0;j<n1+2;j++)
					    b[i][j]=(int) (Math.random()*t1);
					int d[] = new int [n1+1];                //存储符号在a中的位置
					for(int j=0;j<n1+1;j++)                  //随机产生数映射到运算符
					{
						d[j]=(int) (Math.random()*4);
					}		
					for(int j=0;j<n1+1;j++)              //将表达式存储到String类型的字符串中
					{	
						str[i]+=b[i][j]+" "+a[d[j]]+" ";
						str1[i] += b[i][j]+" "+a[d[j]]+" ";
					}
					str[i]+=b[i][n1+1]+" =";            //包含括号,用于输出
					str1[i] += b[i][n1+1]+" ";              //不包含括号,方便堆栈过程的计算
					boolean flag=true; 
					for(int j=i-1;j>=0;j--)
					{
						if(str1[i]==str1[j])            //判断是否重复
						{
							flag=false;
							break;
						}
						else if((n1==0)&&((d[0]==0)||(d[0]==2))&&           //乘法或加法交换同样重复 
								((b[i][0]==b[j][1])&&(b[i][1]==b[j][0])))
						{
							flag = false;
							break;
						}
					}
					for(int z=0;z<n1+1;z++)        //判断有除法时,后边的操作数是否为0
					{
						if(d[z]==3&&b[i][z+1]==0)
						{
							flag=false;
							break;
						}
					}
					if( flag==false)
					{
						i--;
					}
					else
					{
						
						String s =jisuan(str1[i]);
					    s1[i]+=jisuan(str1[i]);
						if(s.equals("error"))
						{
							i--;
						}
						else
						{
							System.out.print(str[i]);
							String q=sc.next();
							if(q.equals(s))
							{
								System.out.println("恭喜你,回答正确!");
								numr++;
							}
							else
							{
								System.out.println("很遗憾,回答错误!  正确结果为:"+s);
								numw++;
							}
						}
					}			
				}
				lianjiezhengshu(str,s1);
				System.out.println("一共"+n+"道题,答对"+numr+"道,错误"+numw+"道,继续努力!");
				break;
			}
			case 2:
			{
				int numr=0;
				int numw=0;  
				System.out.println("请输入操作数的最大范围:");
				int t1 = sc.nextInt();
				System.out.println("请输入题目数量:");
				int n=sc.nextInt();
				String str[] = new String [n];
			    String str1[] = new String [n];
				String s1[]=new String [n];
				for(int i=0;i<n;i++)
				{
					
					str[i]="";
					str1[i]="第"+(i+1)+"题: ";
					s1[i]="";
					int n1=(int) (Math.random()*3);            //随机生成操作数的个数
					str[i]+=chanshengbiaodashi(n1+2,t1);
					str1[i]+=str[i]+" =";
					String s = jisuan(str[i]);
					s1[i]+=jisuan(str[i]);
					if(s.equals("error"))
					{
						i--;
					}
					else
					{
						System.out.print(str1[i]);
						String q=sc.next();
						if(q.equals(s))
						{
							System.out.println("恭喜你,回答正确!");
							numr++;
						}
						else
						{
							System.out.println("很遗憾,回答错误!  正确结果为:"+s);
							numw++;
						}
					}		
					
				}
				lianjiezhengshu(str1,s1);
				System.out.println("一共"+n+"道题,答对"+numr+"道,错误"+numw+"道,继续努力!");
				break;
			}
		
		}
	}	
	
	//分数运算
	public static void fenshu(Scanner sc) throws ClassNotFoundException, SQLException
	{
		System.out.println("请输入题目数量:");
		int n=sc.nextInt();
		System.out.println("请输入操作数范围:");
		int t1=sc.nextInt();
		String str[] = new String [n];
		String str1[]= new String [n];
		String s[]=new String[n];
		String s1[]=new String [n];
		for(int i=0;i<n;i++)
		{
			int n1=(int) (Math.random()*3);
			str1[i]="第"+(i+1)+"道题目:";
			str1[i]+=fenshuchansheng(n1+2,t1);
			str[i]=fenshuchansheng(n1+2,t1);
			s[i]=fenshujisuan(str[i]);
			s1[i]="";
			int z=1;
			for(int j=i-1;j>=0;j--)
			{
				if(str[i].equals(str[j]))
				{
					z=0;
					break;
				}
				//else if()
			}
			if((z==0)||(s[i].equals("error")))
			{
				i--;
			}		
			else
			{
				String b1[] =new String [2];                //对运算结果进行化简
			    int b[]=new int [2];
				b1=s[i].split("\\\\/");
				b[0]=Integer.parseInt(b1[0]);
				b[1]=Integer.parseInt(b1[1]);
				int t=simple(b[0],b[1]);
				b[0] /=t;
				b[1] /=t;
				int a=(int)(b[0]/b[1]);
				int c=b[0]%b[1];
				
				if(b[0]>b[1])              //判断结果格式
				{
					if(b[0]%b[1]==0)
					{
						s1[i]+=a;
						System.out.println("第"+(i+1)+"道题目:"+str[i]+" ="+a);
					}
					else
					{
						s1[i]+=a+"\'"+c+"/"+b[1];
						System.out.println("第"+(i+1)+"道题目:"+str[i]+" ="+s1[i]);
					}
				}
				if(b[1]>b[0])
				{
					s1[i]+=b[0]+"/"+b[1];
					System.out.println("第"+(i+1)+"道题目:"+str[i]+" ="+s1[i]);
				}
				else if(b[0]==b[1])
				{
					s1[i]+="1";
					System.out.println("第"+(i+1)+"道题目:"+str[i]+" ="+s1[i]);
				}
				
			}
			
		}
		lianjiefenshu(str1,s1);             //连接数据库,将表达式和结果导入数据库
		System.out.println("导入成功!");
	}
    //分数连接数据库
	public static void lianjiefenshu(String a[],String b[]) throws ClassNotFoundException, SQLException
    {
		Connection conn = null;
		PreparedStatement pstmt = null;
		String driverName = "com.mysql.jdbc.Driver";
		String userName = "root";
		String userPwd = "123456789";
		String ur11 = "jdbc:mysql://localhost:3306/size03";
		String ur12 = "?user=" + userName + "&password=" + userPwd;
		String ur13 = "&useUnicode=true&characterEncoding=UTF-8";
		String ur1 = ur11 + ur12 + ur13;
		Class.forName(driverName);
		conn = DriverManager.getConnection(ur1);
		String sql = "insert into text03fenshu(表达式,结果) values(?,?)";
		pstmt = conn.prepareStatement(sql);
		for(int i=0;i<a.length;i++)
		{
			pstmt.setString(1,a[i] );
		    pstmt.setString(2, b[i]);
		    pstmt.executeUpdate();
		}
		if(pstmt !=null)
		{
		 pstmt.close();
		}
		if(conn!=null)
		{
		 conn.close();
		}
		   
    }
	//整数连接数据库
	public static void lianjiezhengshu(String a[],String b[]) throws ClassNotFoundException, SQLException
    {
		Connection conn = null;
		PreparedStatement pstmt = null;
		String driverName = "com.mysql.jdbc.Driver";
		String userName = "root";
		String userPwd = "123456789";
		String ur11 = "jdbc:mysql://localhost:3306/size03";
		String ur12 = "?user=" + userName + "&password=" + userPwd;
		String ur13 = "&useUnicode=true&characterEncoding=UTF-8";
		String ur1 = ur11 + ur12 + ur13;
		Class.forName(driverName);
		conn = DriverManager.getConnection(ur1);
		String sql = "insert into text03zhengshu(表达式,结果) values(?,?)";
		pstmt = conn.prepareStatement(sql);
		for(int i=0;i<a.length;i++)
		{
			pstmt.setString(1,a[i] );
		    pstmt.setString(2, b[i]);
		    pstmt.executeUpdate();
		}
		if(pstmt !=null)
		{
		 pstmt.close();
		}
		if(conn!=null)
		{
		 conn.close();
		}
		   
    }
}

  

设计思想:

   这次的实验较上次的改进有,整数运算可以随机产生不超过四个的操作数,可以随机产生括号;

分数部分,可以随机产生不超过四个的操作数,对于多于两个操作数的表达式,利用堆栈的方式进行计算,

首先将String类型的表达式利用空格将数字与运算符分开,将数字强制转换为int类型,进行计算。

最后将表达式和结果都导入数据库,调用数据库,与输入的值比较,查看结果是否匹配,最后统计正确和错误的个数。

 

 运行截图

                                             

 

                         

                   

           项目计划总结

日期/任务

听课/分钟

编写程序/分钟

阅读课本/分钟

日总计/分钟

3.13周一

100

30

 

130

周二

 

60

 

60

周三

 

120

 

120

周四

 

60

 

60

周五

 

80

 

80

周总结

100

350

0

450

 

                                 时间记录日志

日期

开始时间

结束时间

中断时间

净时间

活动

 

3.13周一

14:00

15:50

 

100

上课

 

周二

19:00

22:00

 

120

编程

 

周三

14:00

16:50

 

120

编程

 

周四

19:00

20:50

 

60

编程

 

周五

19:00

21:00

 

80

编程、写报告

 

 

                                                                                                     缺陷记录日志

日期

编号

引入阶段

排除阶段

修复时间

 

 

3.16

周四

01

编码

变译

50

 

 

描述:在真分数相减的差为负数,并化简分数时,将负数的分子先取绝对值再化简,不能用p=0-p;而应该直接p=-p;

以上是关于软件工程概论作业03--将随机产生的表达式导入数据库的主要内容,如果未能解决你的问题,请参考以下文章

软件工程概论-作业02

软件工程概论个人作业03

软件工程概论个人作业01

软件工程概论作业三

软件工程概论作业02

软件工程概论作业01