
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.250] |
![]() |
|
Сообщ.
#1
,
|
|
|
Есть 2-мерный массив, числа в массиве одного порядка и состоят из комбинаций 1 и 2. Например
![]() ![]() 2221 2222 2222 2222 1112 2222 2222 1211 2111 1122 2122 1221 2212 1222 1111 И есть "маски". Это тоже числа, количество цифр в этих числах не может превышать количество цифр в числах массива, т.е. для приведенного выше массива маска может содержать от 1 до 4 цифр. Маска формируется из цифр 0, 1 и 2, и показывает чему должны быть равны определенные разряды чисел массива (0 означает, что значение разряда не важно). Примеры масок: 2002, 11, 121, 221. Так маска 2002 означает, что самый старший и самый младший разряды должны быть равны 2, этой маске соответствуют числа 2222, 2112, 2212, 2122 из примера. Нужно в массиве найти все числа, соответствующие определенной маске. Потом этим числа будут участвовать в обработке. Т.к. реальные массивы имеют большую размерность, а число "масок" и их длина тоже могут меняться, хочется найти какой-то быстрый способ для такой проверки. Пробовал сделать через битовые операции, но не получилось. Может кто-то что-то подскажет? P.S.: пишется все это на Python, для работы с массивами используется NumPy. |
![]() |
Сообщ.
#2
,
|
|
В массиве следует поменять 2 на 0.
Маску надо поделить на две маски. Первая - это маска, у которой 1 там, где в твоей нули, и нули на месте 1 и 2. Вторая - это маска, у которой 2 заменены на 0. Теперь делаем (массив AND маска1) и сравниваем с (маска2). При совпадении - соответствует. Ну а нет - значит нет. |
Сообщ.
#3
,
|
|
|
если сопоставить числам бинарные коды n = 2221 = 1110b = 0x6, и каждой маске сопоставить пару бинарных масок m=2001 -> mz=1001b и mx=0001b, то проверка будет простой ((n xor mx) and mz) равно 0 при соответствии маске.
однако затраты на перевод чисел в такой вид надо учитывать. если набор многоразовый, то дело того стоит, наверно. |
Сообщ.
#4
,
|
|
|
Akina, спасибо почти то, что нужно. Но как я понял, такой метод будет работать не всегда. Например, если маска 22, то и первая и вторая маски будут равны 0.
Видимо, моя вина, что не очень четко описал задачу. Массивы могут быть сформированы не только из 4х-значных чисел, количество разрядов может быть любым, от 1 до 10, но одинаково для всех элементов массива. |
![]() |
Сообщ.
#5
,
|
|
voltron, поймите СМЫСЛ того, что делается - и все эти проблемы легко снимете.
|
Сообщ.
#6
,
|
|
|
Пытаюсь, но пока не очень получается. Если взять элемент массива 2212 и заменить 2 на 0, то получим 10. Пусть маска 2002, тогда маска1 - 110, а маска2 - 0. Если теперь применить AND к элементу и маске1 (считая их двоичными числами) получим: 0010 AND 0110 = 0010. Результат не совпадает с маской2. Если же выполнять AND не поразрядно, а побитово (т.е. исходить из того, что все числа в десятичной системе) вообще ничего не получается.
Хм... что-то я совсем запутался. Попробую еще завтра на свежую голову |
![]() |
Сообщ.
#7
,
|
|
Цитата voltron @ Пусть маска 2002, тогда маска1 - 110, а маска2 - 0. Здрасьте, приехали! Это с какого перепугу длины масок отличаются от длины исходного шаблона? |
Сообщ.
#8
,
|
|
|
Опустил начальные нули.
0110 и 0000 |
![]() |
Сообщ.
#9
,
|
|
Не надо опускать ничего - а то можно доопускаться...
Ну ладно, что тебя собсно смущает? никогда ничего не приходилось с нулём сравнивать? |
Сообщ.
#10
,
|
|
|
Все, разобрался.
Но к сожалению, предложенный метод не очень подходит. По тестам скорость практически не изменилась. |
Сообщ.
#11
,
|
|
|
Цитата voltron @ По тестам скорость практически не изменилась. А вы анализ производительности делали? Цитата voltron @ И есть "маски". Это тоже числа, количество цифр в этих числах не может превышать количество цифр в числах массива Как маски поступают в программу? Может на этапе "загрузки" их приводить к требуемому виду, например, донарашивать урезанными нулями, и т.д.? Может добавить оптимизацию и в алгоритм (разработать алгоритм) и сам алгоритм оптимизировать (его работу). У меня было очень много расчетов, программа работала 3-4 минуты. Добавил OpenMP -> 3-4 секунды ![]() Из-за особенности данных, добавил данные в кеш (сетка) за один проход, часть расчетов не нужных отсеялась при работе со своей ячейкой в кеше. Так что, если цель оптимизация времени работы, надо подходить глобально |