Dividir una cadena de caracteres basada en el cambio de carácter -- ++ campo con strings campo con c++11 camp codereview Relacionados El problema

Split a character string based on change of character


4
vote

problema

Español

Estoy contribuyendo con una solución a la siguiente tarea en el código de Rosetta:

tarea
Dividir una cadena en cadenas delimitadas de coma (más un espacio en blanco) basadas en un cambio de carácter (de izquierda a derecha).

Muestre la salida aquí (use el 1er ejemplo a continuación).

Los espacios en blanco deben tratarse como cualquier otro carácter (excepto que son problemático para mostrar claramente). Lo mismo se aplica a comas.

por ejemplo, la cadena:

ghhh5yy ++ ///

debe dividirse y mostrar:

G, HHH, 5, YY, ++, ///,

Aquí está el código:

  // Solution for http://rosettacode.org/wiki/Split_a_character_string_based_on_change_of_character #include<string> #include<iostream> auto spliter(const std::string &input) {    auto firstCommaPast = false;    std::string res ="";    auto prev = '';    for(auto it = input.cbegin(); it != input.cend();++it) {       if(*it!=prev) {          if(!firstCommaPast) {             firstCommaPast = true;          } else {             res+=", ";          }       }       res+=*it;       prev=*it;    }    return res; }  int main() {    auto input = R"(gHHH5  ))YY++,,,///)";    std::cout<<spliter(input); }     

Soy bastante nuevo para C ++ 11/14, por lo que cualquier sugerencia aquí realmente ayudará.

Original en ingles

I am contributing a solution to the following task on Rosetta Code:

Task
Split a string into comma (plus a blank) delimited strings based on a change of character (left to right).

Show the output here (use the 1st example below).

Blanks should be treated as any other character (except they are problematic to display clearly). The same applies to commas.

For instance, the string:

gHHH5YY++///\

should be split and show:

g, HHH, 5, YY, ++, ///, \

Here is the code:

// Solution for http://rosettacode.org/wiki/Split_a_character_string_based_on_change_of_character #include<string> #include<iostream> auto spliter(const std::string &input) {    auto firstCommaPast = false;    std::string res ="";    auto prev = '\0';    for(auto it = input.cbegin(); it != input.cend();++it) {       if(*it!=prev) {          if(!firstCommaPast) {             firstCommaPast = true;          } else {             res+=", ";          }       }       res+=*it;       prev=*it;    }    return res; }  int main() {    auto input = R"(gHHH5  ))YY++,,,///\)";    std::cout<<spliter(input); }   

I am fairly new to C++11/14 so any suggestions here will really help.

        
 
 

Lista de respuestas

2
 
vote

Algoritmo

Al menos a primera vista, su algoritmo parece ser innecesariamente complejo. No estoy completamente seguro de lo que se pretende se debe realizar. Parece que está tratando de dar algún tipo de tratamiento especial a comas, aunque las instrucciones declaran explícitamente que las comas deben tratarse exactamente como cualquier otro personaje.

Whitespace

Prefiero ver una línea en blanco entre el código #include S y otro código. También prefiero ver un espacio entre el include y el <3 o " que lo sigue:

  #include <string> #include <iostream>  auto spliter(const std::string &input) {   

Estos no hacen ninguna diferencia en la funcionalidad, sino que se ajustan bastante bien con la práctica ampliamente aceptada. No intentaré comentar sobre si la abertura de abertura (código> 99887766555443366) pertenece a la misma línea que el encabezado de la función, o en la siguiente línea por sí misma. Eso es ampliamente debatido, y no creo que haya ningún consenso real sobre el que se prefiere.

Inicialización

Dado que va a ser una cadena vacía de cualquier manera, preferiría usar std::string res; en lugar de std::string res=""; . Este último generalmente agregará un poco de trabajo extra sin lograr nada útil.

Iterators vs. indexing

La razón principal para usar iteradores es admitir algoritmos genéricos. Usarlos para un bucle fuera de un algoritmo genérico es algo cuestionable. En este caso, no veo ninguna mejora real sobre el uso de un tipo de entero e indexación en la cadena.

Error lógico

En este momento, su código asume que el primer carácter de una cadena no puede ser un 9988776665544339 . Si bien eso es probablemente al menos algo inusual, a diferencia de las cuerdas C, es en realidad permitidas / admitidas en un #include0 (y si está presente, su código no funcionará realmente como previsto).

Personalmente, creo que es más fácil de inicializar #include1 en el primer carácter de la cadena de entrada, luego haga que el bucle proceda de #include2 a través del extremo de la cadena. De esta manera, no tenemos que inicializar #include3 a un valor que no puede estar en la cadena (que es bueno, porque no hay tal carácter).

Función Naming

una función hace algo. Como tal, su nombre normalmente debería ser un verbo, no un sustantivo. Aunque puede estar abierto a argumento si el mejor nombre para lo que hace es dividir, vamos a ir con esa idea general, en cuyo caso su nombre debe ser 99887776655443314 , no #include5 .

Código resultante

Incorporando los elementos anteriores, el código podría terminar algo como esto:

  #include6  
 

Algorithm

At least at first glance, your algorithm appears to be unnecessarily complex. I'm not entirely sure what firstCommaPast is intended to accomplish. It seems to be trying to give some sort of special treatment to commas, even though the directions explicitly state that commas should be treated exactly like any other character.

Whitespace

I prefer to see a blank line between the #includes and other code. I also prefer to see a space between the include and the < or " that follows it:

#include <string> #include <iostream>  auto spliter(const std::string &input) { 

These don't make any difference to functionality, but fit pretty well with widely accepted practice. I won't try to comment on whether the opening curly brace ({) belongs on the same line as the function header, or on the next line by itself. That's widely debated, and I don't think there's any real consensus on which is preferred.

Initialization

Given that it's going to be an empty string either way, I'd rather use std::string res; rather than std::string res="";. The latter will typically add a little extra work without accomplishing anything useful.

Iterators vs. indexing

The primary reason for using iterators is to support generic algorithms. Using them for a loop outside of a generic algorithm is somewhat questionable. In this case, I see no real improvement over just using an integer type and indexing into the string.

Logic Error

Right now, your code assumes that the first character of a string can't be a '\0'. While that's probably at least somewhat unusual, unlike with C strings, it is actually allowed/supported in a std::string (and if it's present, your code won't really work as intended).

Personally, I think it's easier to initialize prev to the first character of the input string, then have the loop proceed from input[1] through the end of the string. This way we don't have to initialize prev to a value that can't be in the string (which is good, because there is no such character).

Function Naming

A function does something. As such, its name should normally be a verb, not a noun. Although it may be open to argument whether the best name for what it does is splitting, let's just go with that general idea--in which case its name should be split, not splitter.

Resulting Code

Incorporating the elements above, the code could end up something like this:

#include <string> #include <iostream>  auto split(const std::string &input) {     auto prev = input[0];     std::string res{ prev };      for (size_t i = 1; i < input.length(); i++) {         if (input[i] != prev)             res += ", ";         prev = input[i];         res += prev;     }     return res; }  int main() {     auto input = R"(gHHH5  ))YY++,,,///\)";     std::cout << split(input); } 
 
 
 
 
-1
 
vote

se ve perfecto. Tiene la cadena de entrada con codificación dura aquí, hay una posibilidad de tener un nuevo carácter de línea en su entrada (si la entrada se da en tiempo de ejecución).

 

Looks perfect. You have the input string hardcoded here, is there a possibility of having a new line character in your input (if input is given in run-time).??

 
 
   
   

Relacionados problema

10  Quicksort  ( Templated quicksort ) 
original quicksort.h #include <algorithm> namespace quicksort { template <typename iterator, typename value_type> struct traits { static iterato...

6  Clase de matriz multidimensional simple en C ++ 11  ( Simple multi dimensional array class in c11 ) 
La nueva versión del código se puede revisar en Clase de matriz multidimensional simple en C ++ 11 - Seguimiento . El siguiente código implementa una clas...

3  Entero a la conversión inglesa  ( Integer to english conversion ) 
Escribí algún código para traducir números (por ahora, solo positivo, hasta el límite de 32 bits) en palabras en inglés. Todo funciona y estoy feliz. Busqué...

6  TIPSFE SCANF-LEA FUNCIÓN CON LAS PLANTAS VARIADICAS  ( Typesafe scanf like function with variadic templates ) 
Espero obtener algunos comentarios sobre una función con plantillas variadas que analizan una cadena de formato y rellena algunos parámetros cuyo orden y tipo...

13  Árbol de búsqueda binaria - C ++  ( Binary search tree c ) 
Estoy implementando varias estructuras de datos en un intento por aprender C ++. A continuación se muestra un árbol de búsqueda binario que he implementado pa...

7  Optimizando el juego de la vida de Conway en C ++  ( Optimizing conways game of life in c ) 
¿Cómo podría optimizar aún más mi implementación del juego de la vida de Conway? ¿Y cómo criticarías mis estrategias actuales? Estoy tomando una clase de opti...

3  Java vs C ++ (JAVAC)  ( Java vs c javac ) 
Aquí está el problema para Java VS C ++ ( javac ): Java y C ++ Use diferentes convenciones de nombres: en Java Un identificador de múltiplesWord se const...

53  Operadores nombrados en C ++  ( Named operators in c ) 
a POST POR YAKK Me alertó la idea de los operadores nombrados en C ++. Este look es espléndido (aunque muy poco ortodoxo). Por ejemplo, se puede hacer el ...

10  Clase de Shader OpenGL  ( Opengl shader class ) 
Estoy trabajando a través de algunos tutoriales básicos de OpenGL y he decidido descargar el sombreado de carga / compilación / vinculación a un objeto separa...

14  Implementando una lista relacionada adecuada para un entorno profesional  ( Implementing a proper linked list for a professional environment ) 
Tengo algunas preocupaciones: ¿Es normal que la clase tenga al menos un nodo? En otras palabras, esta implementación no puede tener una lista vinculada va...




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