2010-07-20 16 views
6

Quiero usar la función pack() en Perl para codificar algunos datos. Entonces quiero comparar mi estructura empaquetada a otra estructura empaquetada. Quiero que esto se compare en los valores de bytes de esta estructura empaquetada.¿Cómo comparo los valores empaquetados en Perl?

De acuerdo con la documentación, cmp usa la configuración regional actual para determinar cómo comparar cadenas. Pero no quiero que se aplique ninguna inteligencia a la comparación. Quiero lo que esté más cerca de un memcmp(). Obviamente no puedo usar <=> para comparar mis objetos empaquetados ya que no son números.

¿Cuál es la mejor manera de comparar cadenas empaquetadas en Perl?

Nota: He estado leyendo this article on efficient sorting in Perl que señala que la función de ordenación simple utiliza un algoritmo similar a memcmp para comparar estructuras. Me pregunto cómo lograr tal comparación sin tener que usar sort.

+1

'sort' es realmente un excelente lugar para empezar. Tratar de construir tu propio reemplazo de clasificación probablemente no funcione tan bien como te gustaría, ya que el género Perl ha sido afinado durante años. El enlace de clasificación eficiente que le diste en realidad incluye instrucciones sobre cómo usar estructuras de datos empaquetadas para acelerar el género, lo cual es bastante ingenioso, pero la clasificación debería tomar mucho tiempo antes de que me dedique a mantener eso. – sarnold

+0

¿Desea una comparación (es decir, menor que, mayor que o igual a) o una prueba de igualdad de sí o no? –

+0

@gbacon: Quiero algo con lo que pueda ordenar, por lo tanto, menos que, mayor que, igual a. –

Respuesta

5

consideraciones Deshabilitar configuración regional para el bloque y utilizar cmp como de costumbre:

sub mycmp { 
    no locale; 
    $_[0] cmp $_[1]; 
} 

La documentación perlop ofrece al

lt, le, ge, gt y cmp utilizar la intercalación (especie) orden especificado por la configuración regional actual si use locale está en vigor. Ver perllocale.

y luego en perllocale

El comportamiento predeterminado se restaura con la no locale pragma, o al alcanzar el final de bloque que lo contiene use locale.

Por ejemplo, correr

my($one,$two) = map pack("N", $_) => 1, 2; 
say mycmp($one, $two); 
say mycmp($two, $one); 

salidas

-1 
1
+0

¿Se aplica "sin configuración regional" solo dentro del cierre? Si hay una configuración regional que se aplica fuera del cierre, ¿seguirá aplicándose a cualquier código que esté debajo del cierre? –

+0

@PP Sí, el pragma 'locale' es léxico: está en efecto solo dentro de su bloque adjunto. –

0

Pensando en voz alta aquí: ¿ayudarán los operadores bit a bit? Como hacer un XOR de dos cadenas idénticas dará una cadena de bits con todo lo establecido en 0.

http://perldoc.perl.org/perlop.html#Bitwise-String-Operators

+0

xor sería una gran prueba de igualdad independiente de la configuración regional, en realidad, buena idea, no sería útil por menos de/mayor que sin embargo. –

4

Expand, then contract. Compárese, por ejemplo, la representación hexadecimal de sus estructuras, que sólo utiliza caracteres ASCII y no puede ir en contra de la localización problema que mencionas

unpack('H*', $first) cmp unpack('H*', $second) 
Cuestiones relacionadas