![](/img/trans.png)
[英]How to convert a negative integer into two's complement binary form? (Java)
[英]In Java, how to get positions of ones in reversed binary form of an integer?
我有一個遺留應用程序,它采用 integer,將其轉換為二進制字符串,反轉該字符串,然后將位(一個)的位置作為整數列表。 例如:
6 -> "110" -> "011" -> (2,3)
7 -> "111" -> "111" -> (1,2,3)
8 -> "1000" -> "0001" -> (4)
在沒有字符串操作的情況下,在現代 Java 中實現此目的的簡潔明了的方法是什么? 與 String 之間的轉換對我來說似乎很浪費,而且我知道無論如何都沒有簡單的方法來翻轉 String(沒有String.reverse()
)。
只需依次檢查位:
List<Integer> bits(int num) {
List<Integer> setBits = new ArrayList<>();
for (int i = 1; num != 0; ++i, num >>>= 1) {
if ((num & 1) != 0) setBits.add(i);
}
return setBits;
}
6 [2, 3]
7 [1, 2, 3]
8 [4]
您可以只測試這些位,而無需將 integer 轉換為字符串:
List<Integer> onePositions(int input) {
List<Integer> onePositions = new ArrayList<>();
for (int bit = 0; bit < 32; bit++) {
if (input & (1 << bit) != 0) {
onePositions.add(bit + 1); // One-based, for better or worse.
}
}
return onePositions;
}
位通常從右到左計數,最右邊的位是位 0。操作1 << bit
為您提供一個int
,其位編號bit
設置為 1(並且 rest 為 0)。 然后使用&
(二進制與)檢查input
中是否設置了該位,如果是,則將position記錄在output數組中。
我可以提出一個純粹的按位解決方案嗎?
static List<Integer> onesPositions(int input)
{
List<Integer> result = new ArrayList<Integer>(Integer.bitCount(input));
while (input != 0)
{
int one = Integer.lowestOneBit(input);
input = input - one;
result.add(Integer.numberOfTrailingZeros(one));
}
return result;
}
該解決方案在算法上是最優的:
Integer.bitCount
預先適當調整ArrayList
的大小。內部循環相當簡單:
Integer.lowestOneBit
返回一個只有輸入集最低位的int
。input - one
從輸入中“取消設置”該位,用於下一次迭代。Integer.numberOfTrailingZeros
以二進制計算尾隨零的數量,有效地為我們提供最低 1 位的索引。 1值得注意的是,這可能不是編譯后的最佳方式,而是基於bitCount
的顯式0..n
循環更容易為 JIT 展開。
由於您編寫了“現代 Java”,因此可以使用流(Java 8 或更高版本)來完成它:
final int num = 7;
List<Integer> digits = IntStream.range(0,31).filter(i-> ((num & 1<<i) != 0))
.map(i -> i+1).boxed().collect(Collectors.toList());
僅需要 map,因為您從 1 而不是 0 開始計數。
然后
System.out.println(digits);
印刷
[1, 2, 3]
我自己肯定更喜歡安迪的回答,即使一開始看起來很神秘。 但是由於這里沒有人對流有答案(即使它們在這里完全不合適):
public List<Integer> getList(int x) {
String str = Integer.toBinaryString(x);
final String reversed = new StringBuilder(str).reverse().toString();
return IntStream.range(1, str.length()+1)
.filter(i -> reversed.charAt(i-1)=='1')
.boxed()
.collect(Collectors.toList());
}
一個愚蠢的答案,只是為了多樣化:
BitSet bs = BitSet.valueOf(new long[] {0xFFFFFFFFL & input});
List<Integer> setBits = new ArrayList<>();
for (int next = -1; (next = bs.nextSetBit(next + 1)) != -1;) {
setBits.add(next + 1);
}
(感謝 pero_hero 指出 WJS 的回答需要屏蔽)
給定原始 integer 返回一個包含位位置的列表。
static List<Integer> bitPositions(int v) {
return BitSet.valueOf(new long[]{v&0xFF_FF_FF_FFL})
.stream()
.mapToObj(b->b+1)
.collect(Collectors.toList());
}
或者,如果您想進行位移。
static List<Integer> bitPositions(int v ) {
List<Integer> bits = new ArrayList<>();
int pos = 1;
while (v != 0) {
if ((v & 1) == 1) {
bits.add(pos);
}
pos++;
v >>>= 1;
}
return bits;
}
您不需要反轉實際的二進制字符串。 你可以只計算指數。
String str = Integer.toBinaryString(num);
int len = str.length();
List<Integer> list = new ArrayList<>();
for (int i=0; i < len; i ++) {
if (str.charAt(i) == '1') list.add(len - 1 - i);
}
純娛樂:
Pattern one = Pattern.compile("1");
List<Integer> collect = one.matcher(
new StringBuilder(Integer.toBinaryString(value)).reverse())
.results()
.map(m -> m.start() + 1)
.collect(Collectors.toList());
System.out.println(collect);
@Matthieu M 的 stream 版本。 答案:
List<Integer> list = IntStream.iterate(value, (v) -> v != 0, (v) -> v & (v - 1))
.mapToObj(val -> Integer.numberOfTrailingZeros(val) + 1)
.collect(toList());
您可以使用此解決方案:
static List<Integer> convert(int input) {
List<Integer> list = new ArrayList<>();
int counter = 1;
int num = (input >= 0) ? input : Integer.MAX_VALUE + input + 1;
while (num > 0) {
if (num % 2 != 0) {
list.add(counter);
}
++counter;
num /= 2;
}
return list;
}
它輸出:
[2, 3]
[1, 2, 3]
[4]
或者如果你想:
String strValue = Integer.toBinaryString(value);
List<Integer> collect2 = strValue.codePoints()
.collect(ArrayList<Integer>::new,
(l, v) -> l.add(v == '1' ? strValue.length() - l.size() : -1),
(l1, l2) -> l1.addAll(l2)).stream()
.filter(e -> e >= 0)
.sorted()
.collect(toList());
只需使用字符串indexOf
的索引 function
public class TestPosition {
public static void main(String[] args) {
String word = "110"; // your string
String guess = "1"; // since we are looking for 1
int totalLength = word.length();
int index = word.indexOf(guess);
while (index >= 0) {
System.out.println(totalLength - index);
index = word.indexOf(guess, index + 1);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.