Saltar al contenido

Comparación alfabética de dos cadenas

Después de indagar en diversos repositorios y páginas al concluir hemos descubierto la respuesta que te compartiremos más adelante.

Solución:

Si las cadenas están compuestas únicamente por caracteres ASCII, puede normalizarlas a minúsculas antes de comparar:

documentclassarticle
usepackagepdftexcmds

makeatletter
defcompareStrings#1#2%
  lowercaseedef@tempa[email protected]#1#2%
  typeout#1 -- #2: @tempa%

makeatother

compareStringsabcdefgbcdefg

compareStringsAbcdefgbcdefg

compareStringsBbcdefgacdefg

compareStringsbbcdefgacdefg

compareStringsbcdefgbcdeag

compareStringsABcDeFaBCdef

los pdftexcmds el paquete define [email protected] hacer lo correcto con pdfLaTeX, XeLaTeX y LuaLaTeX. En todos los casos el resultado es

abcdefg -- bcdefg: -1
Abcdefg -- bcdefg: -1
Bbcdefg -- acdefg: 1
bbcdefg -- acdefg: 1
bcdefg -- bcdeag: 1
ABcDeF -- aBCdef: 0

los edef permite también pasar macros a compareStrings, siempre que su expansión consista en caracteres ASCII simples (no hay una restricción real para XeLaTeX y LuaLaTeX, pero los caracteres UTF-8 en pdfLaTeX no funcionarían).

Si necesita ejecutar algo para los diferentes casos, en lugar de producir –1, 0 o 1, puede agregar la prueba habitual:

makeatletter
newcommandcompareStringsDo[5]%
  lowercaseifcase[email protected]#1#2%
    #4or
    #5else
    #3fi

makeatother

Así que con compareStringsDo los el código se ejecutará cuando viene antes en orden alfabético, si son iguales y de lo contrario (después de la normalización a minúsculas).

Un expl3 versión que tiene la gran ventaja de ser totalmente ampliable.

documentclassarticle
usepackagexparse

ExplSyntaxOn
NewExpandableDocumentCommandcompareStringsmm
 
  str_if_eq:eeTF  str_lower_case:f  #1    str_lower_case:f  #2  
    equalStrings#1#2 
    differentStrings#1#2 

ExplSyntaxOff

newcommandequalStrings[2]typeoutStrings #1 and #2 are equal
newcommanddifferentStrings[2]typeoutStrings #1 and #2 are different

newcommandtestAbCdEF

compareStringsabcdefgbcdefg

compareStringsAbcdefgbcdefg

compareStringsBbcdefgacdefg

compareStringsbbcdefgacdefg

compareStringsbcdefgbcdeag

compareStringsABcDeFaBCdef

compareStringsABcDeFtest

stop

La salida de la consola:

Strings abcdefg and bcdefg are different
Strings Abcdefg and bcdefg are different
Strings Bbcdefg and acdefg are different
Strings bbcdefg and acdefg are different
Strings bcdefg and bcdeag are different
Strings ABcDeF and aBCdef are equal
Strings ABcDeF and AbCdEF are equal

Respuesta antigua, simple, que no es realmente la respuesta

[kept for ‘historical purposes’ – can be deleted anytime]

No soy grande LaTeX asistente como egreg, por ejemplo. :) Entonces propongo una solución mucho más simple, simplemente usar un paquete: xstring:

documentclassarticle

usepackagexstring

begindocument

IfStrEqabcdefgbcdefgtruefalse
IfStrEqAbcdefgbcdefgtruefalse
IfStrEqBbcdefgacdefgtruefalse
IfStrEqbbcdefgacdefgtruefalse
IfStrEqbcdefgbcdeagtruefalse
IfStrEqbcdeagbcdeagtruefalse

enddocument

El comando es realmente simple de usar: toma 4 argumentos, los dos primeros son las cadenas que se compararán, el tercero se ejecutará cuando el resultado de la comparación sea true, de lo contrario se ejecutará el argumento número 4.

El paquete proporciona muchas más funciones para la fantasía. string manipulaciones.


EDITAR: Nueva respuesta corregida (todavía usando xstring)

Después de publicar mi primera respuesta, me dijeron (¡con razón!) Que la pregunta era más que una simple verificación de igualdad. Más bien se trata de comparar si un string proviene antes de o después otro alfabéticamente. Después de rascarme un poco la cabeza, se me ocurrió esto:

documentclassarticle

usepackagexstring
usepackage[nomessages]fp

newcommandcompAlph[2]%

StrCompare#1#2[posdiff]

Difference between input strings detected at position:

posdiffsmallskip

StrChar#1posdiff[myfirstchar]

Character in the 1st string that is different:

myfirstcharsmallskip

StrChar#2posdiff[mysecondchar]

Character in the 2nd string that is different:

mysecondcharsmallskip

StrPositionabcdefghijklmnopqrstuvwxyzmyfirstchar[posfirst]
StrPositionabcdefghijklmnopqrstuvwxyzmysecondchar[possecond]

FPevalposrelclip(possecond-posfirst)
`Relative distance' between characters:

posrel


begindocument

compAlphzyzzyzzyryxbcdeag
bigskip
compAlphabcdefgbcdefg
bigskip
compAlphbbcdefgacdefg
bigskip
compAlphbbcdefgacdefg
bigskip
compAlphbcdefgbcdeag
bigskip
compAlphbcdeagbcdeag

enddocument

La cosa de la ‘distancia relativa’ muestra en realidad, ‘qué tan separados’ en el alfabeto definido están los caracteres que difieren. Si el valor es negativo, la segunda palabra debería moverse ‘hacia arriba’, antes de la otra palabra para tenerlas en orden alfabético, y al revés si es positivo.

No es tan elegante como la solución de egreg e imprime el resultado en el documento, también puede parecer un poco burdo y puede necesitar un poco de ajuste, pero es una alternativa. :)

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *