El diario de aprendizaje "6.4 Notas del algoritmo" mapea detalles de uso común

6.4 Explicación detallada del uso común del mapa

ID de concurso de Codeup: 100000599

Pregunta A: Patrones del habla (25)

题目 描述 Las
personas a menudo tienen preferencia entre sinónimos de la misma palabra. Por ejemplo, algunos pueden preferir "la policía", mientras que otros prefieren "la policía". Analizar tales patrones puede ayudar a reducir la identidad de un hablante, lo cual es útil al validar, por ejemplo, si sigue siendo la misma persona detrás de un avatar en línea.
Ahora, dado un párrafo de texto muestreado del discurso de alguien, ¿puede encontrar la palabra más utilizada por la persona?
输入
Cada archivo de entrada contiene un caso de prueba. Para cada caso, hay una línea de texto de no más de 1048576 caracteres de longitud, terminada por un retorno de carro '\ n'. La entrada contiene al menos un carácter alfanumérico, es decir, un carácter del conjunto [0-9 AZ az].
输出
Para cada caso de prueba, imprima en una línea la palabra más común en el texto de entrada, seguida de un espacio y el número de veces que ha ocurrido en la entrada. Si hay más de una de esas palabras, imprima la lexicografía más pequeña. La palabra debe estar impresa en minúsculas. Aquí una "palabra" se define como una secuencia continua de caracteres alfanuméricos separados por caracteres no alfanuméricos o la línea de inicio / fin.
Tenga en cuenta que las palabras no distinguen entre mayúsculas y minúsculas .
样例 输入

Can1: "Can a can can a can?  It can!"

Salida de muestra

can 5

Las ideas
generalmente significa que este problema es hacer que un recuento de palabras (nota que la palabra aquí no es el contenido de las comillas dobles está todo el contenido de la cadena) dentro de la palabra con mayor frecuencia se produce cuando el número de palabras no es sensible a mayúsculas , Pero las palabras deben estar en minúsculas cuando salen, y si hay varias palabras con el mismo número de veces, se genera la que tiene el orden lexicográfico más pequeño.

Esta pregunta obviamente necesita establecer una relación de mapeo de hash. Imagine que si puedo usar todas las palabras que aparecen en una oración como subíndice y el contenido como el número de ocurrencias, siempre que el contenido de salida sea el subíndice y el valor más grandes Es la respuesta Antes de la cadena correspondiente al hash entero, utilizamos el método de 26 a 10 decimales. Si olvida cómo escribir la función hash, puede usar map para hacerlo, lo que será mucho más conveniente (como esta pregunta) ~

Obviamente, debemos establecer el mapeo entre string e int, entonces, cómo obtener cada palabra (la definición de la palabra en el título es una cadena de letras y números consecutivos, como Can1 en la muestra también es una palabra), I Con referencia a las ideas de Liu Shen, se utilizan la función isalnum () (para determinar si es una letra o un número) y la función tolower () (en minúsculas) en la muy conveniente biblioteca estándar C <ctype.h> (o <cctype>). Hay muchas funciones en esta biblioteca, puede ver el tutorial para novatos para más detalles:

C Biblioteca estándar- <ctype.h>

De hecho, si conoce el uso de esta biblioteca y las funciones clave en ella, esta pregunta es muy simple. Solo necesita determinar si cada bit de la cadena es un carácter o un número desde el principio. Si lo es, conéctelo a la cadena temporal tmp ( La adición de cadena + = operación permite conectar la cadena y la cadena), hasta que el siguiente dígito no sea un carácter o número, luego agregue 1 al valor en el mapa (mp [tmp] ++) , Y vacíe la cadena temporal tmp, que se usa para prepararse para concatenar la siguiente palabra.

La operación anterior está bien para la mayoría de las muestras, pero Codeup responderá mal 83, y PAT también tiene 23 puntos (la última muestra no puede pasar el punto). Sin embargo, este no es un gran problema. Por supuesto, podemos encontrarlo con cuidado:

La entrada contiene al menos un carácter alfanumérico, es decir, un carácter del conjunto [0-9 AZ az].

Ver el mensaje clave:Al menos un carácter alfanumérico. Es decir, es posible que el último ejemplo sea escribir solo un número 1 o solo una letra a, luego nuestro método de juicio anterior es que mp [tmp] ++ no se lleva a cabo hasta que el siguiente dígito no sea una letra y un número , Y borre el funcionamiento de la cadena tmp. Si solo se ingresan caracteres alfanuméricos aquí, no existe el siguiente dígito que no sea alfanumérico, por lo que no se establecerá ninguna relación de mapeo en el mapa.

Por lo tanto, debemos hacer un juicio especial sobre si el último dígito de la cadena no es un carácter alfabético . Si todavía es un carácter alfabético, entonces conectaré mp [tmp] ++ y borraré la cadena directamente después de que tmp esté conectado esta vez. Si terminamos el ciclo, ya hemos puesto las palabras que debemos poner en el mapa.

Además, cuando se busca el valor máximo, es mejor no usar la sintaxis de asignación de iterador. Primero declare una temperatura de iterador, y luego cada vez que se actualiza el valor máximo, el iterador actual se asigna a temp, y finalmente siempre que sea temporal -> first y temp-> second puede obtener la clave y el valor correspondiente al valor máximo. Aunque esta sintaxis para los primeros pocos puntos de prueba no son un problema, pero al final un punto de prueba se producirá errores , es decir, en Codeup error de ejecución . Por lo tanto, intente declarar dos variables correspondientes a la clave y el valor para almacenar la clave y el valor correspondiente al valor máximo, a fin de evitar varios problemas transfronterizos.
Código

#include<cstdio>
#include<cctype>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<iostream>
using namespace std;
map<string, int> mp;
int main(){
	string a;
	while(getline(cin, a)){//想要用cin读入空格需要用getline(C语言中是gets) 
		string tmp;
		for(int i=0;i<a.length();i++){
			if(isalnum(a[i])&&i!=a.length()-1){//如果当前位是字母和数字且不是最后一位 
				a[i] = tolower(a[i]);//转换为小写 
				tmp += a[i];//给tmp串上当前字符 
				continue;//继续下一轮循环 
			}
			if(isalnum(a[i])&&i==a.length()-1){//如果最后一位还是字母和数字 
				a[i] = tolower(a[i]);
				tmp += a[i];
				mp[tmp]++;
				tmp.clear();
			} 
			if(tmp.length()!=0){//如果tmp不为空(这里是为了防止下一次还是非字母数字时,执行mp[tmp]++的操作)
				mp[tmp]++;
				tmp.clear();	
			}
		}
		int max = 0;
		string keymax;
		for(map<string, int>::iterator it = mp.begin();it!=mp.end();it++){
			if(it->second>max){//如果键的值大,则更新max的值 
				keymax = it->first;
				max = it->second;
			}
		}
		cout<<keymax<<" "<<max<<endl;
		mp.clear();
	}
	return 0;
}

Resumen

Creo que la mayor dificultad en esta pregunta es pensar en el uso de la función de biblioteca C isalnum (). Si no conoce esta función, es bastante problemático recorrer una por una para encontrar las palabras (y minúsculas), y recordarme aquí Propio : para este tipo de tema usando map, puede declarar una cadena temporal tmp para realizar la operación de concatenación, y luego simplemente ponerla directamente en el mapa después de la concatenación. Pensé en cortar todas las palabras al principio, y luego otra. Uno se pone en el mapa, esta es obviamente una operación un poco estúpida _ (: з 」∠) _

Así que aquí sugiero que puede echar un vistazo a las bibliotecas estándar de C y C ++ cuando no está haciendo nada. Quizás haya encontrado una función de hada muy conveniente que puede usarse (como el conjunto de anteayer en realidad tiene la función de encapsulación del conjunto de intersección).

En general, map nos proporciona un buen contenedor para el mapeo hash. Por lo general, encontramos el problema de un número entero correspondiente a un carácter o cadena, que se puede resolver con map, lo que ahorra espacio y es conciso. Código

Publicado 54 artículos originales · ganó 27 · vistas 4987

Supongo que te gusta

Origin blog.csdn.net/weixin_42257812/article/details/105286173
Recomendado
Clasificación