Sword se refiere a la matriz de oferta-2.1

formación

Se puede decir que la matriz es la estructura de datos más simple: ocupa una memoria continua y almacena los datos en orden. Al crear una matriz, primero debemos especificar la capacidad de la matriz y luego asignar memoria según el tamaño. Incluso si solo almacenamos un número en la matriz, necesitamos preasignar memoria para todos los datos. Por lo tanto, la eficiencia espacial de las matrices no es muy buena y, a menudo, hay áreas libres que no se utilizan por completo.

Dado que la memoria en la matriz es continua, cualquier elemento se puede leer/escribir en tiempo O (1) según el subíndice, por lo que su eficiencia temporal es muy alta. Podemos usar matrices para implementar una tabla hash simple basándonos en la ventaja de la alta eficiencia temporal de las matrices: establezca el subíndice de la matriz en el valor clave (Clave) de la tabla hash y establezca cada número en la matriz en una tabla hash. El valor (Valor), de modo que cada subíndice y el número correspondiente al subíndice en la matriz formen un par clave-valor. Con dicha tabla hash, podemos implementar búsquedas en O(1), resolviendo así muchos problemas de forma rápida y eficiente.

Para resolver el problema de la baja eficiencia del espacio de la matriz, las personas han diseñado e implementado una variedad de matrices dinámicas, como las vectoriales en STL de C++. Para evitar desperdicios, primero abrimos un espacio más pequeño para la matriz y luego agregamos datos a la matriz. Cuando la cantidad de datos excede la capacidad de la matriz, reasignamos un espacio más grande (cada vez que el vector STL expande su capacidad, la nueva capacidad es el doble de la anterior) y copiamos los datos anteriores a la nueva matriz. Liberar la memoria anterior, para reducir el desperdicio de memoria. Pero también notamos que hay muchas operaciones adicionales cada vez que se expande la capacidad del arreglo, lo que tiene un impacto negativo en el rendimiento del tiempo. Por lo tanto, cuando usamos arreglos dinámicos, debemos tratar de minimizar la cantidad de veces que cambiamos la capacidad del arreglo. tamaño.

En C/C++, las matrices y los punteros son dos conceptos relacionados pero diferentes entre sí. Cuando declaramos una matriz, el nombre de la matriz también es un puntero que apunta al primer elemento de la matriz. Podemos acceder a la matriz usando un puntero. Sin embargo, vale la pena señalar que C/C++ no registra el tamaño de la matriz, por lo que cuando se utilizan punteros para acceder a elementos de la matriz, los programadores deben asegurarse de que no se excedan los límites de la matriz. Usemos un ejemplo para comprender la diferencia entre matrices y punteros. Ejecute el siguiente código, ¿cuál es el resultado?

int GetSize(int data[])
{
    
    
    return sizeof(data);
}

int main(int argc, char* argv[])
{
    
    
     int data[] = {
    
    1,2,3,4,5};
     int size1 = sizeof(data1);
     int* data2 = data1;
     int size2 = sizeof(data2);
     int size3 = GetSize(data1);
     printf("%d, %d, %d", size1, size2, size3);
}

La respuesta es generar "20,4,4". data1 es una matriz, sizeof (data1) es encontrar el tamaño de la matriz. Esta matriz contiene 5 números enteros, cada uno de los cuales ocupa 4 bytes, por lo que el total es 20 bytes. data2 se declara como un puntero y, aunque apunta al primer número de la matriz data1, su esencia sigue siendo un puntero. En un sistema de 32 bits, si se realiza sizeof en cualquier puntero, el resultado siempre será 4. En C/C++, cuando se pasa una matriz como parámetro de una función, la matriz degenera automáticamente en un puntero del mismo tipo. Por lo tanto, aunque los datos del parámetro de la función GetSize se declaran como una matriz, degenerarán en un puntero y el resultado de size3 sigue siendo 4.

Buscar en una matriz bidimensional

Pregunta: En una matriz bidimensional, cada fila se ordena en orden creciente de izquierda a derecha y cada columna se ordena en orden creciente de arriba a abajo. Complete una función, ingrese una matriz bidimensional y un número entero, y determine si la matriz contiene el número entero.

Por ejemplo, la siguiente matriz bidimensional está ordenada en orden ascendente en cada fila y columna. Si busca el número 7 en esta matriz, devuelve verdadero; si busca el número 5, devuelve falso porque la matriz no contiene el número.

1  2  8  9
2  4  9  12
4  7  10 13
6  8  11 15

Al analizar este problema, muchos candidatos dibujarán una matriz bidimensional en un rectángulo, luego seleccionarán un número de la matriz y analizarán el proceso de búsqueda en tres situaciones. Cuando el número seleccionado en la matriz es exactamente igual al número a encontrar, el proceso de búsqueda finaliza. Si el número seleccionado es menor que el número que se va a encontrar, entonces, de acuerdo con las reglas de clasificación de la matriz, el número que se va a encontrar debe estar a la derecha o debajo de la posición seleccionada actualmente (como se muestra en la Figura 2.1 (a)). De manera similar, si el número seleccionado es mayor que el número a encontrar, entonces el número a encontrar debe estar arriba o a la izquierda de la posición seleccionada actualmente (como se muestra en la Figura 2.1 (b)).
Insertar descripción de la imagen aquí
Nota: Seleccione un número (cuadrado oscuro) en el medio de la matriz y juzgue el área (área sombreada) donde puede aparecer el número que desea encontrar en función de su tamaño.

En el análisis anterior, dado que el número a encontrar puede aparecer en dos áreas en relación con la posición actualmente seleccionada, y las dos áreas se superponen, el problema parece complicado, por lo que muchas personas se quedan atrapadas aquí.

Cuando necesitamos resolver un problema complejo, una forma muy efectiva es comenzar con un problema específico e intentar encontrar reglas universales analizando ejemplos simples y específicos. Para abordar esta cuestión, también podríamos comenzar con un ejemplo específico. Tomemos el ejemplo de encontrar el número 7 en la matriz dada en la pregunta para analizar el proceso de búsqueda paso a paso.

La razón por la que encontramos un problema antes es que seleccionamos un número en el medio de la matriz bidimensional para compararlo con el número que estamos buscando, lo que resultó en dos áreas superpuestas para buscar la próxima vez. ¿No sería más fácil si seleccionamos un número de una esquina de la matriz para compararlo con el número que estamos buscando?

Primero seleccionamos el número 9 en la esquina superior derecha de la matriz. Dado que 9 es mayor que 7 y 9 es el primer número (y el más pequeño) de la columna 4, el 7 no puede aparecer en la misma columna que el número 9. Por lo tanto, eliminamos esta columna del área que debe considerarse y luego solo necesitamos analizar las tres columnas restantes (como se muestra en la Figura 2.2 (a)). En la matriz restante, el número en la esquina superior derecha es 8. De manera similar, 8 es mayor que 7, por lo que también podemos eliminar la columna donde se encuentra 8. A continuación sólo necesitamos analizar las dos columnas restantes (como se muestra en la Figura 2.2(b)).

En la matriz que consta de las dos columnas restantes, el número 2 se encuentra en la esquina superior derecha de la matriz. 2 es menor que 7, entonces el 7 que desea encontrar puede estar a la derecha de 2 o puede estar debajo de 2. En los pasos anteriores, encontramos que las columnas a la derecha de ⒉ han sido eliminadas, lo que significa que 7 no puede aparecer a la derecha de 2, por lo que 7 solo puede aparecer debajo de 2. Así que también eliminamos la fila donde se encuentra el número 2 y solo analizamos las tres filas y dos columnas de números restantes (como se muestra en la Figura 2.2©). Entre los números restantes, en la esquina superior derecha se encuentra el número 4. Como antes, eliminamos la fila donde se encuentra el número 4, dejando dos filas y dos columnas de números (como se muestra en la Figura 2.2 (d)).

Entre los cuatro números de las dos filas y dos columnas restantes, el de la esquina superior derecha resulta ser el número 7 que estamos buscando, por lo que se puede finalizar el proceso de búsqueda.
Insertar descripción de la imagen aquí
Nota: El área con fondo sombreado en la matriz es el siguiente rango de búsqueda.

Resumiendo el proceso de búsqueda anterior, encontramos las siguientes reglas: primero seleccione el número en la esquina superior derecha de la matriz. Si el número es igual al número que buscas, el proceso de búsqueda finaliza; si el número es mayor que el número que buscas, elimina la columna donde se encuentra el número; si el número es menor que el número que estás buscando buscando, elimine la fila donde se encuentra el número. Es decir, si el número a encontrar no está en la esquina superior derecha de la matriz, cada vez se eliminará una fila o columna del rango de búsqueda de la matriz, de modo que el rango de búsqueda se pueda reducir en cada paso. hasta que se encuentre el número a encontrar, o el rango de búsqueda sea nulo.

Después de analizar claramente todo el proceso de búsqueda, no nos resulta difícil escribir código. El siguiente es el código de referencia correspondiente a las ideas anteriores:

ejemplo de código

#include <cstdio>

bool Find(int* matrix, int rows, int columns, int number)
{
    
    
	bool found = false;

	if (matrix != nullptr && rows > 0 && columns > 0)
	{
    
    
		int row = 0;
		int column = columns - 1;
		while (row < rows && column >= 0)
		{
    
    
			if (matrix[row * columns + column] == number)
			{
    
    
				found = true;
				break;
			}
			else if (matrix[row * columns + column] > number)
				--column;
			else
				++row;
		}
	}

	return found;
}

// ====================测试代码====================
void Test(const char* testName, int* matrix, int rows, int columns, int number, bool expected)
{
    
    
	if (testName != nullptr)
		printf("%s begins: ", testName);

	bool result = Find(matrix, rows, columns, number);
	if (result == expected)
		printf("Passed.\n");
	else
		printf("Failed.\n");
}

//  1   2   8   9
//  2   4   9   12
//  4   7   10  13
//  6   8   11  15
// 要查找的数在数组中
void Test1()
{
    
    
	int matrix[][4] = {
    
     {
    
    1, 2, 8, 9}, {
    
    2, 4, 9, 12}, {
    
    4, 7, 10, 13}, {
    
    6, 8, 11, 15} };
	Test("Test1", (int*)matrix, 4, 4, 7, true);
}

//  1   2   8   9
//  2   4   9   12
//  4   7   10  13
//  6   8   11  15
// 要查找的数不在数组中
void Test2()
{
    
    
	int matrix[][4] = {
    
     {
    
    1, 2, 8, 9}, {
    
    2, 4, 9, 12}, {
    
    4, 7, 10, 13}, {
    
    6, 8, 11, 15} };
	Test("Test2", (int*)matrix, 4, 4, 5, false);
}

//  1   2   8   9
//  2   4   9   12
//  4   7   10  13
//  6   8   11  15
// 要查找的数是数组中最小的数字
void Test3()
{
    
    
	int matrix[][4] = {
    
     {
    
    1, 2, 8, 9}, {
    
    2, 4, 9, 12}, {
    
    4, 7, 10, 13}, {
    
    6, 8, 11, 15} };
	Test("Test3", (int*)matrix, 4, 4, 1, true);
}

//  1   2   8   9
//  2   4   9   12
//  4   7   10  13
//  6   8   11  15
// 要查找的数是数组中最大的数字
void Test4()
{
    
    
	int matrix[][4] = {
    
     {
    
    1, 2, 8, 9}, {
    
    2, 4, 9, 12}, {
    
    4, 7, 10, 13}, {
    
    6, 8, 11, 15} };
	Test("Test4", (int*)matrix, 4, 4, 15, true);
}

//  1   2   8   9
//  2   4   9   12
//  4   7   10  13
//  6   8   11  15
// 要查找的数比数组中最小的数字还小
void Test5()
{
    
    
	int matrix[][4] = {
    
     {
    
    1, 2, 8, 9}, {
    
    2, 4, 9, 12}, {
    
    4, 7, 10, 13}, {
    
    6, 8, 11, 15} };
	Test("Test5", (int*)matrix, 4, 4, 0, false);
}

//  1   2   8   9
//  2   4   9   12
//  4   7   10  13
//  6   8   11  15
// 要查找的数比数组中最大的数字还大
void Test6()
{
    
    
	int matrix[][4] = {
    
     {
    
    1, 2, 8, 9}, {
    
    2, 4, 9, 12}, {
    
    4, 7, 10, 13}, {
    
    6, 8, 11, 15} };
	Test("Test6", (int*)matrix, 4, 4, 16, false);
}

// 鲁棒性测试,输入空指针
void Test7()
{
    
    
	Test("Test7", nullptr, 0, 0, 16, false);
}

int main(int argc, char* argv[])
{
    
    
	Test1();
	Test2();
	Test3();
	Test4();
	Test5();
	Test6();
	Test7();

	return 0;
}

En el análisis anterior, seleccionamos el número de la esquina superior derecha dentro del rango de búsqueda de matriz cada vez. Del mismo modo, también podemos seleccionar el número de la esquina inferior izquierda. Es posible que los lectores interesados ​​deseen analizar el proceso de búsqueda seleccionando la esquina inferior izquierda cada vez. Pero no podemos seleccionar la esquina superior izquierda o la esquina inferior derecha. Tomando la esquina superior izquierda como ejemplo, el número inicial 1 se encuentra en la esquina superior izquierda de la matriz inicial. Dado que 1 es menor que 7, 7 debe ubicarse a la derecha o debajo de 1. En este momento, no podemos eliminar la fila donde se encuentra 1 ni la columna donde se encuentra 1 del rango de búsqueda, por lo que no podemos limitar el rango de búsqueda.

caso de prueba

1) La matriz bidimensional contiene el número a buscar (el número a buscar es el valor máximo y el valor mínimo en la matriz, y el número a buscar está entre el valor máximo y el valor mínimo en la matriz).
2) No hay ningún número buscado en la matriz bidimensional (el número buscado es mayor que el valor máximo en la matriz, el número buscado es menor que el valor mínimo en la matriz, el número buscado está entre el valor máximo y el valor mínimo de la matriz pero no existe tal número en la matriz).
3) Prueba de entrada especial (puntero nulo de entrada).

Puntos de prueba

Las matrices bidimensionales ocupan espacios contiguos en la memoria. Almacene elementos en cada fila en la memoria de arriba a abajo y en la misma fila en orden de izquierda a derecha. Por lo tanto, podemos calcular el desplazamiento relativo a la primera dirección de la matriz en función del número de fila y el número de columna para encontrar el elemento correspondiente.

Cuando los candidatos encuentran que el problema es complejo, la clave para resolver el problema es si pueden descubrir las reglas a través de ejemplos específicos. Siempre que comience a analizar este problema desde la esquina superior derecha de una matriz bidimensional específica, podrá encontrar el patrón de búsqueda y encontrar un gran avance para resolver el problema.

Supongo que te gusta

Origin blog.csdn.net/qq_36314864/article/details/132296018
Recomendado
Clasificación