Comprobando si una cadena contiene una subcadena solo una vez -- java campo con strings camp codereview Relacionados El problema

Checking whether a string contains a substring only once


7
vote

problema

Español

Quiero verificar si una cadena contiene solo una ocurrencia de solo de la subcadena dada (por lo que el resultado de #ifndef PNG_HH #define PNG_HH #include <png.h> namespace png { void write_image(char const *filename, std::uint8_t const *image_data, std::uint32_t image_width, std::uint32_t image_height) { /* create a zeroed out png_image struct */ png_image output_png; std::memset(&output_png, 0, sizeof(output_png)); output_png.version = PNG_IMAGE_VERSION; output_png.format = PNG_FORMAT_GRAY; output_png.width = image_width; output_png.height = image_height; /* write the png file */ png_image_write_to_file(&output_png, filename, 0, image_data, image_height, nullptr); /* cleanup */ png_image_free(&output_png); } } #endif 3 debe ser 99887776655443314 ) . En java , una implementación simple y directa sería

  #ifndef PNG_HH #define PNG_HH #include <png.h>  namespace png {     void write_image(char const *filename, std::uint8_t const *image_data, std::uint32_t image_width, std::uint32_t image_height)     {         /* create a zeroed out png_image struct */         png_image output_png;         std::memset(&output_png, 0, sizeof(output_png));         output_png.version = PNG_IMAGE_VERSION;         output_png.format = PNG_FORMAT_GRAY;         output_png.width = image_width;         output_png.height = image_height;          /* write the png file */         png_image_write_to_file(&output_png, filename, 0, image_data, image_height, nullptr);          /* cleanup */         png_image_free(&output_png);     } } #endif 5  

o

  #ifndef PNG_HH #define PNG_HH #include <png.h>  namespace png {     void write_image(char const *filename, std::uint8_t const *image_data, std::uint32_t image_width, std::uint32_t image_height)     {         /* create a zeroed out png_image struct */         png_image output_png;         std::memset(&output_png, 0, sizeof(output_png));         output_png.version = PNG_IMAGE_VERSION;         output_png.format = PNG_FORMAT_GRAY;         output_png.width = image_width;         output_png.height = image_height;          /* write the png file */         png_image_write_to_file(&output_png, filename, 0, image_data, image_height, nullptr);          /* cleanup */         png_image_free(&output_png);     } } #endif 6  

¿Puede sugerir una implementación más simple / más eficiente?

Original en ingles

I want to check if a string contains only a single occurrence of the given substring (so the result of containsOnce("foo-and-boo", "oo") should be false). In Java, a simple and straightforward implementation would be either

boolean containsOnce(final String s, final CharSequence substring) {     final String substring0 = substring.toString();     final int i = s.indexOf(substring0);     return i != -1 && i == s.lastIndexOf(substring0); } 

or

boolean containsOnce(final String s, final CharSequence substring) {         final String substring0 = substring.toString();         final int i = s.indexOf(substring0);         if (i == -1) {             return false;         }          final int nextIndexOf = s.indexOf(substring0, i + 1);         return nextIndexOf == 0 || nextIndexOf == -1; // nextIndexOf is 0 if both arguments are empty strings. } 

Can you suggest a simpler/more efficient implementation?

     
       
       

Lista de respuestas

3
 
vote

Tal vez usando la coincidencia de patrones. Me parece más legible, pero no tengo idea de cuál es más eficiente.

  public enum InstalmentTransactionEnum {      ONE_INSTALMENT("1"),     TWO_INSTALMENT_NO_INTEREST("2");      private final String installments;      InstalmentTransactionEnum(String installments) {         this.installments = installments;     }      public static InstalmentTransactionEnum forInstallments(String installments) {         for (InstalmentTransactionEnum value : InstalmentTransactionEnum.values()) {             if (value.installments.equals(installments)) {                 return value;             }         }         return ONE_INSTALMENT;     }  } 3  

También tenga en cuenta que public enum InstalmentTransactionEnum { ONE_INSTALMENT("1"), TWO_INSTALMENT_NO_INTEREST("2"); private final String installments; InstalmentTransactionEnum(String installments) { this.installments = installments; } public static InstalmentTransactionEnum forInstallments(String installments) { for (InstalmentTransactionEnum value : InstalmentTransactionEnum.values()) { if (value.installments.equals(installments)) { return value; } } return ONE_INSTALMENT; } } 4 devuelve public enum InstalmentTransactionEnum { ONE_INSTALMENT("1"), TWO_INSTALMENT_NO_INTEREST("2"); private final String installments; InstalmentTransactionEnum(String installments) { this.installments = installments; } public static InstalmentTransactionEnum forInstallments(String installments) { for (InstalmentTransactionEnum value : InstalmentTransactionEnum.values()) { if (value.installments.equals(installments)) { return value; } } return ONE_INSTALMENT; } } 5 . No estoy seguro si contaría esto como correcto o no.

Nota: También puede escribirlo como

  public enum InstalmentTransactionEnum {      ONE_INSTALMENT("1"),     TWO_INSTALMENT_NO_INTEREST("2");      private final String installments;      InstalmentTransactionEnum(String installments) {         this.installments = installments;     }      public static InstalmentTransactionEnum forInstallments(String installments) {         for (InstalmentTransactionEnum value : InstalmentTransactionEnum.values()) {             if (value.installments.equals(installments)) {                 return value;             }         }         return ONE_INSTALMENT;     }  } 6  

No sé cuál de los dos es más legible.

Editar:

Después de mirar hacia arriba, lo que sea más rápido: indexof vs matcher
Parece ser el consenso general de que el índice de índice es un poco más rápido, pero que estamos hablando de momentos tan bajos que realmente no importa mucho.

Ir por cualquier solución que prefiera, supongo ...

 

Perhaps using pattern matching. It looks more readable to me, but I have no idea about which is more efficient.

public static boolean containsOnce(final String s, final CharSequence substring) {     Pattern pattern = Pattern.compile(substring.toString());     Matcher matcher = pattern.matcher(s);     if(matcher.find()){         return !matcher.find();     }     return false; }  public static void main(String[] args) throws Exception {     System.out.println(containsOnce("aba","a"));    //false     System.out.println(containsOnce("abab", "ab")); //false     System.out.println(containsOnce("aba", "b"));   //true     System.out.println(containsOnce("aaa", "aa"));  //true     System.out.println(containsOnce("",""));        //true     System.out.println(containsOnce("ab",""));      //false } 

Also note that containsOnce("aaa","aa") returns true. Not sure if you would count this as correct or not.

Note: you can also write it as

Pattern pattern = Pattern.compile(substring.toString()); Matcher matcher = pattern.matcher(s); return matcher.find() && !matcher.find(); 

I don't know which of the two is more readable.

EDIT:

After looking up whichever is faster: indexof vs matcher
It seems to be the general consensus that indexof is a bit faster, but that we're talking about such low times that it really doesn't matter much.

Go for whichever solution you prefer I guess ...

 
 
0
 
vote

No veo nada malo con el post original. Su conciso y legible:

  public enum InstalmentTransactionEnum {      ONE_INSTALMENT("1"),     TWO_INSTALMENT_NO_INTEREST("2");      private final String installments;      InstalmentTransactionEnum(String installments) {         this.installments = installments;     }      public static InstalmentTransactionEnum forInstallments(String installments) {         for (InstalmentTransactionEnum value : InstalmentTransactionEnum.values()) {             if (value.installments.equals(installments)) {                 return value;             }         }         return ONE_INSTALMENT;     }  } 7  

Estaba escribiendo una prueba recientemente que se necesitaba para verificar agregar una cadena no se agregaría si existía (usé un conjunto en el método de la caja negra), así que escribí algo como esto:

  public enum InstalmentTransactionEnum {      ONE_INSTALMENT("1"),     TWO_INSTALMENT_NO_INTEREST("2");      private final String installments;      InstalmentTransactionEnum(String installments) {         this.installments = installments;     }      public static InstalmentTransactionEnum forInstallments(String installments) {         for (InstalmentTransactionEnum value : InstalmentTransactionEnum.values()) {             if (value.installments.equals(installments)) {                 return value;             }         }         return ONE_INSTALMENT;     }  } 8  
 

I don't see anything wrong with the original post. Its concise and readable:

boolean containsOnce(String s, String sub) {   int firstIndex = s.indexOf(sub)   return firstIndex >=0 && firstIndex == s.lastIndexOf(sub) } 

I was writing a test recently that needed to verifying adding a string would not add if it existed (I used a set in the black box method) so I wrote something like this:

public void testNonDuplicateAdd() {   String actual = methodUnderTest(stringToAdd, addingTo);   assertThat(actual, containsString(stringToAdd));   int firstIndex = actual.indexOf(stringToAdd);   int lastIndex = actual.lastIndexOf(stringToAdd);   assertThat(firstIndex, equals(lastIndex)); } 
 
 
   
   
-2
 
vote

En términos de eficiencia, el public enum InstalmentTransactionEnum { ONE_INSTALMENT("1"), TWO_INSTALMENT_NO_INTEREST("2"); private final String installments; InstalmentTransactionEnum(String installments) { this.installments = installments; } public static InstalmentTransactionEnum forInstallments(String installments) { for (InstalmentTransactionEnum value : InstalmentTransactionEnum.values()) { if (value.installments.equals(installments)) { return value; } } return ONE_INSTALMENT; } } 9 es el ShowStopper tan pronto como InstalmentTransactionEnum install = InstalmentTransactionEnum.forInstallments(installments); 0 no es un 998877766554433311 . El resto del código se ve bien.

La documentación del método debe incluir InstalmentTransactionEnum install = InstalmentTransactionEnum.forInstallments(installments); 2 como ejemplo para devolver InstalmentTransactionEnum install = InstalmentTransactionEnum.forInstallments(installments); 3 , ya que eso podría ser una caja de esquina no obvia.

 

In terms of efficiency, the substring.toString() is the showstopper as soon as substring is not a java.lang.String. The rest of the code looks fine.

The documentation of the method should include containsOnce("fooo", "oo") as an example for returning false, since that might be a non-obvious corner case.

 
 

Relacionados problema

8  Conversión de STD :: Chrono :: Time_Point to / from std :: string  ( Converting stdchronotime point to from stdstring ) 
Considere estas funciones que permitan convertir checkOnline.sh4 a / FROM checkOnline.sh5 Con un formato Fecha de fecha ". checkOnline.sh6 con uso:...

1  Compruebe si dos cadenas son permutación entre sí  ( Check if two strings are permutation of each other ) 
private String sort(String word) { char[] content = word.toCharArray(); Arrays.sort(content); return new String(content); } private boolea...

11  Optimizando el corrector de anagramas Java (comparar 2 cadenas)  ( Optimizing java anagram checker compare 2 strings ) 
Un anagrama es como una mezcla de las letras en una cadena: pots es un anagrama de detener wilma es un anagrama de ilwma Estoy pasando por el ...

18  Invirtiendo una cadena  ( Reversing a string ) 
Tuve esto como una pregunta de entrevista, y el entrevistador señaló esto. Esto es lo que escribí: //C# Syntax here public string Reverse(string s) { c...

6  Las vocales en una cadena están en orden alfabético  ( Vowels in a string are in alphabetical order ) 
Tarea Escriba una implementación que devuelva si un 99887776655544330 tiene vocales (idioma inglés) en orden alfabético (A-Z) o no. Feedback es mi v...

10  Función recursiva que genera las permutaciones de una cadena  ( Recursive function that generates the permutations of a string ) 
Estoy buscando una revisión de mi función recursiva que genere las permutaciones de una cadena. ¿Hay mejores formas de hacer esto? var permutations = []; ...

2  Función para borrar un carácter en una cadena  ( Function to erase a character in a string ) 
void chrrem (char arr[], size_t len, size_t pos) { memmove(arr + pos, arr + (pos + 1), (len - pos) + 1); } Se supone que es simplemente rápido. Borra...

9  Convierta una contraseña a una cadena fonética para usuarios finales  ( Convert a password to a phonetic string for end users ) 
Tanto como lo odio, a veces proporcionar contraseñas a las personas debe hacerse electrónicamente. Cuando hago eso, trato de eliminar cualquier ambigüedad que...

1  Imprima todos los tamaños posibles de subsecuencias de cadena en C  ( Print out all possible sizes of subsequences of string in c ) 
Por ejemplo, dada una cadena "abcdefghijk", quiero que mi función se imprima: a, b, c, d, e, f, g, h, i, j, k. ab, bc, cd, de, ef, fg, gh, hi, ij, jk ab...

3  Implementación más portátil de Tolower ()  ( More portable tolower implementation ) 
Me estoy desafiando a intentar intentar escribir una función que sea tan eficiente, portátil y a prueba de fallas posible. La función es muy simple y solo con...




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