Задать вопрос
  • Как грамотно переписать фабрику?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    У стратегий можно сделать статические методы. Например, метод, возвращающий имя, и метод, создающий экземпляр класса.

    В вектор/мап кладите пары stragetyX.GetName(), &stategyX.CreateStrategy
    А дальше находите там нужную строку и вызывайте функцию-фабрику.

    Но вообще, такие штуки c хранением функций-фабрик в контейнере редко делают. Можно в одном месте и иметь вереницу из if-else. Будет не одна длинная строчка на каждый новый класс, а две но покороче.
    Ответ написан
  • Почему не получается передать указатель на вектор в класс?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    void Field(vector <Circle> &circles, vector <Rectangle> &rects) {


    Это передача по ссылке а не через указатель. Сюда надо передавать сам circleArray.

    Но сразу скажу, препод такой подход не примет. Вся идея полиморфизма, наследования и виртальных методов в том, чтобы хранить везде указатели на Figure. А то, что какие-то из них на самом деле Circle, а какие-то Rectangle, это уже детали реализации. Виртуальные методы должны переопределятся в потомках и именно там должна быть логика, специфичная для разных фигур.

    Например, у фигур может быть метод "выведи себя". Тогда в коде работы с фигурами вы просто вызываете этот метод у васех фигур даже не зная, круг это или прямоугольник. А вот перегруженный вертуальный метод уже будет выводить конкретную фигуру.

    И ваш массив geometry в родительском классе смысла не имеет. Потому что он же не знает, что с этой геометрией делать. Там могут быть углы прямоугольника, а может быть центр круга. Вам надо в каждом классе потомке тупо хранить данные о нем (центр круга и радиус, например)
    Ответ написан
    Комментировать
  • Почему выводится статичное некорректное значение?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    double circleMainArray[circArraySize] = { centerCoordX, centerCoordY, radius };
    geometry = circleMainArray;


    Тут вы заводите локальную переменную circleMainArray, а потом копируете ее адрес в член geometry. По выходу из конструктора локальная переменная удаляется. На ее месте потом поялвяется что-то другое (она на стеке, так что там могут быть адреса возврата, значения регистров или других локальных переменных).

    Правильно было бы выделять память в куче под geometry и или заполнять его руками, или копировать туда данные из локальной перменной. А еще лучше - использовать std::vector.
    geometry = new double[circArraySize];
    geometry[0] = ...;
    geometry[1] = ...;

    Или лучше
    std::vector<double> geometry;
    ...
    Circle(double centerCoordX, double centerCoordY, double radius) :
       geometry{centerCoordX, centerCoordY, radius} {}
    Ответ написан
    6 комментариев
  • Нужно найти 10 елемент,я так понимаю это прогрессия,совсем не могу разобраться?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Можно последовательно найти t1, t2, t3 .. t9 и через них циклом подсчитать t10.

    Нужно их хранить в массиве и тупо записать формулу в коде. Знак суммы становится циклом, в котором надо вычисленное через i выражение прибавлять к счетчику.

    Такая реализация подсчета t(n) будет за O(n^2).

    Если подумать, то можно быстрее. Во-первых, при умножении t0 на С, tk умножится на C^(k+1). Можно доказать по индукции. Теперь осталось подсчитать числа для t0=1 и домножить на t0^( n+1).

    Если же выписать числа на бумажке, то можно заметить, что это числа Каталана, которые считаются по формуле
    (2n)!/n!/(n+1)!

    Итого, ответ - (2n)!/n!/(n+1)! * t0^(n+1)
    При n=10 дает 16796.

    Это уже можно подсчитать за O(n).
    Ответ написан
    Комментировать
  • Как реализованы программы записи экрана и стриминга?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Используются системные api. Все полатформо зависимое, к сожалению. На винде можно делать через кучу разных апи: gdi+, dxgi, wgc. Гуглите "слово из списка capture screen".

    Далее, похоже нужно будет реализовывать виртуальную камеру. Тут гуглите апи dshow. Уже с этим можно ваш проект прикручивать к существующим стриминг платформам.

    Если же вам хочется сделать все свое (включая бакенд) то можно воспользоваться библиотекой webrtc.
    Ответ написан
    Комментировать
  • Почему считывается с файла только 1 слово, а не весь текст?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Если просто через >> читать std::string из std::cin, то он будет читать одно слово.
    Чтобы прочитать всю стороку используйте cin.getline.
    Ответ написан
  • Почему не работает функция?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Проблема в том, что код функций из шаблонов генерируется по мере надобности.
    Вот встретил компилятор где-то Test<int> - и начинает создавать функцию для int.
    Но в единице трансляции с Functions.cpp он этого не встретил и ничего не генерирует. А когда он компилирует Source.cpp он может только сгенерировать декларацию, но не определение функции. Ведь он видит хедер, но не что написано в Functions.cpp.

    Поэтому, если весь шаблон определять в .h файле то компилятор сможет сгенерировать что ему надо всегда.

    Второй варинат решения проблемы - в Functions.cpp указать компилятору, что шаблон будет использоватся с такиим-то типами:
    using Test<int>;

    Этот подход лучше тем, что один и тот же код не компилируется кучу раз, как если бы он был в хедере.
    С другой стороны, вам надо заранее в месте определения шаблона расписать все используемые с ним типы вручную.

    Обычно минусы тут перевешивают плюсы и шаблоны всегда целиком пишут в хедерах. Но это не единственный враиант. Неправда, что шаблоны должны целиком находится в хедерах.
    Ответ написан
    Комментировать
  • Какая сложность у такого цикла for?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Так.
    Ответ написан
    Комментировать
  • Можно ли использовать библиотеки для одного языка в другом?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Можно. Гуглите, что такое ABI.
    Ответ написан
    Комментировать
  • Определить имеются ли в массиве одинаковые элементы. Вывести значения наиболее часто встречающегося элемента?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Или отсортируйте массив, или используйте хеш-мап (unordered_map) для подстчета того, сколько раз каждый элемент встретился. Если где-то этот счетчик стал больше 1, то есть повторяющиеся элементы.

    Для поиска самого частого найдите максимум из значений в хешмапе, потом пройдитесь по массиву еще раз и выведите первый элемент, счетчик для которого равен этому максимуму.
    Ответ написан
    Комментировать
  • Как в указатель на базовый класс вложить ссылку на класс наследник?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Правильно - вот так:
    object = new Kvadrat();

    Теоретически, можно было бы делать как вы пытаетесь:
    object = &kv;

    Но конкретно в вашем коде - это будет UB, потому что kv - это локальная переменная и у нее очень огранниченная область видимости - внутри if. И вот за пределеами этого if, где вы и попытаетесь, очевидно, использовать указатель object, эта локальная переменная будет уже уничтожена. У вас будет т.н. висячий указатель - указывающий туда, где данные были, а сейчас там может быть все, что угодно.

    Поэтому, если вы присваиваете указателю адрес какого-то объекта (&) вам надо убедиться, что время его жизни не меньше, чем у указателя, пока вы будете его использовать. Можно, например, сделать переменную глобальной, но это очень плохой код. Лучше завести все 4 разных класса в начале функции, потом прочитать нужный и взять указатель на него. Этот подход иногда даже используется на практике.

    Но лучше, все-таки, не плодить лишних сущностей и создавать объект сразу в куче с помощью new. Тогда он сам нигде не уничтожится.
    Ответ написан
    1 комментарий
  • Как написать такое при помощи AVX?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Каким-нибудь _mm256_cmpgt_epi16 два раза можно получить для каждого числа 0xFFFF, если оно входит в интервал и 0 иначе. Потом каким-нибудь _mm256_and_si256 можно занулить те числа, которые не попали. Возможно, придется делать and 2 раза.
    Ответ написан
    5 комментариев
  • Как исправить ошибку "unsorted double linked list corrupted"?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Это проблема работы с памятью. Вы там освобождаете память из-под str перед тем, как попросить gmp заполнить эту строку данными:
    free(str);
    mpz_get_str (str,10 , mul);


    gmp пишет данные туда, где была строка. Но в это место нельзя писать после free. Иногда так получается. что менеджер памяти хранит там какие-то свои данные, которые вы портите и потом получаете об этом ошибку. Память может быть возвращена системе, и тогда программа может упасть вообще при попытке записать туда что-то. Или ничего заметного может не произойти вообще.

    Как это часто бывает с ошибками работы с памятью, любая мелочь, вроде фазы луны или лишнего отладочного вывода где-то, может изменить то, как эта испорченная память используется и ошибка может не вызвать падения.
    Ответ написан
    Комментировать
  • Как создать новый поток внутри метода класса?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    В документации есть пример:
    std::thread t5(&foo::bar, &f); // t5 runs foo::bar() on object f


    У вас надо cделать: std::thread t5(&A::Zoom, this);
    Ответ написан
    Комментировать
  • Найти пары слов связанных с 4ми и более одинаковыми url?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Во-первых, я бы с помощью бора все урлы перенумеровал. Теперь в задаче есть 400,000 ключевых слов, связанных с 10-ю числами.

    Далее, В каждой группе по 10 чисел есть 10!/4!/6! = 840 четверок. Всего различных четверок наберется 840*400000 ~= 330,000,000. Это не так много. Для хранения всей этой радости, правда, понадобится ~8 гигабайт памяти, но это подъемно. Потом вам надо среди этих 300 миллионов найти совпадающие. Можно отсортировать (лучше радиксом) или воспользоваться хеш таблицей (правда тут еще больше памяти потребуется).

    Это будет на много порядков быстрее сравнивания каждого слова с каждым или перебор 4-х урлов.
    Все за несколько секунд должно отработать.
    Ответ написан
    1 комментарий
  • Что означают эти формулы?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    "E" (это вообще-то сигма из греческого алфавита) - знак суммы. выражение справа надо просуммировать, подставив вместо k все числа от 3 до n. П - это знак произведения. Выражение справа надо перемножить для всех указанных значений i.

    Поскольку тут в выражении П есть переменная k, связанная в сигме, то можно однозначно сказать, что перемножение идет внутри суммы.

    Ваше решение в вопросе почти правильное. Проблема только в том, что вам надо подсчитать что-то вроде c1*a1*a2*a3 + c2*b1*b2*b3. А вы используете одну и ту же переменную для подсчета каждого слагаемого и общей суммы. У вас получается что-то вроде (c1*a1*a2*a3+c2)*b1*b2*b3
    Ответ написан
    2 комментария
  • Почему выводится другое значение вместо ожидаемого?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Очевидно, потому что оператор value++ (вместе с square) выполнился раньше оператора сдвига <<, которые используются для вывода в поток cout.

    Вообще, у меня оно выводит 13.

    Стандарт гарантирутет, что постинкримент сработает после того, как значение пременной возьмется для вычисления выражения, а вот когда именно во время вычисления этого выражения - это уже от компилятора зависит.

    Вообще, использование переменной value в том же выражении, что и она же с постинкриментом - Undefined behavior.

    Мне лень искать конкретные пункты стандарта, из которых будет следовать, что это UB, но просто запомните: нельзя использовать перменную и переменную++ в одном и том же выражении.
    Ответ написан
    3 комментария
  • Если мы возьмём кубическую кривую Безье и вытянем усы в одну точку, будет ли это квадратичная кривая?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Нет. Потому что кривая называется "кубической" не потому, что там 4 разные точки, а потому что она задается уравнением третьей степени (кубы): a(1-t)^3+bt(1-t)^2+ct^2(1-t)+dt^3. Если вы приравняете b и c, то уравнение так и останется кубическим и в квадртаичное не превратится.
    Ответ написан
  • Сортировка расческой. Что такое число 1.247?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Судя по всему, это число вылезло в результате эксперементов каких-то исследователей. Они просто попробовали кучу разных факторов и нашли что при 1.247 вроде как быстрее в среднем. Формулу по это число потом какой-то шутник придумал. Кроме как в русской википедии (без ссылки на источник) я нигде эту формулу найти не могу.

    Влияет оно так: если число слишком большое, то мелкие элементы в конце массива не успевают перехать в начало на итерациях с достаточно большим шагом; если же число слишком мелкое, то делается много лишних итераций.
    Ответ написан
    Комментировать
  • Как решить эту задачу на python?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Вам надо в цикле считать члены ряда вот по той вот формуле из условия, подставляя вместо n числа 1,2 и т.д.
    Если текущий член стал меньше заданной границы, то надо выйти из цикла. Иначе прибавить к переменной.

    Похоже, предполагается, что следующий член будет вычисляться через предыдущий.
    Ответ написан
    Комментировать