第三次作业—唐洁、陈小丽

 —— 题目:
           请编写一个能自动生成小学四则运算题目的 “软件”。
           让程序能接受用户输入答案,并判定对错。
           最后给出总共 对/错 的数量。

——需求分析:

  • 累计每次测试答对,答错的题的个数
  • 对用户给出的答案做出相应判断
  • 显示答案的对错

——扩展功能:

  • 程序可以求出带括号的四则运算
  • 四则运算中允许有分数的出现
  • 不仅仅只能做10道题目,可以无限制的做

——设计:

  • 采用模块化思想,把源文件分成几个模块进行封装
  • 生成算术表达式以及解析算术表达式

——代码实现:

 main.cpp文件

#include "stackOperation.h"
#include  "stdlib.h"
#include  "stdio.h"
#include "charactorOperation.h"
#include "calculator.h"
#include<string.h>

void main(void)
{
	long sum;
	long sum_answer;
	float answer;
	int right = 0;
	int wrong = 0;
	while(1)
	{
		char *expression = generate(containNums(8));
		sum=((int)(EvaluateExpression(expression)*1000));
		if(sum%10 >= 5)
			sum_answer = sum/10 + 1;
		else
			sum_answer = sum/10;
		printf("%s=",expression);
		scanf("%f",&answer);
		long temp = answer*100;
		if (temp == sum_answer)
		{
			right++;
		}else
		{
			wrong++;
		}
		printf("\nRight: %d,Wrong: %d",right,wrong);
	}
	system("pause");
	system("cls");
} 

calculator.cpp文件
#include "calculator.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//这个方法是产生多少个数字以内的运算表达式
int containNums(int num)
{
	srand((unsigned)time(0));
	return (rand()%(num - 2)) + 2;
}

char* generate(int count)
{
	srand((unsigned)time(0));
	int len_op = (count - 1)*3;
	int repeat = 0;
	int repeat_op = 0;
	int turn = 0;
	int i,j;
	int *nums = (int *)malloc(sizeof(int)*count);
	int *ops = (int *)malloc(sizeof(int)*len_op);
	for (i = 0;i < count; i++)
	{//产生-99到99的整数,0除外
		int temp = -rand()%50 + 50;
		if(temp != 0)
			nums[i] = temp;
	}

	for (j = 0;j < len_op;j++)
	{
		int temp = rand()%6;
		if (temp == 4 && repeat < count && ops[j - 1] != 5)
		{
			repeat++;
			turn++;
			ops[j] = temp;
			continue;
		}
		if (temp == 5 && turn > 0 && ops[j - 1] != 4)
		{
			turn--;
			ops[j] = temp;
			continue;
		}if (temp >= 0 && temp < 4)
		{
			repeat_op++;
			if (repeat_op > count - 1)
			{
				break;
			}
			ops[j] = temp;
			continue;
		}
		j--;
	}

	for(int h = 0 ;h < turn; h++)
	{
		ops[j] = 5;
		j++;
	}

	for(int n = 0; n < j;n++)
	{
		if(ops[n] == 4 && ops[j - 1 - n] == 5)
		{
			ops = &ops[n + 1];
			j--;
		}else
			break;
	}

	len_op = j;
	char *result = (char *)malloc(sizeof(char) * (j + count + 1) * 5);
	i = 0;
	j = 0;
	int state = 0;
	int m;
	int lower = 0;

	for(m = 0; m < len_op + count*5 && j < len_op; m++)
	{
		if(state == 0 && ops[j] != 4)
		{
			if(nums[i] < 0)
			{
				lower = 1;
				nums[i] = 0 - nums[i];
				if(nums[i] > 9)
				{
					result[m++] = ‘(‘;
					result[m++] = ‘-‘;
					result[m++] = ‘0‘ + (nums[i]/10);
				}
				result[m++] = ‘0‘ + (nums[i++]%10);
				result[m++] = ‘)‘;
			}else
			{
				if(nums[i] > 9)
				{
					result[m++] = ‘0‘ + (nums[i]/10);
				}
				result[m++] = ‘0‘ + (nums[i++]%10);
			}
			state = 1;
		}
		switch(ops[j])
		{
		case 0:
			result[m++] = ‘+‘;
			break;
		case 1:
			result[m++] = ‘-‘;
			break;
		case 2:
			result[m++] = ‘*‘;
			break;
		case 3:
			result[m++] = ‘/‘;
			break;
		case 4:
			if(j != 0)
			{
				if(lower == 1)
				{
					if(result[m - 2] >= 48 && result[m - 3] >= 48)
					{
						result[m] = result[m - 1];
						result[m - 1] = result[m - 2];
						result[m - 2] = result[m - 3];
						result[m - 3] = result[m - 4];
						result[m - 4] = result[m - 5];
						result[m - 5] = ‘(‘;
						break;
					}if(result[m - 1] >= 48)
					{
						result[m] = result[m - 1];
						result[m - 1] = result[m - 2];
						result[m - 2] = result[m - 3];
						result[m - 3] = result[m - 4];
						result[m - 4] = ‘(‘;
					}
					lower = 0;
				}
				else
				{
					if(result[m - 1] >= 48 && result[m - 2] >= 48)
					{
						result[m] = result[m - 1];
						result[m - 1] = result[m - 2];
						result[m - 2] = ‘(‘;
						break;
					}if(result[m - 1] >= 48)
					{
						result[m] = result[m - 1];
						result[m - 1] = ‘(‘;
					}
				}
			}
			else
				result[m] = ‘(‘;
			break;
		case 5:
			result[m] = ‘)‘;
			break;
		}

		lower = 0;

		if(ops[j] == 0 || ops[j] == 1 || ops[j] == 2 || ops[j] == 3)
		{
			if(nums[i] < 0)
			{
				lower = 1;
				nums[i] = 0 - nums[i];
				if(nums[i] > 9)
				{
					result[m++] = ‘(‘;
					result[m++] = ‘-‘;
					result[m++] = ‘0‘ + (nums[i]/10);
				}
				result[m++] = ‘0‘ + (nums[i++]%10);
				result[m] = ‘)‘;
			}else
			{
				if(nums[i] > 9)
				{
					result[m++] = ‘0‘ + (nums[i]/10);
				}
				result[m] = ‘0‘ + (nums[i++]%10);
			}
		}
		j++;
	}
	result[m] = ‘#‘;
	return result;
}

charactorOperation.cpp文件

#ifndef __CALCULATOR_H__
#define __CALCULATOR_H__

int containNums(int num);  //几个数以内的运算,至少两个数
char* generate(int count);   //生成算数表达式

#endif

calculator.cpp文件

#include "charactorOperation.h"

int JudgeOperator(char c)
{
	if(c == ‘+‘ || c == ‘-‘ || c == ‘*‘ || c == ‘/‘ || c == ‘(‘ || c == ‘)‘ || c == ‘#‘)
		return 1;
	else
		return 0;
}

int Precede(char temp,char c)
{
	if(temp==‘+‘)
	{
    if(c==‘+‘) return 1;
    else if(c==‘-‘) return 1;
    else if(c==‘*‘) return -1;
    else if(c==‘/‘) return -1;
    else if(c==‘(‘) return -1;
    else if(c==‘)‘) return 1;
    else return 1;
	}
  else if(temp==‘-‘)
  {
    if(c==‘+‘) return 1;
    else if(c==‘-‘) return 1;
    else if(c==‘*‘) return -1;
    else if(c==‘/‘) return -1;
    else if(c==‘(‘) return -1;
    else if(c==‘)‘) return 1;
    else return 1;
   }
   else if(temp==‘*‘)
  {
    if(c==‘+‘) return 1;
    else if(c==‘-‘) return 1;
    else if(c==‘*‘) return 1;
    else if(c==‘/‘) return 1;
    else if(c==‘(‘) return -1;
    else if(c==‘)‘) return 1;
    else return 1;
   }
   else if(temp==‘/‘)
  {
    if(c==‘+‘) return 1;
    else if(c==‘-‘) return 1;
    else if(c==‘*‘) return 1;
    else if(c==‘/‘) return 1;
    else if(c==‘(‘) return -1;
    else if(c==‘)‘) return 1;
    else return 1;
   }
   else if(temp==‘(‘)
  {
    if(c==‘+‘) return -1;
    else if(c==‘-‘) return -1;
    else if(c==‘*‘) return -1;
    else if(c==‘/‘) return -1;
    else if(c==‘(‘) return -1;
    else return 0;

   }
   else if(temp==‘)‘)
  {
    if(c==‘+‘) return 1;
    else if(c==‘-‘) return 1;
    else if(c==‘*‘) return 1;
    else if(c==‘/‘) return 1;
    else if(c==‘)‘) return 1;
    else return 1;
   }
   else
  {
    if(c==‘+‘) return -1;
    else if(c==‘-‘) return -1;
    else if(c==‘*‘) return -1;
    else if(c==‘/‘) return -1;
    else if(c==‘(‘) return -1;
    else return 0;
   }
}

float Evaluate(float num1,float num2,char op)
{
	float result;
	switch(op)
	{
	case ‘+‘:
		result=num2+num1;
		break;
	case ‘-‘:
		result=num2-num1;
		break;
	case ‘*‘:
		result=num2*num1;
		break;
	case ‘/‘:
		result=num2/num1;
		break;
	}
	return result;
}

float char_to_float(char *&p)
{
	char *p_temp1;
	char array[8]={‘\0‘,‘\0‘,‘\0‘,‘\0‘,‘\0‘,‘\0‘,‘\0‘,‘\0‘};
	int i,n,j;
	float number=0;
	int radix=0;

	p_temp1=p;
	i=0;
	j=0;
	while (!JudgeOperator(*p_temp1))
	{
		array[i]=*p_temp1;
		i++;
		j++;
		p_temp1++;
	}

	j--;
	for (i=0;i<8;i++)
	{
		if (array[i]==‘\0‘)
		{
			break;
		}
		else
		{
			switch(array[i])
			{
			case ‘0‘:
				radix=0;
				break;
			case ‘1‘:
				radix=1;
				break;
			case ‘2‘:
				radix=2;
				break;
			case ‘3‘:
				radix=3;
				break;
			case ‘4‘:
				radix=4;
				break;
			case ‘5‘:
				radix=5;
				break;
			case ‘6‘:
				radix=6;
				break;
			case ‘7‘:
				radix=7;
				break;
			case ‘8‘:
				radix=8;
				break;
			case ‘9‘:
				radix=9;
				break;
			}
			if (j==0)
			{
				radix=radix*1;
			}
			if (j>0)
			{
				for (n=j;n>0;n--)
				{
					radix=radix*10;
				}
			}
			number=number+radix;
			j--;
		}
	}

	p=p_temp1;
	return number;
}

charactorOperation.h文件

#ifndef __CHARACTOR_H__
#define __CHARACTOR_H__

int JudgeOperator(char c);
int Precede(char temp,char c);
float Evaluate(float num1,float num2,char op);
float char_to_float(char *&p);

#endif

stackOperation.cpp文件

#include "stackOperation.h"
#include "charactorOperation.h"
#include <stdlib.h>
#include <stdio.h>

int  init_char_stack(char_stack &s)
{
	s.base=(char *)malloc(100*sizeof(char));

	if(!s.base)
		exit(0);

	s.top=s.base;
	s.stacksize=100;

	return  1;
}

int  init_float_stack(float_stack &s)
{
	s.base=(float *)malloc(100*sizeof(float));

	if(!s.base)
		exit(0);

	s.top=s.base;
	s.stacksize=100;

	return  1;
}

int empty_char_stack(char_stack s)
{
	if(s.top==s.base)
		return 1;
	else
		return 0;
}

int empty_float_stack(float_stack s)
{
	if(s.top==s.base)
		return 1;
	else
		return 0;
}

char get_char_top(char_stack s, char &e)
{
	if(s.base==s.top)
	{
		printf("此栈为空!");
		return 0;
	}

	e=*(--s.top);

	return e;
}

float get_float_top(float_stack s, float &e)
{
	if(s.base==s.top)
	{
		printf("此栈为空!");
		return 0;
	}

	e=*(--s.top);

	return e;
}

int char_push (char_stack &s,char e)
{
	if (s.top-s.base>=s.stacksize)
	{
		s.base =(char *)realloc(s.base,(s.stacksize+10)*sizeof(char));

		if(!s.base)
			exit(0);

		s.top=s.base+s.stacksize;

		s.stacksize+=10;
	}

	*s.top++=e;

	return 1;
}

float float_push (float_stack &s,float e)
{
	if (s.top-s.base>=s.stacksize)//栈满,追加存储空间
	{
		s.base =(float *)realloc(s.base,(s.stacksize+10)*sizeof(float));

		if(!s.base)
			exit(0);

		s.top=s.base+s.stacksize;

		s.stacksize+=10;
	}

	*s.top++=e;

	return 1;
}

char char_pop(char_stack &s,char &e)
{
	if (s.base==s.top)
	{
		printf("此栈为空!");
		return 0;
	}

	s.top--;
	e=*s.top;

	return e;
}

float float_pop(float_stack &s,float &e)
{
	if (s.base==s.top)
	{
		printf("此栈为空!");
		return 0;
	}

	s.top--;
	e=*s.top;

	return e;
}

float EvaluateExpression (char *s)
{
	char_stack OPTR;//操作符栈
	float_stack OPND;//操作数栈
	float a,b;
	float final;//存放最后的结果
	float num;
	char c;
	char temp;//暂存栈顶元素
	char op;//暂存操作符
	char *p_s1;//读取字符串的指针
	p_s1=s;

	init_char_stack(OPTR);
	char_push(OPTR,‘#‘);
	init_float_stack(OPND);

	c=*p_s1;
	while (c!=‘#‘ || get_char_top(OPTR,temp)!=‘#‘)
	{
		if (!JudgeOperator(c))
		{
			num=char_to_float(p_s1);
			float_push(OPND,num);
			c=*p_s1;
		}
		else//若为运算符
		{
			switch(Precede(get_char_top(OPTR,temp),c))
			{
			case -1:
				if (get_char_top(OPTR,temp) == ‘(‘ && c == ‘-‘)
				{
					float_push(OPND,0);
				}
				char_push(OPTR,c);
				p_s1++;
				c=*p_s1;
				break;
			case 0:
				char_pop(OPTR,c);
				p_s1++;
				c=*p_s1;
				break;
			case 1:
				char_pop(OPTR,op);
				float_pop(OPND,a);
				float_pop(OPND,b);
				float_push(OPND,Evaluate(a,b,op));
				break;
			}
		}
	}
	*p_s1 = ‘\0‘;
	final=get_float_top(OPND,final);
	return final;
}

stackOperation.h文件
#ifndef __STACK_H__
#define __STACK_H__

typedef struct
{
	char *base;     //指向栈顺序存储结构数组的指针

	char *top;      //栈顶指针,指向栈顶元素下一个位置

	int stacksize; //当前已分配的存储空间,即栈的最大容量,以元素为单位

}char_stack;//操作符栈

typedef struct
{
	float *base;    

	float *top;     

	int stacksize; 

}float_stack;//操作数栈

int  init_char_stack(char_stack &s);
int  init_float_stack(float_stack &s);
int empty_char_stack(char_stack s);
int empty_float_stack(float_stack s);
char get_char_top(char_stack s, char &e);
float get_float_top(float_stack s, float &e);
int char_push (char_stack &s,char e);
float float_push (float_stack &s,float e);
char char_pop(char_stack &s,char &e);
float float_pop(float_stack &s,float &e);
float EvaluateExpression (char *s);

#endif

两人合作步骤:

1. 首先我们先对做的题目读得不太清楚, 题目中的请采用模块化设计思想,修改之前的code,将 “计算功能” 封装起来,真的是不理解。

2. 然后我们通过向同学询问和上网查找资料才知道老师大概要求我们做的是什么,但是这个时候我们两个又意识到我们的代码又出现了新的问题。在第二次作业中我们两个写的代码存在问题,觉得缺乏模块化的思想,自己读起来都觉得很乱。层次不是很清楚,不像其它同学写的一样,主函数和子函数分得很清楚。这样无论是将“计算功能”封装起来,还是对其进行单元测试,实现起来都方便很多。

3.为了更好地实现这次作业的要求,我们两个在商量以后,就觉定重新写代码,并进行规范以及相应的修改。这是一个相当痛苦的过程,什么都是从零开始。

4. 通过老师在课堂上的讲解,大概地知道怎么让自己的代码看起来更加地规范,怎么进行但单元测试。知道了头文件(.h)和源文件(.c)中存放的是些什么内容。

5.对函数进行模块化,将函数进行了封装,并把函数声明与具体实现分别存放在头文件(.h)和源文件(.c)中。

6.代码规范设计方面,我们认真阅读教材Page57:4.2-4.3节中内容,进行了风格、设计讨论,了解之后,一人说一人写。

总结:

1.刚刚拿到这个题的时候是蒙的,作业里面的要求都是在原来的学习过程中没有接触到的。比如说怎么进行封装。

2.在老师的讲解下,大概知道了函数封装和测试的基本思想。

3.对于这次作业的完成感觉很吃力,消耗了大量的时间。

4.上次作业因为写得不规范,给这次作业的完成增加了工作量。

5.编程的过程中,模块化思想很重要。遇到困难时,要懂得查阅资料和同学进行交流。

PSP耗时统计

序号 psp 耗时(h) 百分比(%)
1 需求分析 5 9.0
2 设计 10 18.18
3 代码实现 24 43.6
4 测试 12 21.8
5 分析和总结 4 7.2
时间: 2024-01-02 09:50:50

第三次作业—唐洁、陈小丽的相关文章

软件工程第三次作业(微软小娜案例分析)

第一部分 调研, 评测 1.上手体验  我使用的是win10系统,所以自带Cortana,之后又在手机上下载了安卓版本.第一感受不管是在电脑上还是在手机上都比较流畅,优化的比较好.电脑上使用也比较方便,在桌面上就能直接打开,安卓手机则需要下载.使用上,语音识别还算准确,而且搜索到的信息也比较有用. 2.bug测试 (1)语音输入后莫名弹出必应. (2)语音识别不太准确 3. 用专业的语言描述 (每个bug 不少于 40字),如有必要, 可以配图. 当语音输入有标点时,Cortana有几率打开ed

第三次作业问卷

看到一个问卷不错,拟作为第三次作业的部分内容. 你对自己的未来有什么规划?做了哪些准备? 答:未来走一步算一步,计划赶不上变化,充实自己的知识,多增加一点自己经验,比起知识,更重要的是社交. 你认为什么是学习?学习有什么用?现在学习动力如何?为什么? 答:学习,就是知道一些以前不知道的事.厉害的人有两点:观察力和文化底蕴,学习就是为了增加知识储备,尽量不出现书到用时方恨少的情况.目前的学习动力很缺乏,因为一到大学开始想着混. 你感觉自己什么事情做的比较成功?有什么经验? 答:并不知道,似乎没有什

第三次作业——个人作业——软件产品案例分析

第三次作业--个人作业--软件产品案例分析 评测产品:K米,安卓端 第一部分 调研,评测 评测 初体验 还没去KTV的时候,刚开始下了这个APP,我按正常软件一样,进行了注册功能,可到要写用户信息的时候,(可能是本着比较随意的思想,只想一直点,只填了一些以外使用其他APP时候的基本信息就一直点进一步),在上传用户头像的时候,我想直接跳过,没想到这一定要上传头像才可以啊!!!然后注册完后点进去,看了下K歌功能都不能用,看了一下用户的社区,发现大部分用户动态都是国庆的,这个时候已经10.17了,可见

职业规划第三次作业

看到一个问卷不错,拟作为第三次作业的部分内容. 你对自己的未来有什么规划?做了哪些准备? 答: 学好大学四年的课程,并积极参加各种活动来锻炼自己的能力.在实习期间认真学习工作经验,学习经验然后争取能自己创业 好好交友,多读书, 你认为什么是学习?学习有什么用?现在学习动力如何?为什么? 答:学习是通过他人的言传身教了解知识,将他人的认识转化为自己的知识.学习能够取他人之长补己之短,丰富自己的认知,还避免了闭门造车和坐井观天的错误.现在的学习动力一般,因为新学知识对我来说比较陌生. 你感觉自己什么

o(︶︿︶)o 唉,第三次作业

                                                                             第三次作业 1.需求分析 (1)从combox控件中,获取各种运算(+.=.*./),用户可以输入运算范围,比如想算0-10以内的,那么就在textbox5和6中输入0和10就行,当然,如果5中的数字比6中的数字小的话,会有消息提示框,并清空他们.用户可以选择算法,设置范围后,点击计算,输入结果,回车就可以. 2.设计思路 (1)思考应该怎么做

第三次作业第一题

问卷调查 看到一个问卷不错,拟作为第三次作业的部分内容. 1.   你对自己的未来有什么规划?做了哪些准备 答: 我对未来的规划是想做网页设计类的  目前的准备是多看相关知识的书,熟悉网页设计的软件认真学习,将自己所学运用到实际工作中. 2.   你认为什么是学习?学习有什么用?现在学习动力如何?为什么? 答:学习就是把不会的知识变成会的.学习的作用是学会了就能运用到实践中.现在的学习动力还没有那么努力因为可能是还是找不到自己的目标比较迷茫 3.   你感觉自己什么事情做的比较成功?有什么经验?

第三周作业(一)VS安装及单元测试练习

第三周作业(一) 需求:练习教科书第22~25页单元测试练习,要求自行安装Visual Studio开发平台,版本至少在2010以上,要求把程序安装过程和练习过程写到博客上,越详细越好,要图文并茂,没有书的同学可以向班内助教同学借阅. 1.visual studio 开发平台安装 事实上我对Visual Studio了解不多,只知道支持的编程语言多,用的人也挺多,功能强大.至于到底好在哪里,还是要用上一阵自己体验一下才知道.听同学说VS2015有些卡,所以这里我选择了VS2013. 如图,具体版

软件工程(第三次作业)

软件工程(第三次作业) 组员:周德莉.王铭霞 一.题目 在之前编写的四则运算程序基础之上做如下改进: 1  请参照教材Page57:4.2-4.3节中内容,修改原程序,使之符合 “代码风格和设计规范”的基本要求: 2  请采用模块化设计思想,修改之前的code,将 “计算功能” 封装起来 小提示: 假如在C语言环境下,可将函数声明与具体实现分别存放在头文件(.h)和源文件(.c)中: 3  通过测试程序和API 接口,测试其简单的加法功能. 小提示: 单元测试方法请参看教材Page21:2.1.

OO前三次作业总结

很庆幸我还活着-- 千言万语尽在一言中-- 好了话不多说直接进入正题,在此对前三次OO作业做一个简单的总结: 第一次作业:第一次接触面向对象-作为一个没有java编程基础的小白来说,面对这个本来比较简单的作业还是比较头疼的,首先不懂java语法,其次不理解面向对象的含义:一脸懵逼-- 好在经过两天的煎熬之后也算是勉强入门了,磕磕碰碰写完了第一次作业,由于初次第一次对于面向对象这个概念没有多少理解并且作业难度也不大,所以整个程序只有一个类,代码量110行:主要难点为输入是否合法的判断以及多项式算法