2010-07-20 7 views
6

Ich möchte die pack()-Funktion in Perl verwenden, um einige Daten zu kodieren. Dann möchte ich meine gepackte Struktur mit einer anderen gepackten Struktur vergleichen. Ich möchte, dass dieser Vergleich mit den Byte-Werten dieser gepackten Struktur erfolgt.Wie kann ich gepackte Werte in Perl vergleichen?

Gemäß der Dokumentation verwendet cmp das aktuelle Gebietsschema, um zu ermitteln, wie Zeichenfolgen verglichen werden. Aber ich möchte keine Intelligenz für den Vergleich verwenden. Ich möchte was auch immer einem Memcmp() am nächsten ist. Natürlich kann ich <=> nicht zum Vergleichen meiner gepackten Objekte verwenden, da sie keine Zahlen sind.

Was ist der beste Weg, gepackte Strings in Perl zu vergleichen?

Hinweis: Ich habe gelesen this article on efficient sorting in Perl, die feststellt, dass die einfache Sortierfunktion einen Memcmp-ähnlichen Algorithmus zum Vergleichen von Strukturen verwendet. Ich frage mich, wie man einen solchen Vergleich ohne Sortierung erreichen kann.

+1

'sort' ist wirklich ein ausgezeichneter Ort zu starten aus. Der Versuch, einen eigenen Sort-Ersatz zu bauen, wird wahrscheinlich nicht so gut funktionieren, wie Sie es sich wünschen, da die Perl-Sortierung über Jahre optimiert wurde. Die effiziente Sortierverknüpfung, die Sie angegeben haben, enthält sogar Anweisungen zur Verwendung von gepackten Datenstrukturen, um die Sortierung zu beschleunigen. Das ist ziemlich clever, aber die Sortierung müsste lange dauern, bevor ich mich der Pflege widmen würde. – sarnold

+0

Möchten Sie einen Vergleich (d. H. Weniger als, größer oder gleich) oder einen Ja-oder-Nein-Gleichheitstest? –

+0

@gbacon: Ich möchte etwas, das ich bestellen kann, also weniger als, größer als, gleich. –

Antwort

5

deaktivieren locale Überlegungen für den Block und verwenden cmp wie gewohnt:

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

Die perlop Dokumentation bietet

lt, le, ge, gt und cmp die Sortierung verwenden (sortiert) Reihenfolge, die durch das aktuelle Gebietsschema angegeben wird, wenn use locale in Kraft ist. Siehe perllocale.

und dann in perllocale

Das Standardverhalten mit dem no locale Pragma wiederhergestellt wird, oder auf das Ende des Blocks use locale umschließt erreicht.

Zum Beispiel läuft

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

Ausgänge

-1 
1
+0

Gilt "kein Gebietsschema" nur innerhalb der Schließung? Wenn es ein Gebietsschema gibt, das außerhalb des Abschlusses gilt, gilt es immer noch für einen Code unterhalb des Abschlusses? –

+0

@PP Ja, das 'locale'-Pragma ist lexikalisch: es ist nur innerhalb seines umschließenden Blocks wirksam. –

0

Hier laut denken - werden bitweise Operatoren helfen? Wie tut einen xor auf zwei identischen Strings eine bitstring mit allem, was auf 0.

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

+0

xor wäre ein großer Gleichheitstest unabhängig vom Gebietsschema, eigentlich - nette Idee - wäre nicht nützlich für weniger als/größer als jedoch. –

4

Expand, then contract. Vergleichen Sie zum Beispiel festlegen gibt die hexadezimale Darstellung Ihre Strukturen, die nur ASCII-Zeichen verwendet und kann nicht in Konflikt mit den Lokalisierungs laufen Problem, das du erwähnst.

unpack('H*', $first) cmp unpack('H*', $second) 
Verwandte Themen