Search
Write a publication
Pull to refresh
23
0

Пользователь

Send message
Это скорее вопрос формализации задачи. Если всё честно считать в битах, то да, Θ(N log N) и там, и там. Более того, очевидно, что, если в основном массиве непонятно что записано и мы только меняем местами его элементы, это нижняя граница по дополнительной памяти (потому что всю информацию мы берем только из дополнительной памяти, значит перед началом генерации каждой перестановки в этой памяти должно быть записано своё уникальное значение, последовательностей N!, значит нам требует не меньше log2 N! бит).

Но по факту, N ограничено сверху очень маленькой константой порядка 20 (иначе алгоритм до нашей смерти не закончит работу), поэтому если уж так хочется сравнивать по памяти алгоритмы, то разумнее уж прямо в байтах написать, сколько кому требуется, а не асимптотики сравнивать.
У меня появилась мысль об одной из возможных причин такого разделения. Просто с точки зрения получения количества плюсиков за пост (а если я не ошибаюсь, то каждый плюсик свыше какого-то числа ещё и приносит денежку для тех, кто участвует в ППА) гораздо выгоднее написать на какую-нибудь популярную тему (тему, которая понятна подавляющему большинству), чем написать или перевести техническую статью. Поэтому большинство таких тем утащили на другие ресурсы. Правда способ борьбы, конечно, радикальный.
перейти на пост можно внутри отдельной статьи.
Это неудобно для той роли, в качестве которой вы его рекламируете (объединенная лента для трех сайтов сразу).
Лучше бы при нажатии на пост делался редирект на соответствующую страницу на хабре или гиктаймс, чтобы можно было пост комментировать и оценки ставить.
В том числе потому, что вероятность ошибки при написании 3 новых классов
Нам же не с нуля надо эти классы разрабатывать с какой-то уникальной функциональностью в каждом, они весьма однотипны. Всё можно устроить так, что добавление нового класса будет требовать от нас написание одной строчки кода (например, завернуть объявление класса в макрос) или одного клика в IDE для вставки соответствующего сниппета.
Какие-то у вас странные аналогии, мы же о текстовом файле с кодом говорим, у него нету никаких слоев данных и представлений: какие символы вы нажмете на клавиатуре, те и будут записаны в файл, какие символы записаны в файле, те и будут выведены на экран.
Пробел и таб — это пустое место и воспринимается, как пустое, ничего не значащее место.
Возьмите любой сложный код (скажем, 4 уровня вложенности) на языке со скобочками, удалите из него отступы и попробуйте прочитать. Вам будет очень некомфортно. А если удалить из кода скобочки, оставив отступы, то все останется читаемо. А вы говорите, ничего не значащее место.

Скобочки, на мой взгляд, полезны тем, что не навязывают вам жесткий code style на уровне языка, однако при чтении кода основное внимание мы обращаем именно на отступы.
Надо отметить, что в стандарт С++ (не обычного C) эта фишка ещё не вошла, возможно дело в этом.
А что если сделать рядом с каждой статьей какую-нибудь кнопку "Скрыть", при нажатии на которую для тебя статья исчезает из ленты и списка популярных за сутки? Тогда получится, что один раз глазами отфильтровал такую статью, как не интересную тебе, и больше на неё не натыкаешься при просмотре этих двух разделов.
Да, в С99. Называется designated initializers.
Мне кажется, ваш пример некорректен, отступы — это тоже вполне себе явное выделение блоков. Более того, уверен, что наткнувшись посреди С++ кода на фрагмент типа:
...
if (x == 0)
  y = 10;
  z = 15;
...
90% прочитают его так, как будто и первое, и второе присваивание происходит лишь при выполнении условия, то есть посмотрят не на скобочки (которых нет, и поэтому лишь первое присваивание относится к if), а на отступы.
Не уверен, что я правильно вас понял, но в данном примере обвес строится вокруг функции createDate(), а не каких-то структур данных, а типы width и height, если вы о них, — это обычные сишные структуры с одним интом внутри, которые, в свою очередь, на машинном уровне то же самое, что и простой int.
«Не работают» значит «не работают сразу из коробки». Но ручками все реализуемо:
apples operator+(apples a, apples b)
{
    return apples(unsigned(a) + unsigned(b));
}
Не совсем функция, но для примера сойдет. Скажем, когда мы пишем
std::unordered_set<std::string>
после подстановки параметров по умолчанию получается:
std::unordered_set<std::string, std::hash<std::string>, std::equal_to<std::string>,
    std::allocator<std::string>>

Если мы хотим создать эту же структуру только с нашим аллокатором (поменять последний параметр), то нам прийдется явно выписывать все эти параметры:
std::unordered_set<std::string, std::hash<std::string>, std::equal_to<std::string>,
    my_allocator<std::string>>
вместо какой-нибудь такой записи:
std::unordered_set<std::string, Allocator : my_allocator<std::string>>
Это не решает проблему до конца. Пусть у нас есть какой-нибудь тип, который может быть преобразован, скажем, в Day:
struct T {
    operator Day() const;
};

Тогда мы можем делать так:
createDate(T{}, Year(4), Month(55));
и это реально здорово и является преимуществом вашего метода перед предложенным выше.

Но мы cможем сделать и вот так:
createDate(T{}, Day(4), Month(55));
поэтому до конца проблема не решена.

P.S. И это уже не «без С++11» ;-)
Это, кстати, поинтересней вышеприведенного решения, т.к. здесь не требуется, чтобы параметры были точно типов Day, Year и Month, а достаточно, чтобы можно было однозначно конвертировать каждый аргумент в один из этих типов. Надо бы только защититься от подобных вызовов:
createDate(Day(3), Day(3), Day(3));
Причем final ещё и оптимизировать помогает, скажем, в таком коде:
struct A { virtual void f(); }
struct B : public A { virtual void f() override final; }
struct C final : public A { virtual void f() override; }

void do_with_B(B& b) { b.f(); }
void do_with_C(C& c) { c.f(); }
в обоих функциях do_with... вызов f() будет вызвана напрямую соответствующая функция, тогда как без final там был бы вызов через таблицу виртуальных функций.
С C++11 можно сделать так:
enum class apples : unsigned int {};
apples будет отдельным типом (в него нельзя будет присвоить int или груши, скажем), при этом по умолчанию для него будут определены все операторы сравнения и функция хеширования (поэтому, например, его можно положить в любой STL контейнер, ничего дополнительно не дописывая). Из минусов: не работают арифметические операции, не работает вывод через потоки (и то, и то можно ручками дописать) плюс проблемы с синтаксисом конструирования, т.к. единственный способ сконструировать такой тип из встроенного числового типа — это сделать явный каст:
apples a(0); // Compilation error
apples b( apples(0) ); // OK
apples c = apples{0}; // Compilation error
apples d = apples(0); // OK
В плюсах же есть возможность указывать аргументу значение по умолчанию или речь о чем-то другом идет?
А в чем конкретные проблемы, кроме того, что надо много кода написать, если нам нужны все-все операторы?

Information

Rating
Does not participate
Location
Ижевск, Удмуртия, Россия
Registered
Activity