(Этот вопрос связан с моим предыдущий вопрос, а точнее на мой ответ на него.)
Я хочу сохранить все кубы натуральных чисел в структуре и искать конкретные целые числа, чтобы увидеть, являются ли они идеальными кубами.
Например,
cubes = map (\x -> x*x*x) [1..]
is_cube n = n == (head $ dropWhile (<n) cubes)
Это намного быстрее, чем вычисление кубического корня, но имеет сложность O(n^(1/3))
(я прав?).
Думаю, было бы лучше использовать более сложную структуру данных.
Например, в C я мог бы сохранить длину уже сгенерированного массива (не список - для более быстрой индексации) и выполнить двоичный поиск. Было бы O(log n)
с меньшим коэффициентом, чем в еще один ответ на этот вопрос. Проблема в том, что я не могу выразить это на Haskell (и не думаю, что должен).
Или я могу использовать хеш-функцию (например, mod
). Но я думаю, что несколько списков (или список списков) потребляли бы гораздо больше памяти, и это не снизило бы сложность поиска (все еще O(n^(1/3))
), только коэффициент.
Я думал о каком-то дереве, но без всяких умных идей (к сожалению, я никогда не изучал CS). Я думаю, что тот факт, что все целые числа идут по возрастанию, сделает мое дерево плохо сбалансированным для поиска.
И я почти уверен, что этот факт о возрастающих целых числах может быть большим преимуществом для поиска, но я не знаю, как его правильно использовать (см. Мое первое решение, которое я не могу выразить на Haskell).