Ответы пользователя по тегу C++
  • Почему операция 0.0 / 0.0 выдает ошибку?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    В какой книге написано про nan? По стандарту C++ деление на ноль - это неопределенное поведение:

    If the second operand is zero, the behavior is undefined,


    Правда, есть одно исключение:
    except that if floating-point division is taking place and the type supports IEEE floating-point arithmetic


    Вот только этот стандарт IEEE 754 не постулируется стандартом C++ (потому что зависит от аппаратной реализации чисел с плавающей запятой).

    Какие-то компиляторы с каким-то уровнем оптимизации могут действительно выдавать nan. Но не все и не всегда.
    Ответ написан
  • Найти количество чисел, делящихся на одно и тоже число?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Есть 2 решения.

    Во-первых, если бы вы умели бытсро проверять наибольший общий делитель чисел на отрезке, то можно было бы применить метод двух указателей. Найдите самый длинный отрезок, начинающийся в первом числе. Потом двигайте левую границу отрезка на 1 позицию и сдвигайте правую границу жадно пока можете. Вот вы нашли самый длинный отрезок из второй позиции. Опять двигайте левую границу на 1 и т.д. Выбирайте максимальный отрезок из всех найденных.

    Быстро получать наибольший общий делитель можно за логарифм с помощью структуры данных дерево отрезков. Общая сложность будет O(n log n).

    Второе решение такое: Раз числа на отрезке все делятся на что-то больше 1, то все они делятся на какое-то простое число. Значит задача состоит в том, чтобы найти самый длинный отрезок из чисел, делящихся на одно и тоже простое число. Значит вам надо разложить каждое число в массиве на простые множители и работать с ними отдельно. Далее, вам достаточно просто хранить для каждого простого множителя, какая длина у самого последнего отрезка из чисел с этим делителем и на какой позиции он закончился. Когда вы нашли, что текущее число делится на p, вам надо или начать новый отрезок или добавить текущую позицию к последнему отрезку.

    Общая сложность у этого решения будет O(n sqrt(a)), но его можно ускорить, если предподсчитать для каждого числа от 1 до A один из его простых делителей.
    Ответ написан
    3 комментария
  • Как удалить елемент из очереди с приоритетом?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Очередь с приоритетом реализуется на основе кучи или бинарного дерева поиска (set). В первом случае удаление делается так: Меняете местами первый и последний элемент в куче. Удаляете последний. Потом просеиваете первый элемент вниз, чтобы он встал на свое место. Во втором случае надо просто удалить из сета элемент begin().
    Ответ написан
  • Как решить ошибку нарушение прав доступа при чтении по адресу?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Запустите в дебаггере. Он остановится на строке с ошибкой. Проверьте значения всех переменных (zoo - размер вектора? i - чему равно?)
    Ответ написан
    Комментировать
  • Найти минимальную степень числа N?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Решение у задачи такое должно быть:

    Поскольку n^n делится на a, то n делится на все простые делители a. Поэтому надо разложить a на множители (пусть a= p1^k1*p2^k2 ...)

    Тогда n надо искать в виде k*p1*p2*...

    Это самое k надо перебрать от 1 до максимального ki и проверить, что n^n делится на a. Для этого надо подсчитать, сколько раз k делится на p_i (пусть - это q_i). Тогда надо проверить что, (q_i+1)*n >= k_i для всех простых делителей p_i.
    Ответ написан
  • Как плавно изменять целое число в течение некоторого времени от одного значения до другого?

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

    Или считайте по формуле ans = from + (to-from+0.0)*time/duration
    Ответ написан
    Комментировать
  • Найдите сумму и количество делителей натурального числа?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    В с++ разве есть оператор and? Попробуйте заменить sqrt на проверку i*i ==n. Видимо, проблемы с точностью. Плюс может быть переполнение. Сумма должна быть long long.
    Ответ написан
    1 комментарий
  • Почему выдает что переменные x,y,z - неинициализированы? Почему выдает что == неуместны и возможно я имел ввиду =?

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вам придется работать с winapi.

    Вам нужно создать прозрачное окно и рисовать в него то, что идет поверх рабочего стола (гуглите "winapi draw in transparent window").

    Чтобы не рисовать поверх каких-то окон - надо в каком-то битмапе нарисовать черным цветом силуэты всех этих окон (надо все окна в системе перебрать - тут вам помогут всякие всякие GetWindowRect, EnumWindows, IsWindowVisible.). И при проприсовке надо этот битмап брать как маску (гуглите "winapi clip region").

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    У вас цикл на 10 итераций (for (int count=0; count < 10; ++count)). С возможным ранним выходом (break).
    Ответ написан
    Комментировать
  • Для чего объявляется вложенная структура (или класс) перед тем, как она объявляется дружественной?

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

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

    Но откуда тут вообще может быть непонимание? В C++ никогда нельзя менять, на что ссылаются ссылки. const/не const может быть только то, на что оно ссылается.

    Edit: изначально я тут некорректно назвал это константной ссылкой, но по хорошему, оно называется ссылка на константу.
    Ответ написан
    4 комментария
  • Влияет ли на скорость вычисления сколько знаков в double?

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

    Но, если процессор не умеет в операции с числами с плавающей точкой, то будет программная эмуляция - и там уже может зависеть.
    Ответ написан
    Комментировать
  • Почему в C++ не удаётся чтение при помощи fstream объекта, записанного в файл при помощи того же fstream?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    string нельзя так писать. Потому что сам класс хранит в себе указатели на данные. И sizeof() у него всегда одинаковый, какой длины строчка бы не была. Вы записали какие-то адреса в файл, а когда прочитали - там лежит мусор. Поэтому на каких-то внутренних механизмах строки и происходит ошибка.
    Ответ написан
    5 комментариев
  • Почему не читается файл?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Приведенный вами код выглядит правильно. Выводит оно не то, что вы хотите из-за другой ошибки. Например, файл пуст но вы руками проверяете другой файл.

    Или файл не открывается, потому что его нет, или у вас компилируется через C++98.
    В документации написанно (примечание после параметров):
    If the mode has both trunc and app set, the opening operation fails. It also fails if either is set but out is not, or if both app and in are set.


    Вы же, судя по комментариям, открываете с app и in вместе.

    Вам точно надо читать и писать из этого файла да еще и увеличивать его размер?
    Ответ написан
  • Почему возникает ошибка "cannot be implicitly captured because no default capture mode has been specified" при передачи в функцию?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Почитайте про Лямбды. Сообщение об ошибке вам четко говорит, что оно не может понять, что делать с переменной key, потому что не указан метод захвата по умолчанию и key не указана в списке захвата.
    Ответ написан
    Комментировать
  • Какой тип данных использовать?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Сравнивайте дальше третии символы в строках, если первые совпадают.
    Или сравнивайте строки через strcmp.
    Ответ написан
  • Как удалить объект объявленный в функции?

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

    На самом деле, вам тут не нужна динамическая память. Сам класс Vector не жрет много памяти. Поэтому mulVec может возвращать просто Vector, а не указатель на него. Cам Matrix4x4 тоже не жрет память, поэтому не надо заводить и на него указатели. Вся память у него внутри в указателе data (кстати, вы же в деструкторе ~Matrix4x4 эту data удаляете же?).

    Если же там еще что-то и Vector большой, то возвращайте unique_ptr или shared_ptr на него. Тогда все само удалится, когда надо.

    И еще, в вашем текущем коде вы в main выделяете test, а потом перезаписываете. Тут у вас происходит утечка памяти. Его надо было delete-нуть перед перезаписью, это же указатель. Это хороший пример, почему вот так использовать сырые указатели где не надо - это плохо. Легко ошибиться: надо всегда помнить, кто ответственен за удалиение указателя.
    Ответ написан
    Комментировать
  • Как реализовать реакцию на комбинации клавиш?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    if (S && D) {
      functino3();
    } else if (S) {
      function1();
    } else if (D) {
      function2();
    }
    Ответ написан
    Комментировать
  • Как нормально сделать перемещение по диагонали (sfml)?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Считайте вектор скорости и потом делите на его длину. В зависимости от зажатых кнопок прибавляйте или вычитайте speed из vx или vy (которые изначально 0). Потом, после проверок, делите оба числа на sqrt(vx*vx+vy*vy) (если оно не 0) и сдвигайте спрайт на vx, vy.

    Можно соптимизировать - прибавляйте 1/-1 вместо speed. Тогда значение vx*vx+vy*vy может быть только 0,1 или 2. Заведите константный массив kScaleCoef[3] = {1, 1, sqrt(2)} и потом делайте
    Sprite.Move(speed/kScaleCoef[vx*vx+vy*vy]*vx, speed/kScaleCoef[vx*vx+vy*vy]*vy);
    Ответ написан
    Комментировать