2つのbyte[]
配列がある場合、それらをCの配列と比較するための組み込み関数はありmemcmp()
ますか?
6 に答える
Memcmpは、s1の最初のnバイトが、s2の最初のnバイトよりも小さい、一致する、または大きいことがそれぞれ検出された場合、ゼロより小さい、等しい、またはより大きいintを返します。Equalsはブール値を返します。同じ機能ではありません。さらに、memcmpはバイトを符号なし文字として比較します。
私はこれがうまくいくと思います:
public int memcmp(byte b1[], byte b2[], int sz){
for(int i = 0; i < sz; i++){
if(b1[i] != b2[i]){
if(b1[i] >= 0 && b2[i] >= 0)
return b1[i] - b2[i];
if(b1[i] < 0 && b2[i] >= 0)
return 1;
if(b2[i] < 0 && b1[i] >= 0)
return -1;
if(b1[i] < 0 && b2[i] < 0){
byte x1 = (byte) (256 + b1[i]);
byte x2 = (byte) (256 + b2[i]);
return x1 - x2;
}
}
}
return 0;
}
(編集)実際、2の補数部分は必要ありません:
public static int memcmp(byte b1[], byte b2[], int sz){
for(int i = 0; i < sz; i++){
if(b1[i] != b2[i]){
if((b1[i] >= 0 && b2[i] >= 0)||(b1[i] < 0 && b2[i] < 0))
return b1[i] - b2[i];
if(b1[i] < 0 && b2[i] >= 0)
return 1;
if(b2[i] < 0 && b1[i] >=0)
return -1;
}
}
return 0;
}
Arrays.equals()があります。
対応する命令がハードウェアに存在する場合、JVM実装が実際にこれを最適化するかどうかはわかりませんが、疑わしいです。
また、Cを正しく覚えていれば、strcmpはnullターミネータまで機能します(C文字列に役立ちます)。Javaプログラマーがnullで終了する配列を気にすることはめったにないため、Arraysバージョンは配列全体を比較します。ただし、nullターミネータが気になる場合は、独自の関数を簡単に作成できます。
java.util.Arrays.equals (byte []、byte [])メソッドはあなたの友達です。
まあ、Arrays.equals()
良いですが、サブレンジを比較することはできません。この場合、パススルーArrays.listOf()
とそれ以降もあります.subList()
が、のようなプリミティブにはありませんbyte[]
。
実際には、直接memcmp()
同等のものはありません。ここに議論があります、そして私が知るとすぐにそれは今(15年)までに同じ状態にあります。java.nio.ByteBuffer
ほとんどの「ネイティブ」実装は、 (wrap()
メソッド、次に)を介した私のオプションによって実現できますequals()
。しかし、それはやや大量のコードです。
主題を完全に理解していない人のために:memcmp()
プラットフォームに依存する方法で実装されています。これは非常に効率的であり、現在Javaでは何もそれに近づいていません。少なくともインデックス範囲のチェックのために、手動サイクルはパフォーマンスの点ではるかに遠いです。多分いつかEmbeddedC/C++から来た人々はこのトピックに満足するでしょう:-)。
[Arrays.equals] [1]
[1]: http: //java.sun.com/j2se/1.5.0/docs/api/java/util/Arrays.html#equals(byte []、byte [])
Java 8では、バイトを符号なしの値として処理しても問題がない場合は、C / C++memcmpが実際に行うことです。
private static int memcmp(byte[] a, byte[] b, int sz) {
for (int i = 0; i < sz; i++) {
if (a[i] != b[i]) {
return Byte.toUnsignedInt(a[i]) - Byte.toUnsignedInt(b[i]);
}
}
return 0;
}