Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

566
Views
En Java, ¿cómo obtener posiciones de unos en forma binaria invertida de un número entero?

Tengo una aplicación heredada que toma un número entero, lo convierte en una cadena binaria, invierte esa cadena y luego obtiene las posiciones de los bits (unos) como una lista de números enteros. Por ejemplo:

 6 -> "110" -> "011" -> (2,3) 7 -> "111" -> "111" -> (1,2,3) 8 -> "1000" -> "0001" -> (4)

¿Cuál es una forma sucinta y clara de lograr esto en Java moderno sin las operaciones de cadena? La conversión hacia y desde String me parece un desperdicio, y sé que de todos modos no hay una manera simple de voltear una Cadena (no String.reverse() ).

over 4 years ago · Santiago Trujillo
13 answers
Answer question

0

No necesita invertir la cadena binaria real. Puedes simplemente calcular el índice.

 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); }
over 4 years ago · Santiago Trujillo Report

0

Simplemente puede probar los bits sin convertir el número entero en una cadena:

 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; }

Los bits generalmente se cuentan de derecha a izquierda, siendo el bit más a la derecha el bit 0. La operación 1 << bit le da un int cuyo bit numerado se establece en 1 (y el resto en 0). Luego use & (y binario) para verificar si este bit está establecido en la input y, de ser así, registre la posición en la matriz de salida.

over 4 years ago · Santiago Trujillo Report

0

Simplemente verifique los bits a su vez:

 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; }

Demostración en línea

 6 [2, 3] 7 [1, 2, 3] 8 [4]
over 4 years ago · Santiago Trujillo Report

0

Simplemente use la función indexOf de la clase String

 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); } } }
over 4 years ago · Santiago Trujillo Report

0

Puedes usar esta solución:

 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; }

Produce:

 [2, 3] [1, 2, 3] [4]
over 4 years ago · Santiago Trujillo Report

0

Definitivamente preferiría la respuesta de Andy, incluso si parece críptica al principio. Pero como nadie aquí tiene una respuesta con las transmisiones todavía (incluso si están totalmente fuera de lugar aquí):

 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()); }
over 4 years ago · Santiago Trujillo Report

0

Como escribió "Java moderno", así es como se puede hacer con flujos (Java 8 o superior):

 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());

El mapa solo es necesario ya que empiezas a contar desde 1 y no desde 0.

Luego

 System.out.println(digits);

huellas dactilares

 [1, 2, 3]
over 4 years ago · Santiago Trujillo Report

0

Una respuesta tonta, solo por variedad:

 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); }

(Gracias a pero_hero por señalar que el enmascaramiento era necesario en la respuesta de WJS)

over 4 years ago · Santiago Trujillo Report

0

solo por diversión:

 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);
over 4 years ago · Santiago Trujillo Report

0

Dado el entero original, devuelve una lista con las posiciones de los bits.

 static List<Integer> bitPositions(int v) { return BitSet.valueOf(new long[]{v&0xFF_FF_FF_FFL}) .stream() .mapToObj(b->b+1) .collect(Collectors.toList()); }

O si quieres hacer cambios de bits.

 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; }
over 4 years ago · Santiago Trujillo Report

0

o si quieres:

 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());
over 4 years ago · Santiago Trujillo Report

0

¿Puedo proponer una solución bit-wise pura?

 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; }

Esta solución es algorítmicamente óptima:

  1. Asignación de memoria única, usando Integer.bitCount para dimensionar apropiadamente ArrayList por adelantado.
  2. Número mínimo de iteraciones de bucle, una por bit establecido 1 .

El bucle interno es bastante simple:

  • Integer.lowestOneBit devuelve un int con solo el bit más bajo del conjunto de entrada.
  • input - one "desestablece" este bit de la entrada, para la próxima iteración.
  • Integer.numberOfTrailingZeros cuenta el número de ceros finales, en binario, dándonos efectivamente el índice del bit más bajo.

1 Es notable que esta puede no ser la forma más óptima una vez compilada y que, en cambio, un bucle explícito 0..n basado en bitCount sería más fácil de desarrollar para el JIT.

over 4 years ago · Santiago Trujillo Report

0

una versión corriente de @Matthieu M. respuesta:

 List<Integer> list = IntStream.iterate(value, (v) -> v != 0, (v) -> v & (v - 1)) .mapToObj(val -> Integer.numberOfTrailingZeros(val) + 1) .collect(toList());
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!