Un programa para generar automáticamente cuatro problemas aritméticos para proyectos emparejados (C ++)

Chen Yu y Guo Yicai completaron esta operación por parejas.

Cero, dirección de github:

https://github.com/King-Authur/-Automatically-generate-four-arithmetic-problems


1. Requisitos relevantes del proyecto.

Implemente un programa de línea de comandos que genere automáticamente cuatro preguntas aritméticas de la escuela primaria (también puede usar una interfaz gráfica con funciones similares).
Inserte la descripción de la imagen aquí
Requisitos del proyecto

  1. Utilice el parámetro -n para controlar el número de preguntas generadas, por ejemplo

Myapp.exe -n 10

Se generarán 10 preguntas.

  1. Use el parámetro -r para controlar el rango de valores numéricos (números naturales, fracciones verdaderas y denominadores de fracciones verdaderas) en la pregunta, por ejemplo

Myapp.exe -r 10

Se generarán cuatro problemas aritméticos dentro de 10 (excluyendo 10). Este parámetro se puede establecer en 1 u otros números naturales. Se debe proporcionar este parámetro; de lo contrario, el programa informa un error y proporciona información de ayuda.

  1. En el problema generado, el proceso de cálculo no puede producir números negativos, es decir, si hay una subexpresión de la forma e1 − e2 en la expresión aritmética, entonces e1≥ e2.

  2. Si hay una subexpresión de la forma e1 ÷ e2 en la pregunta generada, el resultado debería ser una fracción verdadera.

  3. El número de operadores que aparecen en cada pregunta no excede de 3.

  4. Las preguntas generadas por el programa en una ejecución no pueden repetirse, es decir, dos preguntas no pueden convertirse en la misma pregunta mediante un número limitado de intercambios de expresiones aritméticas + y ×.
    Por ejemplo:
    23 + 45 = y 45 + 23 = son preguntas repetidas
    6 × 8 = y 8 × 6 = también son preguntas repetidas.
    Las dos preguntas 3+ (2 + 1) y 1 + 2 + 3 son repetitivas, ya que + está asociado a la izquierda, 1 + 2 + 3 es equivalente a (1 + 2) +3, que es 3+ (1 +2), que es 3+ (2 + 1).
    Pero 1 + 2 + 3 y 3 + 2 + 1 son dos preguntas que no se repiten, porque 1 + 2 + 3 es equivalente a (1 + 2) +3, y 3 + 2 + 1 es equivalente a (3 + 2 ) +1, no pueden convertirse en el mismo problema a través de un número limitado de intercambios.

Las preguntas generadas se almacenan en el archivo Exercises.txt en el directorio actual del programa de ejecución, en el siguiente formato:
1. Cuatro preguntas aritméticas 1
2. Cuatro preguntas aritméticas 2
......

Entre ellos, el puntaje verdadero está en el siguiente formato cuando se ingresa y sale: el puntaje verdadero de tres quintos se expresa como 3/5, y el puntaje verdadero de dos y octavos se expresa como 2'3 / 8.

  1. Mientras genera las preguntas, calcule las respuestas a todas las preguntas y guárdelas en el archivo Answers.txt en el directorio actual del programa en ejecución, en el siguiente formato:

1. Respuesta 1
2. Respuesta 2

En particular, el cálculo de la puntuación real se muestra en el siguiente ejemplo: 1/6 + 1/8 = 7/24.

  1. El programa debería ser capaz de soportar la generación de 10,000 preguntas.

  2. El programa admite el archivo de preguntas y el archivo de respuestas dados para determinar lo correcto y lo incorrecto en la respuesta y para contar el número. Los parámetros de entrada son los siguientes:
    Myapp.exe -e <exercisefile>.txt -a <answerfile>.txt

Los resultados estadísticos se envían al archivo Grade.txt en el siguiente formato:
Correcto: 5 (1, 3, 5, 7, 9)
Incorrecto: 5 (2, 4, 6, 8, 10)

El número 5 después de ":" indica el número de preguntas correctas / incorrectas, y el número de preguntas correctas / incorrectas está entre paréntesis. En aras de la simplicidad, se supone que las preguntas de entrada son todas preguntas numeradas que cumplen con las especificaciones.


Segundo, las dificultades encontradas y las soluciones.

(1) Cómo llevar a cabo la programación de pares
Antes de que comenzara el proyecto, tuvimos una discusión de más de una hora, aclaramos las ideas y llevamos a cabo el diseño general y la planificación del proyecto, y luego asignamos los módulos de los que fuimos responsables y escribimos Archivo de interfaz para desarrollo de proyectos.
En el proceso de programación, si encontramos dudas o sentimos que hay discrepancias en nuestras ideas, nos comunicaremos a WeChat a tiempo para asegurar el progreso normal del proyecto.
Después de completar la escritura del código, primero verificamos nuestro propio código y módulo de prueba, y luego integramos el código y lo enviamos a la otra parte para que la otra parte lo revise. En la operación real, hemos encontrado muchos errores entre nosotros.

(Dos)


3. Código clave y descripción del diseño

Diseño general
Inserte la descripción de la imagen aquí

Definición de datos

typedef struct variable
{
	int num_or_Symbol;		 //0是数字1是符号
	int Symbol = -1;		//    + - * % ( ) 分别表示为 0 1 2 3 4 5
	int numer;				//如果是数字此为分子
	int Den = 1;			//如果是数字此为分母
	int num;

	bool operator == (variable c){
		return num_or_Symbol == c.num_or_Symbol && Symbol == c.Symbol && numer == c.numer && Den == c.Den && num == c.num;
	}
}var;

Las partes principales son las siguientes

//生成表达式函数
Status Create(var** exp, int size, int *length);
//计算表达式函数
Status Calculation(var* exp, int size, var* result, int length);
//中缀表达式转后缀表达式
Status Infix_to_Postfix(var* p, int size, var* Postfix, int length, int& postLen);
//判断两个问题是否等价
Status is_question_same(var* Question, int lenQuest, var* newQuestion, int lenNewQuest, int size);
//m指令的执行
void M_instructions(var** expression, int amount, int size, var* result);
//判断对错
void Correction(int* save, char* answerfile, char* exercisefile);

Código clave

Status Create(var** exp, int size, int* length) 
{
	var* expre;
	int mark_num = random(1, 4);//计算符个数
	int pre = 0;//前括号在第pre个数字前
	int aft = 0;//后括号在第aft个数字后
	int judge = 0;//判断,0写入数字,1写入符号
	int n = 0;
	*length = mark_num + mark_num + 1;
	n = 0;
	if (mark_num > 1)//如果运算符有3个,则存在括号
	{
		pre = random(1, mark_num);
		if(pre == 1)//不让括号括住整个式子
			aft = random((pre + 1), (mark_num + 1));
		else
			aft = random((pre + 1), (mark_num + 2));
		(*length) += 2;
		expre = new var[*length + 1];
		expre[pre * 2 - 2].num_or_Symbol = 1;
		expre[pre * 2 - 2].Symbol = 4;
		expre[aft * 2].num_or_Symbol = 1;
		expre[aft * 2].Symbol = 5;
	}
	else
	{
		expre = new var[*length + 1];
	}
	n = 0;
	while (n < *length)
	{
		if (expre[n].Symbol < 4)
		{
			if (judge == 0)
			{
				expre[n].num_or_Symbol = 0;
				expre[n].Den = random(2, size);
				expre[n].numer = random(0, expre[n].Den);
				expre[n].num = random(1, size);
				judge = 1;
			}
			else
			{
				expre[n].num_or_Symbol = 1;
				expre[n].Symbol = random(0, 4);
				judge = 0;
			}
		}
		n++;
	}
	*exp = expre;
	return SUCCESS;
}
Status Infix_to_Postfix(var* p, int size, var* Postfix, int length, int& postLen)
{
	//传入的postfix要记得为空
	var stack[maxn];
	int top = 0;
	for (int i = 0; i < length; i++)
	{
		if (p[i].num_or_Symbol == 0)//是数字
		{
			Postfix[postLen++] = p[i];//放入输出串中
		}
		if (p[i].num_or_Symbol == 1 && p[i].Symbol == 4)//左括号
		{
			++top;
			stack[top] = p[i];
		}
		while (p[i].num_or_Symbol == 1 && p[i].Symbol != 4 && p[i].Symbol != 5)
		{
			if (top == 0 || stack[top].Symbol == 4 || prio(p[i]) > prio(stack[top]))
			{
				++top;
				stack[top] = p[i];
				break;
			}
			else
			{
				Postfix[postLen++] = stack[top];
				top--;
			}
		}
		if (p[i].num_or_Symbol == 1 && p[i].Symbol == 5)//右括号
		{
			while (stack[top].Symbol != 4)
			{
				Postfix[postLen++] = stack[top];
				top--;
			}
			top--;
		}
	}
	while (top != 0)
	{
		Postfix[postLen++] = stack[top--];
	}
	return SUCCESS;
}
Status is_postfix_same(var* Question, int lenQuest, var* newQuestion, int lenNewQuest, int size)
{
	var Postfix1[maxn], Postfix2[maxn];
	var stack1[3][3], stack2[3][3];
	int len1 = 0, len2 = 0, sta_size1 = 0, sta_size2 = 0;

	//获取后缀表达式
	Infix_to_Postfix(Question, size, Postfix1, lenQuest , len1);
	Infix_to_Postfix(newQuestion, size, Postfix2, lenNewQuest, len2);

	//获取子表达式
	get_Subexpression(Postfix1, len1, stack1, sta_size1);
	get_Subexpression(Postfix2, len2, stack2, sta_size2);

	bool flag;
	for (int i = 0; i < sta_size1; i++)
	{
		flag = false;
		for (int j = 0; j < sta_size2; j++)
		{
			//短式等价
			if (cmp(stack1[i], stack2[j]))
			{
				flag = true;
				stack2[j][2].Symbol = -1;//将表达式的运算符删掉
				break;
			}
		}
		if (!flag)//如果存在不一样的,返回not same
		{
			return ERROR;
		}
	}
	return SUCCESS;
}
void M_instructions(var **expression, int amount, int size, var* result)
{
	fstream answer;
	answer.open(ANSWERFILE, ios::out | ios::app);
	var results[maxn];//后缀表达式
	int length;
	int i = 0;
	int j = 0;
	int k = 0;
	while (i < amount)
	{
		Create(&expression[i], size, &length);
		result[i].Symbol = length;
		if (Calculation(expression[i], size, results, length) == ERROR || results[0].num >= size || results[0].numer >= size || results[0].Den >= size)
		{
			continue;
		}
		result[i].Den = results[0].Den;
		result[i].num = results[0].num;
		result[i].numer = results[0].numer;
		result[i].num_or_Symbol = 0;
		result[i].Symbol = length;
		j = 0;
		while (j < i)
		{
			//结果一样,表达式可能一样
			if (result[j].Den == result[i].Den && result[j].numer == result[i].numer && result[j].num == result[i].num)
			{
				if (is_question_same(expression[i], result[i].Symbol, expression[j], result[j].Symbol, size))
				{
					break;
				}
			}
			j++;
		}
		if (i != j)
		{
			if(k ++ < 20)//连续20次重复答案表明给的size太小,而amount太大,表达式多样性不足
				continue;
		}
		Visit(expression[i], length, i + 1);

		answer << i + 1 << ".   ";
		if (result[i].numer == 0)
		{
			answer << result[i].num;
		}
		else
		{
			if (result[i].num != 0)
			{
				answer << result[i].num;
				answer << "`";
			}
			answer << result[i].numer;
			answer << "/";
			answer << result[i].Den;
		}
		answer << endl;
		i++;
		k = 0;
	}
	answer.close();
}

Cuatro, operación de prueba

Genera al azar 10 preguntas
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

Genere al azar 10 preguntas después de cambiar el valor de la pregunta
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

La prueba determina si es correcta o incorrecta después de completar la respuesta en el archivo exercisefile.txt
Inserte la descripción de la imagen aquí


5. Formulario de PSP

PSP2.1 Etapas del proceso de software personal Tiempo estimado (minutos) Tiempo real (minutos)
Planificación Plan 20 20
· Estimación · Estime cuánto tiempo llevará esta tarea 10 10
·Desarrollo · Desarrollo 120 100
· Análisis · Análisis de necesidades (incluido el aprendizaje de nuevas tecnologías) 60 60 60 60
· Especificaciones de diseño · Generar documentos de diseño. 20 20
· Revisión de diseño · Revisión de diseño (revisión de documentos de diseño con colegas) 10 10
· Estándar de codificación · Especificaciones de código (haciendo especificaciones apropiadas para el desarrollo actual) 5 5 10
· Diseño · Diseño específico 30 50
· Codificación · Codificación específica 180 200
· Revisión de código · Revisión de código 20 15
· Prueba · Prueba (autocomprobación, modificar código, enviar cambios) 20 20
Informes Informe 30 30
· Informe de prueba · Informe de prueba 20 15
· Medida del tamaño · Calcular la carga de trabajo 10 10
· Plan de mejora de procesos y autopsias · Resumen luego, y proponer un plan de mejora de procesos 30 30
Total 585 600

6. Resumen del proyecto

Resumen de Guo Yicai:
1. En este proyecto, completamos cada tarea con mayor eficiencia a través de la programación de pares, el estímulo mutuo y la supervisión mutua. Reconocimos plenamente los beneficios de la programación de pares y entendimos su efectividad en la eficiencia de la programación y la verificación de errores. Gran efecto Por supuesto, también aprendí sus deficiencias , especialmente en el entorno objetivo de comunicación inconveniente durante la epidemia, la dificultad de comunicación también ha aumentado considerablemente, pero gracias a la función de pantalla compartida de la conferencia web, la conveniencia del teléfono WeChat, la comunicación del paciente con el paciente y la discusión activa y otros factores , Las deficiencias de la programación de pares también se han complementado enormemente.
2. En el curso del proyecto, aprendí cómo convertir expresiones de infijo en expresiones de sufijo, las reglas para calcular expresiones de sufijo y los métodos para determinar si las dos preguntas son equivalentes . También aprendí a escribir más estandarizado Interfaz de documentos, el recibo es bastante abundante.
3. Además, la interfaz gráfica todavía se está estudiando, y solo se puede hacer una interfaz simple, que no cumple con los requisitos de la parte de expansión del proyecto. Esto es un pequeño arrepentimiento. También es necesario inspirarse para aprender y dominar el conocimiento más rápido y mejor Para completar los requisitos del proyecto.
4. Finalmente, agradezco a mi compañero Chen Yu nuevamente.

Chen Yu Resumen:
1, este proyecto es la primera vez que trabajamos juntos para completar el proyecto por el método de programación de conexiones para la programación, y completar de manera muy eficiente los requisitos del proyecto , en el camino hubo muchos puntos de desacuerdo , pero a través de la programación en parejas Podemos debatir y unificar nuestras opiniones de manera oportuna, para que no se pierda demasiado tiempo en lugares innecesarios .
2. Originalmente, quería que el usuario completara la respuesta en el programa, pero debido a que no pensé en una mejor forma interactiva, al final no implementé esta función, y solo dejé que el usuario completara la respuesta manualmente en el archivo txt.
3. Finalmente, ¡es realmente cómodo trabajar con el líder de Yicai! !


7. Fuente de referencia

[1] Polaco, polaco inverso y evaluación de expresión

Supongo que te gusta

Origin www.cnblogs.com/Authur-gyc/p/12683512.html
Recomendado
Clasificación