Есть число N, необходимо найти все уникальные числа до 0 до N. Например из чисел 123,132,213,231,312,321 уникальным будет только любое одно, но если N = 321, то скорее всего уникальным будет 123 т.к. в переборе встретиться первым. Простой перебор не подходит, т.к. для long значений он становится очень долгим.
boolean isNext = false;
long num; //Входящее число
long digit;
long digit2;
while (num > 0) {
digit = num % 10;
digit2 = num / 10;
if (digit >= digit2 % 10) {
isNext = true;
} else {
isNext = false;
break;
}
num /= 10;
}
Частичное решение вашей задачи.
Позволяет найти все числа с уникальными комбинациями цифр для указанного количества знаков (n). Не хватает остановки при достижении указанного числа N - ищет все возможные n-значные числа.
Например: найти все уникальные 4-х значные числа - алгоритм найдет все числа от 1 до 9999. Найти все 3-х значные - найдёт числа от 1 до 999.
Определение уникального числа:
Уникальным считается то число, которое имеет комбинацию цифр отличную от всех чисел проверенных ранее.
Пример 1. Все уникальные двухзначные числа (10 - 99):
Число 21
не является уникальным, так как имеет ту же комбинации цифр, что и число 12
, проверенное ранее.
Число 14
является уникальным, так как это первый из двух возможных вариантов комбинации цифр 1
и 4
. Вторым вариантом является число 41
, но оно ещё не встречалось (соответственно, когда мы до него дойдём оно уже не будет уникальным).
Пример 2. Уникальные трёхзначные числа от 100 до 199:
Решение:
Предлагаю не проверять все числа на уникальность перебором, а изначально конструировать только уникальные комбинации цифр. Для простоты возьмём числа без нулей (нули требуют дополнительной обработки):
1) Первая цифра любого числа может иметь только девять вариантов: 1
, 2
, 3
... 9
. Мы будем собирать комбинации для каждой стартовой цифры отдельно - в виде строки. Конечно, нет нужды делать это одновременно, подойдёт цикл прокручивающий числа от 1
до 9
и выполняющий все требуемые действия для каждой строки по очереди.
Итак, возьмём девять начал состоящих из 1 цифры:
# В квадратных скобках зафиксированная (неизменяемая) часть
# состоящая из одной цифры.
[1] -> в эту сторону будет расти число
[2] -> в эту сторону будет расти число
[3] -> в эту сторону будет расти число
[4]
[5]
[6]
[7]
[8]
[9]
Можно представлять вместо чисел кубики - вначале у нас 9 рядов по одному кубику, на следующем шаге мы добавляем справа ещё по одному кубику, потом ещё и т. д. до требуемого количества кубиков (знаков) в ряде.
2) Если текущая цифра равна 1
, то следующая цифра тоже должна быть 1
или больше и так для каждой последующей цифры. Меньше она быть не может, так как в этом случае мы получим уже пройденную комбинацию. То есть 23
- новая уникальная комбинация, а 21
уже была найдена ранее в числе 12
.
[1] <- 1 #присоединяем 1 к уже имеющейся строке.
[2] <- 2 #присоединяем 2 к уже имеющейся строке.
[3] <- 3
[4] <- 4
[5]5
[6]6
[7]7
[8]8
[9]9
Обратите внимание, что первая цифра у нас зафиксирована, а вторую мы будем менять, создавая таким образом все возможны двухзначные комбинации.
3) Присоединяем к фиксированная части следующую цифру (предыдущая цифра + 1), до тех пор, пока она не будет равна 9
. Видно, что для числа 99
уже не будет новых комбинаций. А для числа 11
их ещё 8 - 12
, 13
, 14
, 15
, 16
, 17
, 18
, 19
. Дойдя в каждом ряде до цифры 9
мы получим все возможные комбинации для конкретной стартовой цифры. А соединив все результаты воедино - все возможные комбинации для данного количества знаков, - что и требовалось.
[1] <- 2 #увеличиваем текущую цифру на 1 и добаляем к уже имеющейся строке.
[2] <- 3 #увеличиваем текущую цифру на 1 и добаляем к уже имеющейся строке.
[3] <- 4 #увеличиваем текущую цифру на 1 и добаляем к уже имеющейся строке.
[4] <- 5 #увеличиваем текущую цифру на 1 и добаляем к уже имеющейся строке.
[5]6
[6]7
[7]8
[8]9
[9]9 #данная комбинация, начинающаяся с 9 достигла своего предела.
4) Если нужно собрать трёхзначные комбинации, то берём всё возможные двухзначные комбинации полученные на предыдущем этапе, фиксируем их в виде строки и повторяем все шаги, начиная с пункт 1. Делать это удобно с помощью рекурсии.
# В квадратных скобках зафиксированная часть
# состоящая из двух цифр.
[11] <- 1 #присоединяем 1 к уже имеющейся строке.
[22] <- 2 #присоединяем 2 к уже имеющейся строке.
[33]3
[44]4
[55]5
[66]6
[77]7
[88]8
[99]9
Реализация на Python:
# head - здесь фиксируется стартовая часть каждой комбинации
###
# start - точка отсчёта для новых комбинаций
###
# digit_num - количество знаков для которого требуется найти комбинации.
# 4 == 3 знака, 3 == 2 знака и т.д.
###
# depth - отслеживаем глубину рекурсии, чтобы остановить её в нужный момент.
# Также используется для понимания порядкового номера знака над которым работаем
# в данный момент.
def print_uniq_nums(head, start, digit_num, depth):
if depth >= digit_num:
return
if depth > 0:
print(head)
# запускаем счётчик от 0 до 9
# если нули можно было бы не учитывать, как в моём упрощённом
# объяснении, то можно было начинать отсчёт со "start",
# а так как они нужны, то начинаем от нуля, потом пропускаем ненужное
# и продолжаем со "start"
for i in range(0, 10):
# Чтобы не создавало комбинации типа 001, 002 и т.д.
if i == 0 and depth == 0:
continue
# Для защиты от неправильных комбинаций типа:
# 110 (уже была: 101), 220 (уже была: 202)
if i == 0 and depth > 1 and head[depth - 1] != "0":
continue
if i == 0 or i >= start:
# прибавляем к фиксированной части, находящейся в head,
# изменямое окончание и отдаём получившуюся комбинацию
# на следующий уровень рекурсии
num_str = "%s%s" % (head, i)
# Если i == 0, то пробрасываем текущую точку отсчёта
# на следующий уровень рекурсии, чтобы после
# нулей счётчик не сбивался.
# Иначе будет неправильная комбинация 2001, вместо 2002
if i > 0:
start = i
print_uniq_nums(num_str, start, digit_num, depth + 1)
print_uniq_nums("", 1, 4, 0)
Output (сокращённый):
1
10
100
101
102
103
104
105
106
107
108
109
11
111
112
..............
119
12
122
..............
128
129
13
133
..............
2
20
200
202
..............
207
208
209
22
222
223
..............
Другой вариант решения:
Перебираем все числа от 0 до N, каждое разбиваем на отдельные цифры и укладываем в массив. Массив сортируем, формируем из него строку, делаем её хэш и добавляем его в хэш-таблицу. В качестве ключа используем получившийся хэш, в качестве значения - 1
. При нахождении следующего числа с такой же комбинацией цифр, увидим, что в хэш-таблице уже есть такой элемент, значит, это число пропускаем.
Представляю свой алгоритм:
int [] array={2,3,4,5,4,3,2,1};
list<int> list;
for(int i=0;i<array.length;i++)
{
int count=0;
for(int j=0;j<array.length;j++)
{
if(array[i]==array[j]) count++;
}
if(count==0) list.Add(arra[i]); // добавляем в список или в любой контейнер
}
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Есть библиотека - node-vk-bot-api Как с помощью нее обратиться например за методом usersget (возвращающее информацию о профиле)
На сервере или на клиенте грамотно делать генерацию excel файлов? Таблица для экспорта сделана на флексахНа клиентской стороне на js нормально...
Задача такая создать динамический диалог на ajax js и phpЗадача вроде выполнена, но при использовании данной функции создается куча запросов...