Experiencia en la depuración de C ++ Primer ejercicio 3.26

Originalmente, se trataba de juzgar si era legal (Versión en inglés, página 113). Originalmente pensé que la causa del error era que beg + end excedía el rango del vector. Después de la compilación, descubrí que el error era en realidad que la operación + no estaba definida en absoluto. Esto encarna la importancia de los programas codificados a mano.
Mi definición de mediana dicotómica no es la misma que en el libro, el libro es en realidad la mediana o la derecha de las dos medianas. Tengo problemas para definirlo como el valor mediano o el lado izquierdo de los dos valores medianos (porque prefiero el lado izquierdo). Como resultado, causó discusiones problemáticas en las líneas 34-49 del programa (simplemente mal, no quiero cambiar la definición de medio).

#include <iostream>
#include <vector>
#include <algorithm>
using std::cin;
using std::cout;
using std::cerr;
using std::endl;
using std::vector;
using std::sort;

int main()
{
    
    
	vector<int> vint;
	int i;
	int seek;
	cout << "Please input the number you seek:" << endl;
	cin >> seek;
	cout << "Please input numbers from where you want to seek a certain number:" << endl;
	while (cin >> i)
		vint.push_back(i);
	sort(vint.begin(),vint.end());
	// The next three lines are used for test in terms of the numbers after sorting.
	cout << endl;
	for (auto c : vint) cout << c << " "; // show the contents of 'vint'
	cout << endl;
	auto beg = vint.cbegin();
	auto end = vint.cend(); // Remember that 'end' is one off the end.
	auto mid = beg + (end - beg + 1) / 2 - 1; // 'mid' is at the middle or the first (left) one of the two middle ones.
	cout << beg - vint.cbegin() << " " << mid - vint.cbegin() << " " << end - vint.cbegin() << endl;
	cout << "*mid= " << *mid << endl;
	while (mid != end && *mid != seek)
	{
    
    
		// This 'if' aims to move 'mid' to the next place as when there are only 2 elements, 'mid' remains still.
		if (end - mid != 2)
		{
    
    
			if (seek < *mid) end = mid;
		    else beg = mid + 1;
			mid = beg + (end - beg + 1) / 2 - 1;
		}
		else
		{
    
    
			if (*(mid + 1) == seek) // move 'mid' to the next place
				mid += 1;
			else
			{
    
    
    			cerr << "Sorry, there is no " << seek << "." << endl; // to indicate there's no that number
    			return -1;
			}
		}
		// The next two lines are used for test in terms of the current place and value of 'mid'.
		cout << beg - vint.cbegin() << " " << mid - vint.cbegin() << " " << end - vint.cbegin() << endl;
		cout << "*mid= " << *mid << endl;
	}
	// Check whether the one we find is the first of all. If not, move to the number to its left.
	while (*(mid - 1) == seek && (mid - vint.cbegin()) != 0)
		mid -= 1;
	// The next line is used for test in terms of the final place and value of 'mid'.
	cout << "*mid, &mid= " << *mid << "," << mid - vint.begin() << '\n' << endl;
	// The place needs to plus one as the place in vector begins at 0, while we need it at 1.
	cout << "The number " << seek << " is in No." << mid - vint.cbegin() + 1 << " place." << endl;
	return 0;
}

Aquí hay algunas experiencias incorrectas:

Olvidé redefinir la mitad de la línea 38

En realidad, este es el problema del pensamiento inconsistente. Al entrar en la segunda ronda del ciclo while, se deben preparar todos los pasos para el inicio, la mitad y el final. (Una cuestión de alfabetización)

II Líneas 33-49 olvídate de clasificar y discutir

Todavía hay un problema con el programa, así que enumeré la situación en el borrador del documento y descubrí que cuando se bloquea dentro de dos valores, mid permanecerá en la misma posición y ya no se moverá (permanecerá quieto), por lo que a veces caerá en una mala muerte durante el experimento. ciclo. Tan parcheado con una declaración if.
Sin embargo, ¡todavía hay problemas con el programa! ! !

III Uso incorrecto de ++ en la línea 42

El descubrimiento de este problema se benefició de la prueba intermedia que dio como resultado la conclusión intermedia, y luego en una prueba se encontró que las posiciones inicial, media y final saltaron directamente de 6 6 8 a 6 8 8. Es extraño, es obvio que mid + = 1, entonces, ¿cómo es que consigues dos lugares a la vez?
Prueba
Después de la inspección, se encontró que ++ se usó incorrectamente en la declaración if (esto es un error e impresionante) .Aunque era una declaración de juicio, el mid fue efectivamente cambiado.
(En realidad , hay una explicación más detallada en C ++ Primer 4.5 Operadores de incremento y decremento ).

IV Uso incorrecto de la línea 55--

Del mismo modo, también funciona en mid.

La salida de la línea V 60 olvida +1

Esto también es un problema muy serio, la razón es que la posición del vector comienza en 0, pero comenzamos a contar desde 1, por lo que la posición contada por mid-vint.begin () será 1 peor, lo que hará que el resultado sea incorrecto. (También encontré problemas de los datos intermedios experimentales)

Conclusión

1. Es beneficioso pensar más. Aunque tomó algún tiempo encontrar errores, también fue un proceso de mejora.
2. La alfabetización lógica es muy importante. La estructura debe ser clara, no desordenada, o lo que está en su mente no se refleja en el programa.
3. Aproveche al máximo el resultado de la conclusión intermedia. Este es un buen mensaje de error que nos permite prescribir el medicamento adecuado para hacer frente al fenómeno de que un determinado parámetro es diferente de lo que esperábamos. Al mismo tiempo, varios conjuntos de experimentos nos permiten resumir las reglas, lo que puede apuntar a errores.
4. El concepto debe ser claro. El libro C ++ Primer todavía tiene mucho análisis de conceptos. Una comprensión y memoria completas de esto le ayudará a no cometer errores fatales que el compilador no puede detectar (como ++ y - aquí).


Ver también

Página de navegación de Teddy van Jerry
[Ejercicio básico de C ++ (5ª edición)] Programa de ejercicios-Capítulo 3 (Capítulo 3)

Supongo que te gusta

Origin blog.csdn.net/weixin_50012998/article/details/108146684
Recomendado
Clasificación