way - strings c++




Compruebe si una cadena es un prefijo de otra (8)

Tengo dos cadenas que me gustaría comparar: String y String: ¿Hay alguna función de biblioteca que devuelva verdadero al pasar estas dos cadenas, pero falso para decir String y OtherString ?

Para ser precisos, quiero saber si una cadena es un prefijo de otra.


¿Qué pasa con el "buscar" y verificar el resultado para la posición 0?

string a = "String";
string b = "String:";

if(b.find(a) == 0)
{
// Prefix

}
else
{
// No Prefix
}

¿Qué tal simplemente?

bool prefix(const std::string& a, const std::string& b) {
  if (a.size() > b.size()) {
    return a.substr(0,b.size()) == b;
  }
  else {
    return b.substr(0,a.size()) == a;
  }
}

C ++ no C, seguro, simple, eficiente.

Probado con:

#include <string>
#include <iostream>

bool prefix(const std::string& a, const std::string& b);

int main() {
  const std::string t1 = "test";
  const std::string t2 = "testing";
  const std::string t3 = "hello";
  const std::string t4 = "hello world";
  std::cout << prefix(t1,t2) << "," << prefix(t2,t1) << std::endl;
  std::cout << prefix(t3,t4) << "," << prefix(t4,t3) << std::endl;
  std::cout << prefix(t1,t4) << "," << prefix(t4,t1) << std::endl;
  std::cout << prefix(t1,t3) << "," << prefix(t3,t1) << std::endl;

}

Creo que strncmp es lo más cercano a lo que estás buscando.

Sin embargo, si se reformula, puede estar buscando strstr(s2,s1)==s2 , que no es necesariamente la forma más eficaz de hacerlo. Pero no quieres entrenar n ;-)

De acuerdo, está bien, la versión de c ++ sería !s1.find(s2) .

Bueno, puedes hacerlo aún más c ++, algo como esto: std::mismatch(s1.begin(),s1.end(),s2.begin()).first==s1.end() .


Esto es eficiente y conveniente:

a.size() >= b.size() && a.compare(0, b.size(), b) == 0

Con std::string , la operación de size es de costo cero, y compare utiliza el método de traits::compare rápidos traits::compare .

Tenga en cuenta que sin la comparación de tamaño, compare solo no es suficiente porque compara solo caracteres a.size() y "xyz" sería un prefijo de "xy" .


Puedes usar esto:

para c ++ 14 o menos

bool has_prefix
    (std::string str, std::string prefix)  {
    return str.find(prefix, 0) == 0;
}

para c ++ 17

//is much faster
auto has_prefix
    (std::string str, std::string_view prefix) -> decltype(str.find(prefix) == 0) {
    return str.find(prefix, 0) == 0;
}

Si sabe qué cadena es más corta, el procedimiento es simple, solo use std::equal con la cadena más corta primero. Si no lo hace, algo como lo siguiente debería funcionar:

bool
unorderIsPrefix( std::string const& lhs, std::string const& rhs )
{
    return std::equal(
        lhs.begin(),
        lhs.begin() + std::min( lhs.size(), rhs.size() ),
        rhs.begin() );
}

str1.find (str2) devuelve 0 si se encuentra str2 completo en el índice 0 de str1:

#include <string>
#include <iostream>

// does str1 have str2 as prefix?
bool StartsWith(const std::string& str1, const std::string& str2)
{   
    return (str1.find(str2)) ? false : true;
}

// is one of the strings prefix of the another?
bool IsOnePrefixOfAnother(const std::string& str1, const std::string& str2)
{   
    return (str1.find(str2) && str2.find(str1)) ? false : true;
}

int main()
{
    std::string str1("String");
    std::string str2("String:");
    std::string str3("OtherString");

    if(StartsWith(str2, str1))
    {
        std::cout << "str2 starts with str1" << std::endl;      
    }
    else
    {
        std::cout << "str2 does not start with str1" << std::endl;
    }

    if(StartsWith(str3, str1))
    {
        std::cout << "str3 starts with str1" << std::endl;      
    }
    else
    {
        std::cout << "str3 does not start with str1" << std::endl;
    }

        if(IsOnePrefixOfAnother(str2, str1))
        {
            std::cout << "one is prefix of another" << std::endl;      
        }
        else
        {
            std::cout << "one is not prefix of another" << std::endl;
        }

        if(IsOnePrefixOfAnother(str3, str1))
        {
            std::cout << "one is prefix of another" << std::endl;      
        }
        else
        {
            std::cout << "one is not prefix of another" << std::endl;
        }

    return 0;
}

Salida:

  str2 starts with str1
  str3 does not start with str1
  one is prefix of another
  one is not prefix of another

std::string(X).find(Y) es cero si y solo si Y es un prefijo de X





prefix