Búsqueda de una cadena dentro de una cadena más grande [cerrado]

Realmente necesito ayuda con esta última parte de mi programa. Necesito encontrar una cadena dentro de una cadena más grande y, si la encuentro, devolver la ubicación de inicio de la subcadena. Desde las direcciones:

Tenga en cuenta que la ubicación de su cadena comienza desde 0 y termina en la longitud -1. Si no se encuentra la cadena, se devolverá un valor de -1.

Empecé y se compila el siguiente código, solo quiero saber si esto es realmente correcto. No quiero meterme demasiado en mi cabeza, pero necesito algunos comentarios de los expertos. ¿Lo estoy haciendo bien? ¿O al menos voy en la dirección correcta?

const int MyString::Find(const MyString& other)
{
    int start(0);
    int counter(0);
    int end = other.Size;
    int count(0);
    int end1 = Size;
    int nfound = -1;
    char* temp;

    if(other.String[0] != '\0' && other.String[0] != ' ')
    {
        if(other.String[count] == String[counter])
        {
            start = counter;

            for(int i = count; i < end-1;i++)
            {
                for(int j = counter; j < end1 -1; j++)
                {
                    temp[j] = String[j];
                }
            }
            if(other == temp)
            {
                return start;
            }
            else
                return nfound;
        }

        else{
            while(other.String[count] != String[counter])
            {
                counter++;
                if(other.String[count] == String[counter])
                {
                    start = counter;
                    for(int i = count; i < end-1;i++)
                    {
                        for(int j = counter; j < end1 -1; j++)
                        {
                            temp[j] = String[j];
                        }
                    }
                    if(other == temp)
                    {
                        return start;
                    }
                    else
                        return nfound;
                }
            }
        }
    }
    else
    {
        return nfound;
    }
}

preguntado el 12 de junio de 12 a las 19:06

SO no es un lugar para que las personas revisen su código; es posible que desee probar el sitio Code Review SE. -

No está directamente relacionado con la P: tiene una pérdida de memoria: asigna con new[] (que ni siquiera es necesario) pero nunca delete[]. -

@jrok gracias! He editado el código debido a la filtración que has señalado. -

Espera, espera, SÍ necesitas new en este fragmento de código en particular! Lo que quise decir es que realmente no necesita una matriz de caracteres asignada dinámicamente para implementar una función de búsqueda. Vea la respuesta de Steve Jessop. -

2 Respuestas

Asumiendo que no quieres hacer nada muy sofisticado, considera que needle es una subcadena de haystack si y sólo si hay algún índice de haystack para el cual la subcadena que comienza en ese índice es igual a needle.

Además, no necesita copiar muchas subcadenas. A partir de su índice elegido, simplemente compare carácter por carácter hasta que (a) encuentre una discrepancia, en cuyo caso intente con otro índice, o (b) se quede sin haystack, en cuyo caso no es posible ninguna coincidencia para este o cualquier índice mayor, o de lo contrario (c) se queda sin needle, en cuyo caso ha encontrado una coincidencia, así que devuelva el índice desde el que está trabajando.

Si hay más de una coincidencia (por ejemplo, si busca "na" in "banana"), luego, con suerte, las instrucciones le indicarán cuál devolver. Esto le dice en qué orden considerar los índices en haystack.

Si desea hacer algo muy sofisticado, busque Boyer-Moore, Knuth-Morris-Pratt y otros algoritmos de búsqueda de cadenas publicados con diferentes compensaciones. Parece que hace falta más de una persona para inventar uno bueno.

Respondido el 12 de junio de 12 a las 19:06

¡gracias! esto ha ayudado mucho, ahora solo tengo una pregunta: ¿Cuál es la forma más eficiente de hacer esto si no usa bucles? Bueno, 2 preguntas: siempre me tropiezo al devolver la ubicación de inicio porque parece que no hay forma de retractarse y obtener la ubicación de inicio después de comparar todos los personajes: user1363061

La forma más eficiente es no hacerlo en absoluto, no hacerlo usted mismo. Utilice una biblioteca depurada y optimizada para su comodidad. - Kuba no se ha olvidado de Monica

@user1363061: hay varias formas de obtener la ubicación de inicio. Una sería almacenarlo en una variable mientras comparas los caracteres. Otra sería restar la longitud de needle de cualquier compensación en haystack terminas adentro. La cuestión de lo que es más eficiente es demasiado complicada para admitir una respuesta simple. Cada algoritmo tiene ciertas entradas (o categorías de entrada) en las que funciona mejor o peor. - steve jesop

Este es un código un poco malo desde mi punto de vista. \0 se usa en char*-strings para indicar el final de la cadena. No hay necesidad de usarlo en la clase que encapsula cadenas. Hay muchos algoritmos para encontrar subcadenas en cadenas, uno de ellos es el algoritmo Knuth-Morris-Pratt. Otros se enumeran en este artículo. Algoritmo de búsqueda de cadenas

Respondido el 12 de junio de 12 a las 19:06

"No hay necesidad de usarlo en la clase que encapsula cadenas" y, sin embargo, std::string lo hace. Es cierto que eso es solo para apoyar el c_str() función. - steve jesop

Quiero decir, no hay necesidad de usarlo explícitamente. Hace que el código sea menos legible. algo asi if(str.empty()) es mucho más legible que if(str[0] == '\0') y será más fácil reemplazar su cadena ANSI con una cadena Unicode, por ejemplo: solounchico

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.