Напишите программу, которая сбрасывает заданное количество последних битов числа java

Обновлено: 31.10.2024

Упражнения со строками Java [107 упражнений с решением]

[В нижней части страницы доступен редактор для написания и выполнения скриптов.]

<р>1. Напишите программу Java для получения символа по заданному индексу в строке. Перейти в редактор

<р>2. Напишите программу на Java, чтобы получить символ (кодовая точка Unicode) по заданному индексу в строке. Перейти в редактор

<р>3. Напишите программу Java, чтобы получить символ (кодовая точка Unicode) перед указанным индексом в строке. Перейти в редактор

<р>4. Напишите программу на Java для подсчета количества кодовых точек Unicode в указанном текстовом диапазоне строки. Перейти в редактор

<р>5. Напишите программу Java для лексикографического сравнения двух строк. Две строки лексикографически равны, если они имеют одинаковую длину и содержат одни и те же символы в одних и тех же позициях. Перейти в редактор

<р>6. Напишите программу на Java для лексикографического сравнения двух строк, игнорируя различия в регистре. Перейти в редактор

<р>7. Напишите программу на Java для объединения заданной строки с концом другой строки. Перейти в редактор

<р>8. Напишите программу на Java, чтобы проверить, содержит ли заданная строка указанную последовательность значений char. Перейти в редактор

<р>9. Напишите программу на Java для сравнения заданной строки с указанной последовательностью символов. Перейти в редактор

<р>10. Напишите программу на Java для сравнения заданной строки с заданным строковым буфером. Перейти в редактор

<р>11. Напишите программу Java для создания нового объекта String с содержимым массива символов. Перейти в редактор

<р>12. Напишите программу на Java, чтобы проверить, заканчивается ли данная строка содержимым другой строки. Перейти в редактор

<р>13. Напишите программу на Java, чтобы проверить, содержат ли два объекта String одни и те же данные. Перейти в редактор

<р>14. Напишите программу на Java для сравнения заданной строки с другой строкой, игнорируя рассмотрение регистра. Перейти в редактор

<р>15. Напишите программу Java для печати текущей даты и времени в указанном формате. Перейти в редактор

Примечание. : текущая дата и время изменятся в соответствии с датой и временем вашей системы.

<р>16. Напишите программу на Java, чтобы получить содержимое заданной строки в виде массива байтов. Перейти в редактор

<р>17. Напишите программу на Java, чтобы получить содержимое заданной строки в виде массива символов. Перейти в редактор

<р>18. Напишите программу Java для создания уникального идентификатора данной строки. Перейти в редактор

<р>19. Напишите программу на Java, чтобы получить индекс всех символов алфавита. Перейти в редактор

Образец строки всего алфавита: "Быстрая коричневая лиса перепрыгивает через ленивую собаку".

<р>20. Напишите программу на Java, чтобы получить каноническое представление строкового объекта. Перейти в редактор

21. Напишите программу на Java, чтобы получить последний индекс строки в строке. Перейти в редактор

Образец строки всего алфавита: "Быстрая коричневая лиса перепрыгивает через ленивую собаку".

22. Напишите программу на Java, чтобы получить длину заданной строки. Перейти в редактор

23. Напишите программу на Java, чтобы определить, соответствует ли область в текущей строке области в другой строке. Перейти в редактор

24. Напишите программу Java для замены указанного символа другим символом. Перейти в редактор

25. Напишите программу на Java для замены каждой подстроки заданной строки, которая соответствует заданному регулярному выражению, заданной заменой. Перейти в редактор

Пример строки: "Быстрая коричневая лиса перепрыгивает через ленивую собаку".

В приведенной выше строке замените все лисы на кошку.

26. Напишите программу на Java, чтобы проверить, начинается ли данная строка с содержимого другой строки. Перейти в редактор

27. Напишите программу на Java, чтобы получить подстроку заданной строки между двумя указанными позициями. Перейти в редактор

28. Напишите программу на Java для создания массива символов, содержащего содержимое строки. Перейти в редактор

29. Напишите программу на Java для преобразования всех символов строки в нижний регистр. Перейти в редактор

<р>30. Напишите программу Java для преобразования всех символов строки в верхний регистр. Перейти в редактор

31. Напишите программу на Java, чтобы обрезать все начальные или конечные пробелы в заданной строке. Перейти в редактор

32. Напишите программу на Java для поиска самой длинной палиндромной подстроки в строке. Перейти в редактор

33. Напишите программу на Java для поиска всех чередований заданных строк. Перейти в редактор

34. Напишите программу на Java для поиска второго наиболее часто встречающегося символа в заданной строке. Перейти в редактор

35. Напишите программу на Java для вывода всех перестановок заданной строки с повторением. Перейти в редактор

36. Напишите программу на Java, чтобы проверить, являются ли две строки промежутком между данной строкой. Предполагая, что уникальные символы в обеих строках. Перейти в редактор

37.Напишите программу на Java, чтобы найти длину самой длинной подстроки заданной строки без повторяющихся символов. Перейти в редактор

38. Напишите программу Java для печати после удаления дубликатов из заданной строки. Перейти в редактор

39. Напишите программу на Java для поиска первого неповторяющегося символа в строке. Перейти в редактор

40. Напишите программу на Java, которая делит строку на n равных частей. Перейти в редактор

41. Напишите программу Java для удаления повторяющихся символов из заданной строки, представленной в другой заданной строке. Перейти в редактор

42. Напишите программу на Java для вывода элементов списка, содержащих все символы заданного слова. Перейти в редактор

43. Напишите программу на Java, чтобы найти максимальное количество символов в строке. Перейти в редактор

44. Напишите программу на Java, которая реверсирует строку с помощью рекурсии. Перейти в редактор

45. Напишите программу на Java, которая переворачивает слова в заданной строке. Перейти в редактор

46. Напишите программу на Java, которая переворачивает каждое слово в строке с помощью методов. Перейти в редактор

47. Напишите программу на Java, которая переставляет строку так, чтобы все одинаковые символы находились на расстоянии d. Перейти в редактор

48. Напишите программу на Java, чтобы удалить "b" и "ac" из заданной строки. Перейти в редактор

49. Напишите программу на Java для поиска первого неповторяющегося символа в потоке символов. Перейти в редактор

<р>50. Напишите программу на Java для определения лексикографического ранга заданной строки. Перейти в редактор

NB: Всего возможных перестановок BDCA (лексикографический порядок):
ABCD ABDC ACBD ACDB ADBC ​​ADCB BACD BADC BCAD BCDA BDAC BDCA
1 2 3 4 5 6 7 8 9 10 11 12
/>БДКА появляются в 12 позиции перестановки (лексикографический порядок).

51. Напишите программу на Java для подсчета и вывода всех дубликатов во входной строке. Перейти в редактор

52. Напишите программу на Java, чтобы проверить, являются ли две заданные строки поворотами друг друга. Перейти в редактор

<р>53. Напишите программу на Java для сопоставления двух строк, одна из которых содержит подстановочные знаки. Перейти в редактор

<р>54. Напишите программу на Java для поиска наименьшего окна в строке, содержащей все символы другой строки. Перейти в редактор

55. Напишите программу Java для рекурсивного удаления всех смежных дубликатов из заданной строки. Перейти в редактор

56. Напишите программу на Java для добавления двух заданных строк таким образом, чтобы, если конкатенация создает двойные символы, пропустить один из символов. Перейти в редактор

<р>57. Напишите программу Java для создания новой строки из заданной строки, заменяющей местами последние два символа заданной строки. Длина данной строки должна быть не менее двух. Перейти в редактор

<р>58. Напишите программу на Java, которая считывает строку и возвращает true, если она заканчивается указанной строкой длины 2. Перейдите в редактор

<р>59. Напишите программу Java для чтения строки, если строка начинается с «красного» или «черного», верните строку этого цвета, в противном случае верните пустую строку. Перейти в редактор

60. Напишите программу на Java, которая считывает две строки, соединяет их вместе и возвращает результат. Если строки имеют разную длину, удалите символы из начала более длинной строки и сделайте их одинаковой длины. Перейти в редактор

61. Напишите программу на Java, чтобы создать новую строку, берущую указанное количество символов из первой и последней позиции заданной строки. Перейти в редактор

62. Напишите программу на Java, которая считывает строку и возвращает значение true, если в данной строке появляется слово «хорошо», начиная с индекса 0 или 1. Перейти в редактор

63. Напишите программу на Java, чтобы проверить, присутствуют ли первые два символа в конце заданной строки. Перейти в редактор

64. Напишите программу Java для чтения строки, и если подстрока длины два появляется как в ее начале, так и в конце, верните строку без подстроки в начале, в противном случае верните исходную строку без изменений. Перейти в редактор

65. Напишите программу Java для чтения заданной строки, и если первый или последний символы совпадают, верните строку без этих символов, в противном случае верните строку без изменений. Перейти в редактор

66. Напишите программу на Java для чтения строки и возврата строки без первых двух символов. Оставьте первый символ, если это «g», и оставьте второй символ, если это «h». Перейти в редактор

67. Напишите программу Java для чтения строки, и если один или оба первых двух символа равны заданному символу, возврат без этих символов, в противном случае возвращает строку без изменений. Перейти в редактор

68. Напишите программу на Java для чтения строки и возврата после удаления указанного символа и его непосредственных левого и правого символов. Перейти в редактор

69. Напишите программу на Java, которая возвращает подстроку, которая находится между первым и последним появлением подстроки «toast» в заданной строке, или возвращает пустую строку, если подстрока «toast» не существует. Перейти в редактор

70. Напишите программу на Java, чтобы проверить, является ли строка pq-сбалансированной или нет.Строка является pq-сбалансированной, если для всех p в строке по крайней мере один "q" должен существовать справа от p. Но "q" до "p" делает pq-сбалансированный ложным. Перейти в редактор

71. Напишите Java-программу для проверки двух заданных строк на наличие одной из них в конце другой строки (без учета регистра). Перейти в редактор

72. Напишите программу на Java, которая возвращает true, если заданная строка содержит строку «pop», но средний «o» также может быть другим символом. Перейти в редактор

73. Напишите программу на Java, чтобы проверить, появляется ли подстрока перед точкой (.) в данной строке. Перейти в редактор

74. Напишите программу на Java, чтобы проверить, создается ли строка префикса с использованием первых определенных символов в данной строке, появляется ли где-то еще в строке. Перейти в редактор

75. Напишите программу на Java, чтобы проверить, присутствует ли данная подстрока в середине другой заданной строки. Здесь под серединой понимается разница между количеством символов слева и справа от заданной подстроки не более 1. Перейти в редактор

76. Напишите программу на Java, чтобы подсчитать, сколько раз подстрока «жизнь» присутствует в любом месте данной строки. Подсчет также может происходить для подстроки 'li?e', любого символа вместо 'f'. Перейти в редактор

77. Напишите программу на Java, чтобы добавить строку с определенным количеством раз, разделенных подстрокой. Перейти в редактор

78. Напишите программу Java, которая повторяет определенное количество символов определенное количество раз из последней части заданной строки. Перейти в редактор

79. Напишите программу Java для создания новой строки из заданной строки после удаления второго символа из подстроки длины три, начинающейся с «z» и заканчивающейся «g», представленной в указанной строке. Перейти в редактор

<р>80. Напишите программу на Java, чтобы проверить, является ли символ непосредственно перед и после указанного символа одинаковым в данной строке. Перейти в редактор

81. Напишите программу на Java, чтобы проверить, встречаются ли две строки длины 3 и 4 одинаковое количество раз в заданной строке. Перейти в редактор

82. Напишите программу Java для создания новой строки, дважды повторяющей каждый символ заданной строки. Перейти в редактор

83. Напишите программу на Java, чтобы создать новую строку из двух заданных строк таким образом, чтобы каждый символ двух строк приходил соответственно. Перейти в редактор

84. Напишите программу на Java, чтобы создать новую строку, состоящую из p символов, начиная с первого в заданной строке, за которыми следует p-1 число символов, пока p не станет больше нуля. Перейти в редактор

85. Напишите программу на Java, чтобы создать новую строку с каждым символом непосредственно перед и после непустой подстроки, в зависимости от того, что он появляется в непустой заданной строке. Перейти в редактор

86. Напишите программу на Java для подсчета количества троек (символов, появляющихся три раза подряд) в заданной строке. Перейти в редактор

87. Напишите программу на Java, чтобы проверить, является ли указанный символ счастливым или нет. Символ счастлив, когда один и тот же символ появляется слева или справа от него в строке. Перейти в редактор

88. Напишите программу на Java, которая возвращает строку, в которой каждое вхождение слова «есть» в нижнем регистре заменено на «не является». Перейти в редактор

89. Напишите программу на Java для вычисления суммы чисел, встречающихся в заданной строке. Перейти в редактор

90. Напишите программу на Java для проверки количества вхождений двух подстрок в любом месте строки. Перейти в редактор

91. Напишите программу Java для подсчета количества слов, оканчивающихся на «m» или «n» (без учета регистра) в заданном тексте. Перейти в редактор

92. Напишите программу на Java, которая возвращает подстроку после удаления всех экземпляров строки удаления, заданной из заданной основной строки. Перейти в редактор

93. Напишите программу на Java, чтобы найти самую длинную подстроку, которая появляется на обоих концах заданной строки. Перейти в редактор

94. Напишите программу на Java для поиска самой длинной строки зеркального отображения на обоих концах заданной строки. Перейти в редактор

95. Напишите программу на Java, которая возвращает сумму цифр, присутствующих в заданной строке. Если цифр нет, сумма возвращается 0. Перейти в редактор

96. Напишите программу Java для создания новой строки после удаления указанного символа из заданной строки, за исключением первой и последней позиции. Перейти в редактор

97. Напишите программу на Java, которая возвращает строку с символами позиции индекса 0,1,2, 5,6,7, . из заданной строки. Перейти в редактор

98. Напишите программу на Java, чтобы проверить, следует ли сразу же за первым экземпляром данного символа тот же символ в данной строке. Перейти в редактор

99. Напишите программу на Java, которая возвращает новую строку, используя каждый символ четных позиций из заданной строки. Перейти в редактор

100. Напишите программу на Java, чтобы проверить, содержит ли данная строка другую строку. Вернуть истину или ложь. Перейти в редактор

101.Напишите программу на Java, чтобы проверить, содержит ли заданная строка только цифры. Вернуть истину или ложь. Перейти в редактор

102. Напишите программу Java для преобразования заданной строки в int, long, float и double. Перейти в редактор

103. Напишите программу на Java для удаления указанного символа из заданной строки. Перейти в редактор

104. Напишите программу Java для сортировки по возрастанию и убыванию длины заданного массива строк. Перейти в редактор

105. Напишите программу на Java для подсчета вхождений данной строки в другую заданную строку. Перейти в редактор

106. Напишите программу на Java для объединения данной строки с самой собой заданное количество раз. Перейти в редактор

107. Напишите программу на Java для подсчета вхождений определенного символа в заданную строку. Перейти в редактор

Редактор кода Java:

Ещё впереди!

Не отправляйте сюда решение приведенных выше упражнений. Если вы хотите внести свой вклад, перейдите на соответствующую страницу упражнений.

Пусть входное число равно n. n-1 перевернул бы все биты после самого правого установленного бита (включая установленный бит). Таким образом, выполнение n&(n-1) даст нам требуемый результат.

Итак, теперь давайте посмотрим, как n – 1 переворачивает все биты вправо (включая самый правый установленный бит) числа n.
Возьмем n = 12, поэтому (n – 1) = 11,

n можно записать как (n = (n – 1) + 1), так что теперь мы можем думать об этой задаче как о добавлении 1 к любому числу (см. эту статью для лучшего понимания)
Двоичное представление (n-1) = 11 = 1011, поэтому теперь давайте составим n из (n-1), что можно сделать, добавив 1 на (n-1)
При добавлении 1 к любому числу X все биты справа от крайнего правого 0 (включая самый правый нуль) переворачиваются
(n -1) = 1011

(n-1) + 1 = 1100 (все биты справа от крайнего правого нуля (включая самый правый нуль) перевернуты)
Поскольку мы перевернули самый правый нуль, поэтому теперь самый правый нуль заменяется на крайний правый 1 (он же самый правый установленный бит числа n), а все биты до крайнего правого 0 такие же, как и раньше
X = 010 . . . . . 0 (самый правый ноль) 111

Х + 1 = 010 . . . . . 1 (самый правый) 0 0 0

X = 71 = Думайте об этом как n – 1

Двоичное представление X = 1000111

X + 1 = 72 = Думайте об этом как n

Двоичное представление (X+1) = 1001000
Наблюдение:

1. Все биты слева от самого правого 0 (за исключением самого правого 0) в X (думая, что это n – 1) такие же, как и слева от самой правой 1 (за исключением самого правого 1) в X + 1 (думая это как n)

2. Все биты справа от самого правого 0 (включая самый правый 0) в X (думая, что это n – 1) отличаются от битов справа от самого правого 1 (включая самый правый 1) в X + 1 (думая это как n)

Таким образом, побитовое И левой части X (до крайнего правого 0, исключая самый правый 0) и левой части X + 1 (до крайнего правого 1, исключая крайний правый 1) даст требуемый ответ, побитовое И правой части X (от самый правый 0) и правая часть X + 1 (от крайнего правого 1 (крайний правый установленный бит)) приведет к 0

Я работал над упражнением по программированию и застрял в поиске правильного алгоритма. Вот проблема:

  1. Изменить бит i, если следующий бит i+1 равен 1, а все остальные биты i+2 и последующие равны 0
  2. Изменить последний бит без ограничений

всего требуется 15 шагов.

Дополните следующее определение:

Можно получить псевдокод или просто алгоритм. Это не домашнее задание или задание.

@Fureeish Люди там могут подумать, что StackOverflow — это автоматическая машина для домашних заданий. Не стал бы их винить. Мог обмануть кого угодно. :)

Это простой поиск графа в ширину. Узлы — это двоичные значения; ребра являются допустимыми ходами из каждого узла. В сети есть много примеров таких поисков. Кодируйте свои переходы, проверяйте результат. Напишите здесь, если вы застряли.

6 ответов 6

Это замечательная задача для рекурсивного алгоритма.

Если длина двоичного представления равна 0, вы уже можете сказать ответ. Или, если длина 0 не разрешена, то, если длина равна 1, вы говорите ответ в зависимости от того, равен ли этот бит 0 или 1.

Если длина больше 1:

  • Если первый бит равен 0, ответ будет таким же, как и без этого 0-бита. Удалите его и вызовите рекурсивно, чтобы получить ответ.
  • Если первый бит равен 1, разделите на три подзадачи и найдите количество шагов для каждой:
    1. Создайте ситуацию, в которой вам разрешено менять начальную 1 на 0. Это означает, что за ней должна следовать 1, а затем все 0. Напишите для этого рекурсивный вспомогательный алгоритм. Он будет очень похож на основной алгоритм, и, вероятно, у них может быть общая логика.
    2. Поменять 1 на 0 (1 шаг)
    3. Преобразуйте оставшиеся биты в 0.Еще один рекурсивный вызов.

Алгоритм может занять много времени. На самом деле это подсчет шагов, поэтому требуется время, пропорциональное количеству шагов, которое, я думаю, примерно пропорционально введенному числу. Ваш метод принимает длинный аргумент, но с моим алгоритмом для больших длинных значений он может не завершиться в течение срока службы компьютера, на котором он работает. Также количество шагов может переполнить целое и даже длинное (если входное значение является отрицательным длинным).

Быстрый способ

Следующее решение не требует рекурсии и выполняется за постоянное время. Я не могу правильно объяснить, как это работает, что является серьезной проблемой, если мы хотим использовать его для чего-то. Я поиграл с некоторыми примерами, увидел закономерность и обобщил ее. Напротив, ИМХО, красота рекурсивного решения выше заключается в том, что его легко понять (если вы понимаете рекурсию).

Пример: введите 8 или 1000 в двоичном формате. Результат 15 или 1111 двоичный. Шаблон таков: каждый бит результата является XOR предыдущего бита результата и бита в той же позиции во входных данных. Таким образом, из 1000 просто скопируйте передний бит, 1. Следующий бит — это 1 XOR 0 = 1, где 1 — передний бит результата, а 0 берется из ввода. Оставшиеся два бита вычисляются таким же образом.

Длинный пример, чтобы вы могли проверить, поняли ли вы:

Я проверил этот метод на моей собственной реализации первого алгоритма выше, используя различные входные данные до 100 000 000, и они всегда совпадают, поэтому я считаю, что быстрый метод тоже правильный. Я по-прежнему предлагаю вам написать код, запустить и протестировать его, чтобы убедиться, что я все понял правильно.

например: двоичное число 12 равно 1100, поэтому ответ должен быть 3, так как установлен 3-й бит справа.

Мне нужна позиция последнего установленного бита файла . Может ли кто-нибудь сказать мне, как я могу это сделать.

ПРИМЕЧАНИЕ. Мне нужна только позиция, здесь я не хочу устанавливать или сбрасывать бит. Так что это не дубликат любого вопроса в stackoverflow.

17 ответов 17

В этом ответе «Сбросить самый правый установленный бит» рассказывается, как получить и сбросить самый правый установленный бит для целого числа без знака или целого числа со знаком, представленного в виде дополнения до двух.

получить крайний правый установленный бит,

снять крайний правый установленный бит,

почему это работает

Это хорошее объяснение, но неверный ответ. Этот код возвращает целое число только с установленным крайним правым битом, но он не делает то, что задает вопрос, и возвращает битовую позицию этого бита (+1 за OP).

Нахождение (отсчитываемого от 0) индекса младшего значащего бита эквивалентно подсчету количества нулей в конце заданного целого числа. В зависимости от вашего компилятора для этого есть встроенные функции, например gcc и clang поддерживают __builtin_ctz . Для MSVC вам нужно будет реализовать свою собственную версию, этот ответ на другой вопрос показывает решение, использующее встроенные функции MSVC.

Учитывая, что вы ищете индекс, основанный на 1, вам просто нужно добавить 1 к результату ctz, чтобы получить то, что вы хотите.

Обратите внимание, что эта операция не определена, если a == 0 . Кроме того, существуют __builtin_ctzl и __builtin_ctzll, которые следует использовать, если вы работаете с long и long long вместо int .

Привет, кажется лучшим решением (!). Предложение дополнить пояснения. Есть некоторая путаница в отношении «самого правого», «самого левого», «начиная с позиции самого старшего бита» и «наименее значимого». Итак, путаница с CLZ и CTZ и их __builtin_cXz. Можете ли вы также объяснить жаргон и выбор CLZ/CTZ?

Я не согласен с тем, что крайний правый и крайний левый здесь путаются. Любой, кто когда-либо считал до десяти на бумаге, знает, что правая цифра менее значительна, чем левая.

Я думаю, что это лучший ответ. Он решает правильную проблему и делает это за постоянное время и не требует функции журнала.

Самый левый бит числа n можно получить по формуле: n & ~(n-1)

Это работает, потому что когда вы вычисляете (n-1) .. вы на самом деле делаете все нули до самого правого бита равным 1, а самый правый бит равным 0. Затем вы берете НЕ из этого .. что оставляет вас с следующее: x= ~(биты от исходного числа) + (крайний правый 1 бит) + конечные нули

Теперь, если вы сделаете (n & x), вы получите то, что вам нужно, поскольку единственный бит, который равен 1 в обоих n и x, является самым правым битом.

Я думаю, вы имеете в виду «Самый правый бит n можно получить с помощью формул: n & ~ (n-1)»? кроме этого, этот ответ идеально подходит, чтобы объяснить, почему, а не как.

Как и в случае с другими ответами, это хорошее объяснение, но неправильный ответ. Этот код возвращает целое число только с установленным крайним правым битом, но он не делает то, что задает вопрос, и возвращает битовую позицию этого бита (+1 за OP).

Здесь можно использовать свойство 2s-дополнения.
Самый быстрый способ найти дополнение числа до 2 – это получить самый правый установленный бит и перевернуть все слева от него.
Например: рассмотрим 4-битную систему
4=0100
2-е дополнение 4 = 1100, что означает не что иное, как -4
4&(-4)=0100.
Обратите внимание, что существует только один установленный бит, и это крайний правый установленный бит, равный 4.
Аналогичным образом мы можем обобщить это для n.
n&(-n) будет содержать только один установленный бит, который фактически находится в самой правой позиции установленного бита n.
поскольку в n&(-n) есть только один установленный бит, это степень числа 2.
Итак, наконец, мы можем получить позицию бита с помощью:

Должно ли это решение явно обрабатывать случай, когда (n & -n) == 0? Потому что log2(0) выдает -inf, который не является допустимым целым числом?

В Knuth 7.1.3 есть хитрый трюк, когда вы умножаете на "волшебное" число (найденное методом грубой силы), которое сопоставляет первые несколько битов числа с уникальным значением для каждой позиции самого правого бит, а затем вы можете использовать небольшую таблицу поиска. Вот реализация этого трюка для 32-битных значений, адаптированная из библиотеки nlopt (лицензия MIT/expat).

1- Вычесть 1 номер формы: (a-1)

2- Возьмем отрицание: ~(a-1)

3- Выполните операцию "И" с исходным числом:

int last_set_bit = a & ~(a-1)

Причина вычитания заключается в том, что при отрицании последний бит устанавливается равным 1, поэтому при выполнении операции "И" выдается последний установленный бит.

Попробуйте это

Объяснение:
Как отмечено в этом ответе, n&(n-1) сбрасывает последний установленный бит.
Итак, если мы сбросим последний установленный бит и выполним операцию xor с числом; по характеру операции xor последний установленный бит станет 1, а остальные биты вернут 0

Это возвращает целое число, являющееся степенью двойки: в нем установлен только тот бит, который является самым правым установленным битом в n. Я полагаю, что за него проголосовали против, потому что ОП запросил log2 этого (плюс один). То есть для 1100b он вернет 100b(4) вместо log2(4) + 1 = 3. Я не голосовал против этого, я думаю, что это все еще полезно.

Вы можете найти позицию самого правого установленного бита, выполнив побитовое исключающее ИЛИ n и (n&(n-1))

Это неправильно. Если n=4 или 0b100, ответ должен быть 2, при нулевой индексации. 100 и 011 = 000; 100 ^ 000 = 100, то есть 4 вместо ожидаемых 2.

Проверьте, равно ли a & 1 0. Если да, сдвиньте вправо на единицу, пока оно не станет ненулевым. Количество сдвигов – это количество битов справа от самого правого установленного бита.

Этот я унаследовал с пометкой, что он пришел от HAKMEM (попробуйте здесь). Он работает как с целыми числами со знаком, так и без знака, с логическим или арифметическим сдвигом вправо. Это также довольно эффективно.

Вы должны проверить все 32 бита, начиная с индекса 0 и продвигаясь влево. Если вы можете выполнить побитовое преобразование с одним битом в этой позиции и получить обратно ненулевое значение, это означает, что бит установлен.

В типичных системах int будет 32-битным, но размер * CHAR_BIT даст вам правильное количество битов в a, даже если он другого размера

Согласно решению dbush, попробуйте следующее:

пояснение с примером: 12 - 1100

число^ (число-1) = 12^11 = 7 (111)

число^ (число-1))+1 = 8 (1000)

log2(1000) = 3 (ответ).

x & ~(x-1) изолирует младший бит, равный единице.

И результат такой, как показано ниже.

Пусть x будет вашим целочисленным вводом. Побитовое И на 1. Если оно четное, т.е. 0, 0&1 вернет вам 0. Если оно нечетное, т.е. 1, 1&1 вернет вам 1.

На этот вопрос существует пятнадцать существующих ответов, включая ответ, набравший 30 голосов. Вы уверены, что ваш ответ еще не был предоставлен? Если нет, то почему кто-то может предпочесть ваш подход существующим предложенным подходам? Используете ли вы новые возможности? Есть ли сценарии, в которых ваш подход лучше подходит?

Хорошо, поэтому системы счисления просто работают с логарифмами и показателями степени. Итак, я углублюсь в подход, который действительно имеет для меня смысл.

Я бы предпочел, чтобы вы прочитали это, потому что я пишу там о том, как я интерпретирую логарифмы.

Когда вы выполняете операцию x & -x, она дает вам значение, в котором самый правый бит равен 1 (например, это может быть 0001000 или 0000010 . Теперь, согласно тому, как я интерпретирую логарифмы, это значение самый правый установленный бит, является конечным значением после того, как я увеличиваюсь со скоростью 2. Теперь нас интересует количество цифр в этом ответе, потому что, что бы это ни было, если вы вычтете из него 1, это именно бит-счетчик установленного бита (бит-счетчик здесь начинается с 0, а счетчик цифр начинается с 1, так что да) Но количество цифр - это именно то время, которое вы расширили до + 1 (в соответствии с моей логикой) или просто формула, которую я упомянул в предыдущей ссылке. Но теперь, поскольку нам действительно не нужны цифры, а нужен счетчик битов, и нам также не нужно беспокоиться о значениях битов что потенциально может быть реальным (если число равно 65), потому что число всегда кратно 2 (кроме 1). Поэтому, если вы просто возьмете логарифм значения x & -x , мы получим в бит счет! Я видел ответ до того, как он упомянул об этом, но мне захотелось написать, почему это действительно работает.

Этот класс реализует вектор битов, который увеличивается по мере необходимости. Каждый компонент набора битов имеет логическое значение. Биты BitSet индексируются неотрицательными целыми числами. Отдельные индексированные биты могут быть проверены, установлены или очищены. Один BitSet может использоваться для изменения содержимого другого BitSet с помощью операций логического И, логического включающего ИЛИ и логического исключающего ИЛИ.

По умолчанию все биты в наборе изначально имеют значение false .

Каждый битовый набор имеет текущий размер, который представляет собой количество бит пространства, используемого в данный момент битовым набором. Обратите внимание, что размер связан с реализацией набора битов, поэтому он может меняться в зависимости от реализации. Длина набора битов связана с логической длиной набора битов и определяется независимо от реализации.

Если не указано иное, передача нулевого параметра любому из методов в BitSet приведет к исключению NullPointerException .

BitSet небезопасен для многопоточного использования без внешней синхронизации.

Сводка конструктора

Создает набор битов, начальный размер которого достаточно велик для явного представления битов с индексами в диапазоне от 0 до nbits-1 .

Краткое описание метода

Все методы Статические методы Методы экземпляров Конкретные методы
Модификатор и тип Метод и описание
void and (набор BitSet)

Устанавливает биты от указанного fromIndex (включительно) до указанного toIndex (исключая) в значение false .

Устанавливает каждый бит из указанного fromIndex (включительно) в указанный toIndex (исключительно) в дополнение к его текущему значению.

Возвращает новый BitSet, состоящий из битов из этого BitSet от fromIndex (включительно) до toIndex (исключительно).

Возвращает значение true, если в указанном BitSet есть какие-либо биты, установленные в true, которые также установлены в true в этом BitSet.

Возвращает индекс первого бита со значением false, который встречается после указанного начального индекса или после него.

Возвращает индекс первого бита со значением true, который встречается после указанного начального индекса или после него.

Возвращает индекс ближайшего бита, для которого задано значение false, который находится в указанном начальном индексе или перед ним.

Возвращает индекс ближайшего бита, для которого установлено значение true и который находится в указанном начальном индексе или перед ним.

Устанавливает биты от указанного fromIndex (включительно) до указанного toIndex (исключая) в значение true .

Устанавливает биты от указанного fromIndex (включительно) до указанного toIndex (исключительно) до указанного значения.

Возвращает новый набор битов, содержащий все биты в заданном байтовом буфере между его позицией и пределом.

Возвращает новый набор битов, содержащий все биты в заданном длинном буфере между его позицией и пределом.

Методы, унаследованные от класса java.lang.Object

Сведения о конструкторе

Битовый набор

Битовый набор

Создает набор битов, начальный размер которого достаточно велик для явного представления битов с индексами в диапазоне от 0 до nbits-1 . Все биты изначально равны false .

Сведения о методе

значение

Точнее,
BitSet.valueOf(longs).get(n) == ((longs[n/64] & (1L
для всех n .

Этот метод эквивалентен BitSet.valueOf(LongBuffer.wrap(longs)) .

значение

Возвращает новый набор битов, содержащий все биты в заданном длинном буфере между его позицией и пределом.

Точнее,
BitSet.valueOf(lb).get(n) == ((lb.get(lb.position()+n/64) & (1L
для всех n .

Длинный буфер не изменяется этим методом, и установленный бит не сохраняет ссылку на буфер.

значение

Точнее,
BitSet.valueOf(bytes).get(n) == ((bytes[n/8] & (1
для всех n .

Этот метод эквивалентен BitSet.valueOf(ByteBuffer.wrap(bytes)) .

значение

Возвращает новый набор битов, содержащий все биты в заданном байтовом буфере между его позицией и пределом.

Точнее,
BitSet.valueOf(bb).get(n) == ((bb.get(bb.position()+n/8) & (1
для всех n .

Буфер байтов не изменяется этим методом, и установка битов не сохраняет ссылки на буфер.

массив байтов

к длинному массиву

Точнее, если
long[] longs = s.toLongArray();
затем longs.length == (s.length()+63)/64 и
s.get(n) == ((longs[n/64] & (1L
для все н.

Устанавливает каждый бит из указанного fromIndex (включительно) в указанный toIndex (исключительно) в дополнение к его текущему значению.

Устанавливает биты от указанного fromIndex (включительно) до указанного toIndex (исключая) в значение true .

Устанавливает биты от указанного fromIndex (включительно) до указанного toIndex (исключительно) до указанного значения.

очистить

очистить

Устанавливает биты от указанного fromIndex (включительно) до указанного toIndex (исключая) в значение false .

очистить

Возвращает значение бита с указанным индексом. Значение истинно, если бит с индексом bitIndex в настоящее время установлен в этом BitSet; в противном случае результат будет ложным .

Возвращает новый BitSet, состоящий из битов из этого BitSet от fromIndex (включительно) до toIndex (исключительно).

следующий бит

Возвращает индекс первого бита с установленным значением true, который встречается в указанном начальном индексе или после него. Если такого бита не существует, возвращается -1.

Чтобы перебрать истинные биты в BitSet , используйте следующий цикл:

следующийClearBit

Возвращает индекс первого бита со значением false, который встречается после указанного начального индекса или после него.

предыдущийSetBit

Возвращает индекс ближайшего бита, для которого установлено значение true и который находится в указанном начальном индексе или перед ним. Если такого бита не существует или если в качестве начального индекса указано -1, то возвращается -1.

Чтобы перебрать истинные биты в BitSet , используйте следующий цикл:

предыдущийClearBit

Возвращает индекс ближайшего бита, для которого задано значение false и который находится в указанном начальном индексе или перед ним. Если такого бита не существует или если в качестве начального индекса указано -1, то возвращается -1.

длина

Возвращает «логический размер» этого BitSet: индекс старшего установленного бита в BitSet плюс один. Возвращает ноль, если BitSet не содержит установленных битов.

пусто

пересекается

Возвращает значение true, если в указанном BitSet есть какие-либо биты, установленные в true, которые также установлены в true в этом BitSet.

количество элементов

Выполняет логическое И этого целевого набора битов с установленным битом аргумента. Этот набор битов изменен таким образом, что каждый бит в нем имеет значение true тогда и только тогда, когда он изначально имел значение true и соответствующий бит в аргументе набора битов также имел значение true .

Выполняет логическое ИЛИ этого набора битов с аргументом набора битов. Этот набор битов изменяется таким образом, что бит в нем имеет значение true тогда и только тогда, когда он либо уже имеет значение true, либо соответствующий бит в аргументе набора битов имеет значение true .

  • Бит изначально имеет значение true , а соответствующий бит в аргументе имеет значение false .
  • Бит изначально имеет значение false , а соответствующий бит в аргументе имеет значение true .

и нет

хэш-код

Возвращает значение хэш-кода для этого набора битов. Хэш-код зависит только от того, какие биты установлены в этом BitSet.

Хеш-код определяется как результат следующего вычисления: обратите внимание, что хэш-код изменяется, если изменяется набор битов.

Возвращает количество бит пространства, фактически используемого этим BitSet для представления битовых значений. Максимальный элемент в наборе - это размер - 1-й элемент.

равно

Сравнивает этот объект с указанным объектом. Результат является истинным тогда и только тогда, когда аргумент не равен нулю и является объектом Bitset, который имеет точно такой же набор битов, установленный в значение true, как этот набор битов. То есть для каждого неотрицательного индекса int k должно быть истинным. Текущие размеры двух наборов битов не сравниваются.

клон

Клонирование этого BitSet создает новый BitSet, равный ему. Клон набора битов — это другой набор битов, в котором точно такие же биты установлены в значение true, как и в этом наборе битов.

к строке

Возвращает строковое представление этого набора битов. Для каждого индекса, для которого этот BitSet содержит бит в установленном состоянии, десятичное представление этого индекса включается в результат. Такие индексы перечислены в порядке от наименьшего к наибольшему, разделены ", " (запятая и пробел) и окружены фигурными скобками, что приводит к обычной математической нотации для набора целых чисел.

Пример: теперь drPepper.toString() возвращает " <> ". Теперь drPepper.toString() возвращает " ". Теперь drPepper.toString() возвращает " ".

поток

Возвращает поток индексов, для которых этот BitSet содержит бит в установленном состоянии. Индексы возвращаются в порядке от самого низкого до самого высокого. Размер потока — это количество битов в установленном состоянии, равное значению, возвращаемому методом кардинальности().

Установленный бит должен оставаться постоянным во время выполнения операции терминального потока. В противном случае результат операции терминального потока не определен.

  • Обзор:
  • Вложенный |
  • Поле | |
  • Подробности:
  • Поле | |

Сообщите об ошибке или функции.
Дополнительные справочные материалы по API и документацию для разработчиков см. в документации по Java SE. Эта документация содержит более подробные описания, предназначенные для разработчиков, с концептуальными обзорами, определениями терминов, обходными путями и примерами рабочего кода.
Авторские права © 1993, 2022, Oracle и/или ее дочерние компании. Все права защищены. Использование регулируется условиями лицензии.Также ознакомьтесь с политикой распространения документации.

Читайте также: