Задать вопрос
  • Как убрать линию, соединяющую (0,0) и начало графика ln(x) Tcanvas?

    @Mercury13
    Программист на «си с крестами» и не только
    Прямые причины этого отрезка.
    1. В первом MoveTo ты спутал реальные и экранные координаты. И в первом графике, видимо, тоже, только там линия уходит влево за край.
    2. У тебя нет никакой логики поведения на разрывах. В простейшем случае — в первую точку MoveTo, а не LineTo.

    И прочие ошибки.
    3. Не инициализирован y.
    4. Ты рисуешь не на том холсте. Видимо, ты хотел забуферизировать графики — но графики не отпечатываются на картинке, а рисуются на холсте формы. Как только ты минимизируешь-восстановишь прогу, графики исчезнут. Надо рисование либо в событие OnPaint (тогда график будет перестраиваться каждый раз при перерисовке), либо отпечатать на Picture.Bitmap (график останется отпечатанным на картинке). Во втором случае не забудь image2.Invalidate (отложенно перерисовать, когда это станет возможным);
    5. Шаг слишком мал. Это должен быть эквивалент одного или двух пикселей.

    ПРИМЕЧАНИЕ ПО ПОВОДУ 4. В WinVista+ с включенным Aero может быть всё в порядке (Aero буферизирует окна, чтобы работал Aero Flip и прочее). Выключи Aero, и будет обычный «хардкор» Windows: ничего не запоминает, а когда потребуется, перерисовывает.
    Ответ написан
    9 комментариев
  • Как правильно переопределить оператор присваивания с инициализацией методов классов-родителей?

    @Mercury13
    Программист на «си с крестами» и не только
    Попытайтесь выяснить, кто не терпит тупого поэлементного копирования, и изолировать их. Либо в один маленький объектик, либо в один маленький уровень наследования.

    Вариант 1. Сделать промежуточный уровень наследования, в который вносим некопируемые части.

    class LevelObject
    {
    private:
       Level& level;  // Сцылка на уровень, по определению неизменная
       int x, y;           // Присваивать.
    }


    Разбиваем на две части (внимание! — конструктор копирования для простоты не прописан, вероятно, потребуется и он):
    #include <iostream>
    
    class Level
    {
    public:
        int value;
        Level(int aValue) : value(aValue) {}
    };
    
    class LevelChild
    {
    protected:
        Level& level;  // не присваивать
    public:
        LevelChild(Level& aLevel) : level(aLevel) {}
        LevelChild operator=(LevelChild&) { return *this; }   // ничего не делающая операция «присвоить»
    };
    
    class LevelObject: public LevelChild
    {
    protected:
        int x, y;
    public:
        LevelObject(Level& aLevel, int aX, int aY) : LevelChild(aLevel), x(aX), y(aY) {}
        void print();
    };
    
    void LevelObject::print()
    {
        std::cout << "(" << x << ", " << y << ") at level " << level.value << std::endl;
    }
    
    int main()
    {
        Level l1(1);  LevelObject o1(l1, 1, 2);
        Level l2(2);  LevelObject o2(l2, 3, 4);
        o1.print();
        o2.print();
        o2 = o1;
        o2.print();
    }


    Вариант 2. Сделать маленькие объекты-функции со своими операциями присваивания.

    class LevelObject
    {
    private:
       Level* level;  // На сей раз уже копируется
       Array3 pos;    // Какой-то инкапсулированный объект-массив
       std::wstring name;   // тоже инкапсулированный объект
    }


    И всё, когда для std::wstring и Array3 корректно прописаны операции присваивания, для LevelObject всё будет работать корректно без единой строчки.

    P. S. А точно ваш объект страдает от поэлементного копирования и нужна своя операция?
    Ответ написан
    Комментировать
  • Почему срабатывает конструктор копирования?

    @Mercury13
    Программист на «си с крестами» и не только
    Операция присваивания, по договорённости, должна возвращать Pol&.
    Ответ написан
    Комментировать
  • Почему выходит это ошибка?

    @Mercury13
    Программист на «си с крестами» и не только
    Ошибка в SQL. Обратные кавычки, ЕМНИП, расширение MySQL; на других СУБД поля «закавычиваются» квадратными скобками. Попробуй [dbt_AdmissionProduct] или вообще убери эти кавычки.

    Ну и ещё вижу ошибку — запрос не закончен, и в этом может быть дело.

    Ах да. Писать SQL вот таким образом — ад редкостный. Я бы написал так.

    const
      CRLF = #13#10;
    
    xxx.SQL.Text := 'INSERT INTO dbt_AdmissionProduct ('  + CRLF+ 
                               'p_product, p_count…' + CRLF + …
    Ответ написан
  • Как называется игра из книги "Теория игр" Авинаш Диксит?

    @Mercury13
    Программист на «си с крестами» и не только
    Обратная игра Баше, или игра Баше на мизер.
    Игра Баше в обычном её виде — с точностью до наоборот; заставить противника взять последний флажок.
    Ответ написан
    Комментировать
  • Как в CBuilder организовать объявление свойства?

    @Mercury13
    Программист на «си с крестами» и не только
    Вот, допустим, подсказка по XE2.
    Data.Win.ADODB.TADOQuery
    
    Type  | Visibility | Source             | Unit           | Parent 
    class | public     | Data.Win.ADODB.pas | Data.Win.ADODB | Data.Win.ADODB 
                       | Data.Win.ADODB.hpp |


    Вот и подключаешь <Data.Win.ADODB.hpp>. В более ранних версиях Builder придётся подключать просто <ADODB.hpp>.
    Ответ написан
    1 комментарий
  • NIL в красно-черном дереве?

    @Mercury13
    Программист на «си с крестами» и не только
    Исходник, конечно, дай — посмотрим, что там можно сделать. Как вариант, можно сделать так.

    Node nullNode = { NULL, NULL, NULL, BLACK };
    class NodeHandle {
    private:
      Node* data;
      Node* getData() const { return data ?data : &nullNode; }
    public:
      NodeHandle() : data(&nullNode) {}
      NodeHandle(Node* x) : data(x) {}
      NodeHandle& operator=(Node* x) { data = x; return *this; }
      bool operator == (const Node* x) const { return (data == x); }
      bool operator != (const Node* x) const { return (data != x); }
      bool operator == (const NodeHandle& x) const { return (data == x.data); }
      bool operator != (const NodeHandle& x) const { return (data != x.data); }
      Node* operator ->() const { return getData(); }
      Node& operator *() const { return *getData(); }
      operator Node*() const { return getData(); }
    }


    Но, думаю, всё же где-то вкралась ошибка.
    Ответ написан
    Комментировать
  • Откуда берется мусор в переменной с плавающей запятой в Delphi?

    @Mercury13
    Программист на «си с крестами» и не только
    Из-за того, что число 340,788 невозможно точно отобразить в плавающей запятой. Никакой: ни single, ни double, ни extended. А FloatToStr на стандартных настройках предполагает точность не то double, ни то extended.
    Ответ написан
    Комментировать
  • Почему происходит ошибка при обращении к полю статического класса?

    @Mercury13
    Программист на «си с крестами» и не только
    Дело в том, что static-член в теле класса — это только заголовок, говорящий, что такое есть, но не создающий ни кода, ни данных. Эквивалент extern. Где-то в CPP (т.е. в одной и только в одной единице компиляции — не в .h!) нужны…

    std::vector LogVoting::RegisteredDeputy;

    И так далее.

    Если этим полям нужен нестандартный конструктор — пожалуйста…
    std::vector LogVoting::RegisteredDeputy(42);
    Ответ написан
  • Как угадать возраст за наименьшее кол-во попыток?

    @Mercury13
    Программист на «си с крестами» и не только
    Бинарный поиск, однако точка деления — не (a+b)/2, а медиана куска распределения от a до b (т.е. round(F−1([F(a) + F(b)]/2)); F(·) — функция распределения, тупо переделанная из кусочно-постоянного вида в кусочно-линейный, сплайновый или ещё какой-нибудь).
    Немного неоптимально, но крайне просто.

    З.Ы. Эта штука достаточно оптимальна для «гладких» распределений. В общем случае неоптимальна — например, если у нас три возраста с вероятностями 0,45, 0,1 и 0,45, стоит спросить первый, потом третий и уж при полном невезении второй (среднее 1,65 запроса), а не брать среднее, а затем — первое или второе (в среднем 1,9 запросов).

    Если нужен точный оптимум — решать задачу динамического программирования по критерию
    N[a,b] = min{c} (1 + (N[a,c−1]p[a,c−1] + N[c+1,b]p[c+1,b]) / p[a,b]).
    Граничные условия: при a = b N[a,b] = 1; при a>b N[a,b] = 0.
    p[a,b] — суммарная вероятность от a до b включительно; вычисляется как sum[b]−sum[a−1]; sum[i] = sum{x <= i} p(x).
    N[0,M] = ?

    Или, обозначив Q[a,b] как N[a,b]p[a,b],
    Q[a,b] = min{c} (p[c] + Q[a,c−1] + Q[c+1,b]).
    Так как p[0,M] = 1, то Q[0,M] = N[0,M].
    Граничные условия: при a = b Q[a,b] = p[a]; при a>b Q[a,b] = 0.
    Q[0,M] = ?

    Решается задача за O(M²) операций. Если нужно хранить всю информацию, чтобы в нужный момент прокрутить цепь запросов — O(M²) памяти; если только указать оптимум — можно обойтись O(M).
    Ответ написан
    3 комментария
  • Какую видеокарту купить для работы с web?

    @Mercury13
    Программист на «си с крестами» и не только
    Что угодно с выходом на DVI/HDMI. А сдачу приберегите — пригодится на хороший монитор.
    Ответ написан
    Комментировать
  • Что такое нарушения принципов ООП?

    @Mercury13
    Программист на «си с крестами» и не только
    Нарушение инкапсуляции. Наружу (т.е. public) торчат какие-то данные, которые можно изменить, и объект уходит в противоречивое состояние.

    Инверсия абстракции. Простые вещи, которые, вероятно, понадобятся потомкам, недоступны даже через protected.

    Нарушение принципа Лисков (ломаная абстракция). Для отца вы сделали некое предположение, которое неверно для сыновей. Классический пример — прямоугольник и квадрат — предполагается, что отец может произвольно масштабироваться, что неверно для сына.

    Класс вместо интерфейса. Если можно, родителя делайте классом без данных с двумя видами функций: public virtual = 0, и protected/public не-virtual (т.н. интерфейс с утилитами). Наследоваться от нескольких классов с данными очень некузяво (а во многих языках вообще невозможно).

    Всемогущий родитель. Слишком много функциональности придумали родительскому классу.

    В общем, покажите интерфейсы (protected/public, без точных реализаций) ваших классов, и погоняем, что там неверного.
    Ответ написан
    Комментировать
  • В чем разница int mas[], int mas[0], int mas[100]?

    @Mercury13
    Программист на «си с крестами» и не только
    int mas[] используется в трёх местах.

    1. Когда размер определяется инициализатором: int mas[] = { 1, 2, 3, 4, 5 };
    2. Чтобы задать параметр вида «массив неопределённой длины»: double vecLen(double a[], int size) {}
    Си не может жёстко задавать размер массива в параметре, чтобы больший или меньший не подходил; даже если напишешь напишешь double vecLen(double a[3]) {}, всё равно другой массив подойдёт. Си++ задаёт так: double vecLen(double (&a)[3]) {})
    3. Подсказал jcmvbkbc, реально мало на что нужно: extern int a[].

    int mas[0] создаёт массив нулевой длины, надобности в котором, понятное дело, никакой. Зато этот код используется, чтобы накладывать структуру данных, которая заканчивается массивом неизвестной длины, на какой-то буфер в памяти — как указатель: тут массив (C++ не проверяет выход за границу).

    struct Packet {
      unsigned short length;
      unsigned char data[0];
    }
    
    void processPacket(void* data, unsigned length)
    {
       // Простите уж, что перешёл на C++
       const Packet& packet = *reinterpret_cast<Packet*>(data);
       if (length != sizeof(Packet) + packet.length)
         throw std::logic_error("Packet size mismatch");
       for (unsigned i = 0; i < packet.length; ++i) {}
    }
    Ответ написан
    8 комментариев
  • Зачем нужен Total Commander?

    @Mercury13
    Программист на «си с крестами» и не только
    Буду говорить не про Total Commander, а про весь класс программ — двухпанельные файловые менеджеры.
    1. Удобная работа без мыши.
    2. Привычка со времён «Нортона».
    3. Просмотрщик и редактор.
    4. Простой вызов чего-то из командной строки.
    5. (сейчас уже неактуально, было на Windows XP) Как один из двух «презервативов» против заражения autorun-вирусом (второй — отключённый автозапуск).
    6. Лёгкий доступ к важным каталогам.
    Ответ написан
    Комментировать
  • Как понять заголовочные файлы?

    @Mercury13
    Программист на «си с крестами» и не только
    #include — как ни странно.

    Вы так и не поняли такой вещи, как «единица компиляции». Дело в том, что в Си c-файлы компилируются независимо друг от друга (в единую программу всё собирает линкер). А чтобы сказать «оно есть, только в другой единице компиляции», используют прототипы и extern’ы.

    А если вы хотите просто внести код в ту же единицу компиляции, просто пишите его в хедере, да и всё. Только в большинстве компиляторов это исключает предкомпилированные хедеры — а ТАКИЕ хедеры вам предкомпилировать, скорее всего, и не нужно.

    <брюзга mode on>
    Не создают кода (а значит, в традиционной системе с кучей единиц компиляции находится именно в хедерах)
    • extern и прототипы
    • inline
    • не до конца специфицированные шаблоны
    • static-поля в классе (но потом это static-поле придётся повторить в какой-нибудь одной единице компиляции)
    • может, ещё что-то, только я забыл…
    <брюзга mode off>
    Ответ написан
    1 комментарий
  • Как математически определить уникальное число для любых двух in64?

    @Mercury13
    Программист на «си с крестами» и не только
    Нельзя, простая комбинаторика.
    Одно число — 264 варианта, два числа — 2128 вариантов.
    Принцип Дирихле говорит, что в одной из клеток будут даже не два кролика, а как минимум ceil(2128/264) = 264 кролика — то есть для какого-то ответа будут как минимум 264 пары аргументов, которые его дают.
    Ответ написан
    3 комментария
  • Как рассчитать глубину полигона (метод z-буфера)?

    @Mercury13
    Программист на «си с крестами» и не только
    Это уже не z-буферизация, а алгоритм художника. Возьмите, например, z-координату центра.
    Ответ написан
    Комментировать
  • Зачем нужны однородные координаты?

    @Mercury13
    Программист на «си с крестами» и не только
    Все распространённые преобразования (сдвиги, повороты, проецирование) можно реализовать матрицей 4×4.
    Ответ написан
    Комментировать
  • Узко специализированно или широко?

    @Mercury13
    Программист на «си с крестами» и не только
    Это шаблон проектирования «стратегия», и по-хорошему реализуется в виде обработчиков или виртуальных функций.
    Ответ написан
    Комментировать
  • Алгоритмы: Задача о назначениях, как реализовать множественные назначения?

    @Mercury13
    Программист на «си с крестами» и не только
    Непонятно, как вы в такой ситуёвине считаете штраф. Ведь если штраф считается как раньше, а загрузка работника не ограничена, и задачи-то нет — каждую из работ можно дать тому работнику, который выполняет её лучше всех.

    Если же загрузка работника ограничена m работами — тогда решите задачу о максимальном потоке.

    Исток → работник: пропускная m
    работник → работа: пропускная 1
    работа → сток: пропускная 1
    Ответ написан
    Комментировать