Contando Office ocurrencias -- ++ campo con stl camp codereview Relacionados El problema

Counting word occurences


6
vote

problema

Español

Este es un programa simple de conteo de palabras que escribí para jugar y familiarizarse con el uso de 9988776655544331 . ¿Hay algo que pueda mejorar?

No usé Ctrl + z para detener el programa porque eso suspende el proceso en Linux.

  #include <iostream> #include <iomanip> #include <string> #include <map> #include <iterator> using std::cout; using std::cin; using std::endl; using std::string;   int main(){     std::map<string, int> words;     cout << "Enter some text. Type "***" to end." << endl;      std::istream_iterator<string> begin(cin);     std::istream_iterator<string> end;      while(begin != end){         if(*begin == string("***"))             break;         words[*begin++]++;     }     for(std::map<string,int>::iterator iter = words.begin(); iter != words.end(); ++iter)         cout << std::setw(6) << iter->second << " " << iter->first << endl;  return 0; }   

Entrada de muestra:

  engie does wut engie wants pyro mad   engie rek pyro pyro go cry deny engie u try rekt u will get   

Salida:

   1 cry  1 deny  1 does  4 engie  1 get  1 go  1 mad  3 pyro  1 rek  1 rekt  1 try  2 u  1 wants  1 will  1 wut   
Original en ingles

This is a simple word count program I wrote to play around and get familiar with using std::map. Is there anything I can improve upon?

I didn't use CTRL+Z to stop the program because that suspends the process on Linux.

#include <iostream> #include <iomanip> #include <string> #include <map> #include <iterator> using std::cout; using std::cin; using std::endl; using std::string;   int main(){     std::map<string, int> words;     cout << "Enter some text. Type "***" to end." << endl;      std::istream_iterator<string> begin(cin);     std::istream_iterator<string> end;      while(begin != end){         if(*begin == string("***"))             break;         words[*begin++]++;     }     for(std::map<string,int>::iterator iter = words.begin(); iter != words.end(); ++iter)         cout << std::setw(6) << iter->second << " " << iter->first << endl;  return 0; } 

Sample input:

engie does wut engie wants pyro mad   engie rek pyro pyro go cry deny engie u try rekt u will get 

Output:

 1 cry  1 deny  1 does  4 engie  1 get  1 go  1 mad  3 pyro  1 rek  1 rekt  1 try  2 u  1 wants  1 will  1 wut 
     
 
 

Lista de respuestas

6
 
vote
vote
La mejor respuesta
 

Extraer literales duplicados

La cadena literal "***" aparece dos veces en el código: Una vez en el mensaje útil, y otra vez cuando lo revisa. No es demasiado terrible. Pero sería mejor extraer una constante para eliminar la duplicación:

  $array = [     0 => [0, 0, 0, 0, 0],     1 => [0, 0, 0, 0, 0],     2 => [0, 0, 0, 0, 0],     3 => [0, 0, 0, 0, 0],     4 => [0, 0, 0, 0, 0], ]; 5  

Otra ventaja de esto es que solo crea $array = [ 0 => [0, 0, 0, 0, 0], 1 => [0, 0, 0, 0, 0], 2 => [0, 0, 0, 0, 0], 3 => [0, 0, 0, 0, 0], 4 => [0, 0, 0, 0, 0], ]; 6 una vez.

Tipos de alias

Algunos de los nombres de tipo son bastante largos. Recomendaría darles alias más cortos, por ejemplo:

  $array = [     0 => [0, 0, 0, 0, 0],     1 => [0, 0, 0, 0, 0],     2 => [0, 0, 0, 0, 0],     3 => [0, 0, 0, 0, 0],     4 => [0, 0, 0, 0, 0], ]; 7  

Limitar el alcance variable

Es una buena práctica para limitar las variables a sus pequeños alcances posibles. Por lo tanto, en lugar de declarar el $array = [ 0 => [0, 0, 0, 0, 0], 1 => [0, 0, 0, 0, 0], 2 => [0, 0, 0, 0, 0], 3 => [0, 0, 0, 0, 0], 4 => [0, 0, 0, 0, 0], ]; 8 y $array = [ 0 => [0, 0, 0, 0, 0], 1 => [0, 0, 0, 0, 0], 2 => [0, 0, 0, 0, 0], 3 => [0, 0, 0, 0, 0], 4 => [0, 0, 0, 0, 0], ]; 9 Variables antes del bucle, Conéctelo a un bucle 9988776665544332020 y declaro allí.

  for1  

También cambió de nombre de la variable de bucle, porque 99887766555443322 no fue un buen nombre para un iterador, y 998877766555443323 es un nombre más utilizado para Fin-OF -stream .

 

Extracting duplicated literals

The string literal "***" appears twice in the code: once in the helpful message, and another time when you check for it. It's not too terrible. But it would be better to extract to a constant to eliminate duplication:

const string endmark("***"); cout << "Enter some text. Type \"" << endmark << "\" to end." << endl;  while(begin != end){     if(*begin == endmark)         break;     words[*begin++]++; } 

Another advantage of this is that you only create string("***") once.

Alias types

Some of the type names are pretty long. I would recommend to give them shorter aliases, for example:

typedef std::map<string, int> wordsmap; typedef std::istream_iterator<string> istreamiter; 

Limiting variable scope

It's a good practice to limit variables to their smallest possible scopes. So instead of declaring the begin and end variables before the loop, convert it to a for loop and declare it there.

for (istreamiter iter(cin), eos; iter != eos;) {     if (*iter == endmark) {         break;     }     words[*iter++]++; } 

I also renamed the loop variable, because begin was not a good name for an iterator, and eos is a more commonly used name for end-of-stream.

 
 
6
 
vote

No puede usar comillas dobles en una cadena literal como esta:

  for4  

(El resaltado de sintaxis incluso cambia el color del for5 ).

Para imprimirlos, tiene que escapar de ellos como tales:

  for6  

Supongo que su compilador ignoró el original, ya que obtuve un error cuando lo intenté.

consulte este para obtener más información sobre las secuencias de escape en C ++.

 

You cannot use double quotes in a string literal like this:

cout << "Enter some text. Type "***" to end." << endl; 

(The syntax-highlighting even changes the color of the ***.)

In order to print them out, you have to escape them as such:

cout << "Enter some text. Type \"***\" to end." << endl; 

I suppose your compiler ignored the original, as I got an error when I tried it.

See this for more info on escape sequences in C++.

 
 
5
 
vote

Personalmente apreciaría el bucle de entrada:

  static std::string const  endmark("***")  ...  for(;(begin != end) && (*begin != endmark);++begin) {     words[*begin]++; }   

El bucle de salida I usaría STD :: Copiar.

  for(std::map<string,int>::iterator iter = words.begin(); iter != words.end(); ++iter)     cout << std::setw(6) << iter->second << " " << iter->first << endl;  ...  std::copy(std:begin(words), std::end(words), std::istream_iterator<WordCount>(std::cout, " "));   

Solo necesita definir un operador de salida para WordCount.

  typedef std::map<string,int>::iterator WordCount; std::ostream& operator<<(std::ostream& stream, WordCount const& item) {      return stream << std::setw(6) << item->second << " " << item->first; }   

Evitaría std::endl a menos que realmente desee descargar la salida (generalmente no es el caso). Prefiero usar " " en su lugar.

 

I personally would tighten the input loop:

static std::string const  endmark("***")  ...  for(;(begin != end) && (*begin != endmark);++begin) {     words[*begin]++; } 

The for the output loop I would use std::copy.

for(std::map<string,int>::iterator iter = words.begin(); iter != words.end(); ++iter)     cout << std::setw(6) << iter->second << " " << iter->first << endl;  ...  std::copy(std:begin(words), std::end(words), std::istream_iterator<WordCount>(std::cout, "\n")); 

You just need to define an output operator for WordCount.

typedef std::map<string,int>::iterator WordCount; std::ostream& operator<<(std::ostream& stream, WordCount const& item) {      return stream << std::setw(6) << item->second << " " << item->first; } 

I would avoid std::endl unless you really want to flush output (usually not the case). Prefer to use "\n" in its place.

 
 
         
         
2
 
vote

Aparte de lo que Jamal dijo. Pasé por mi código de nuevo y decidí que debería cambiar el Loop 99887776665544335 .

En lugar de usar std::map<string,int>::iterator iter probablemente debería hacer: std::map<string,int>::const_iterator iter

O incluso mejor solo: auto iter

 

Apart from what Jamal said. I went through my code again and decided I should change the for loop.

Instead of using std::map<string,int>::iterator iter I should probably do: std::map<string,int>::const_iterator iter

Or even better just: auto iter

 
 
 
 

Relacionados problema

11  Yaai (otro de otra implementación)  ( Yaai yet another any implementation ) 
Soy un desarrollador de juegos de C # actualmente aprendiendo C ++ y este es mi proyecto de segundo Big-ish (el primero es un Implementación vectorial ). E...

4  Una implementación de clase de cadena personalizada  ( A custom string class implementation ) 
Esta es mi primera implementación de un "contenedor" usando la regla de cinco, cualquier comentario con gusto aceptaré. He intentado hacerlo como sea posible,...

4  Optimización del algoritmo de STL y DIJKSTRA  ( Stl and dijkstras algorithm optimization ) 
Este es el problema y mi solución a esto es: #include "iostream" #include "stdio.h" #include "algorithm" #include "math.h" #include "string.h" #include "...

14  C ++ String_cast <> Función de plantilla  ( C string cast template function ) 
En C ++, para simplificar la conversión de cadena entre std::string y 9988776655544336 , creé las siguientes funciones de plantilla de utilidad: #pragma...

2  Fusionar ocurrencias adyacentes de elementos idénticos en la recopilación de datos  ( Merge adjacent occurrences of identical elements in data collection ) 
Hay una pequeña Ejercicio de programación para fusionar elementos idénticos adyacentes en una colección. Aquí hay dos soluciones (Pasando las pruebas de...

9  STOD-SAUSE STOD :: MAPS ACCESOR  ( Thread safe stdmap accessor ) 
Después de aprender de que std::map8 los contenedores no son intrínsecamente atómicos y, por lo tanto, no son seguros de hilo (echa un vistazo Este Piedra...

1  Track Ejecución Tiempo usando STD :: Chrono Instalaciones e imprime el tiempo de ejecución de una manera comprensible  ( Track execution time using stdchrono facilities and print the execution time i ) 
La clase a continuación se utilizará para rastrear el tiempo de ejecución de varias operaciones. No hay necesidad de sumergir en bibliotecas C para obtener un...

4  Contenedor que itera un rango o una lista  ( Container which iterates a range or a list ) 
He hecho algún contenedor compuesto Range que acepta un rango MIN / MAX como 9988776665544331 o un conjunto de enteros como un std::set . Internament...

5  C ++ Practica en plantillas de STL y algoritmos  ( C practice on stl templates and algorithms ) 
He implementado el siguiente programa a continuación para obtener una asignación para la práctica en plantillas de STL y algoritmos. Todo lo que estoy haciend...

3  Multiplique elementos vectoriales por un valor escalar usando STL y plantillas  ( Multiply vector elements by a scalar value using stl and templates ) 
Escribí una pequeña simulación científica en la que quería manipular los vectores con el mismo tipo de funcionalidad que usan los vectores adorables de Python...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos