Ответы пользователя по тегу C++
  • Как можно ускорить алгоритм?

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

    Проблема в том, что если число K простое - то вы будете проходиться до него. Есть трюк - достаточно проверять только числа до корня из K. Ведь если у числа есть какой-то минимальный собственный (меньше него самого) делитель, то он точно меньше корня (потому что делителей как минимум два, и если минимальный из них больше корня, то их произведение - больше самого числа).

    Если вы не нашли делителя до корня, то число простое и в качестве делитеял можно брать все K и тогда ответ будет K-1.
    Ответ написан
    2 комментария
  • Почему возникает ошибка доступа к элементу в классе?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Потому что в fillMatrix вы заполняете не член класса fullMatrixPointer, а параметр функции с точно таким же названием. Если вы включите ворнинги у компилятора, то он вам об этом скажет.

    После выхода из функции этот указатель никуда дальше не попадает. И в showMatrix передается незаполненый указатель.
    Ответ написан
    3 комментария
  • Как решить проблему с исключением в моем коде?

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

    Вы уже открыли вашу программу в дебаггере. В правом нижнем углу вы видите стек. Первые 3 функции - это в недрах библиотеки. Вам тут ничего не понятно, поднимайтесь вверх. Ткните в четвертую строчку - там где Main().

    Увидите, что ошибка происходит на строчке:
    cout << morze.find( text[i] )->second <<" ";

    Проблема возникает при попытке обратиться к second у возвращенного значения. Но почему? Читайте ошибку: "cannot dereference end map/set iterator".

    Т.е. find возвращает end() итератор. Действительно, посмотрите в документацию - map вернет end() если искомого ключа в нем нет.

    Иправить ошибку просто - исправьте ваш код. Сначала присвойте переменной возвращенный из find итератор, и потом проверяйте, а не end() ли он. И только в противном случае выводите.

    Я подозреваю, что символом оказался пробел. Пробела в вашем мапе morze нет, вот все и падает.
    Ответ написан
    1 комментарий
  • Как сравнить unsigned long long и char* в C++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Потому что вы передаете во второй to_string первый символ (его код). Если вы передадите в качестве числа 61, а в качестве строки "A..." то будет true.

    Если вам надо сравнить число и строку, как набор цифр, то вы или только число переводите в to_string или только строку переводите в to_number.
    Ответ написан
    Комментировать
  • Как обращаться к элементам массива через указатель?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Раз вы передаете ссылку, то tmp_word и s являются тупо массивами, т.е. указателями на char. Поэтому вам не надо одновременно их разыменовывать и обращатся по индексу. Или пишите *(tmp_word+tmp) или tmp_word[tmp]

    А вообще, можно их и не передавать как ссылки а передвать сами массивы, как указатель на char.
    void DeleteWords(char *s, char *tmp_word, int size_word)


    Так будет понятнее и проще. А еще лучше, передавайте std::string или std::vector. По ссылке, чтобы избежать копирования. По const ссылке, если не хотите, чтобы их внутри функции меняли.
    Ответ написан
    1 комментарий
  • Как специализировать метод родительского класса?

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

    Определите shader::construct и пометьте override.
    Ответ написан
  • Как использовать переменную из одной функции в другой, не запуская при этом работу второй функции?

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

    Вы там выделяете новую память и заполняете ее, но снаружи это нигде не видно.

    Или можно наоборот - выделять массив в info, но тогда надо не выделять его в detal и передавать указатель на указатель, что бы info могла изменять stu. Или лучше, пусть info массив возвращает.
    Ответ написан
    Комментировать
  • Как удалить элементы векторов по одинаковому индексу С++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    int index = std::distance(NUMBER.begin(), it);
    TYPE.erase(TYPE.begin() + index);
    PRICE.erase(PRICE.begin() + index);
    ...


    Вы же удаляете элемент по индексу равному значению удаляемого элемента.

    Я бы, правда, вместо кучи массивов завел один массив со структурами. Это сильно упростит код, хоть и может в некоторых крайних случаях работать чуть медленее.
    Ответ написан
    1 комментарий
  • Почему вызывается приватный конструктор копирования?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Он там не вызывается. Этот приватный конструктор используется в функции
    void lib::LinkedList<T>::push(const T&) [with T = Item<int>]
    , которая в шаблоне (там где вы создаете Node* tmp). При первом обращении к этой функции компилятор пытается ее инстанциировать и натыкается на эту проблему, о чем и сообщает вам. Пока эта функция вообще никак нигде не используется - программа компилируется.

    В приведенных вами примерах вы эту функцию так или иначе трогаете разными способами.

    lib::LinkedList<Item<int>> list = lib::LinkedList<Item<int>>()
    вызвает проблему пока у вас есть virtual метод в интерфейсе, потому что это тут вызывается конструктор копирования (сначала конструктор по умолчанию для временного lib::LinkedList<Item<int>>(), а потом это все копируется в конструируемый list).

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

    Если вы напишите lib::LinkedList<Item<int>> list() - то все скомпилируется, потому что конструктор по умолчанию, видимо, не требует знания о методе push. Также удаление virtual или наследования вылечит эту проблему.

    Далее, точно по этой же причине не скомпилируется list.push(a) - это прямой вызов этой запретной функции. Если же вы напишите list.push(Item<int>()), то оно скомпилируется потому что тут вызывается push с перемещением.

    Но для исправления этого кода вам надо прежде всего избавится от этой поломанной функции push.
    Ответ написан
    3 комментария
  • Какой open source проект написан на труъ Си++?

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

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

    Если постоянные жалобы, то устройте код ревью в команде. Пусть ваш код хотя бы пару неделек кто-то постоянно будет проверять перед комитом и выдавать конкретные правки (а вообще код-ревью хорошо использовать всегда. Тот же github дает возможность это делать. Или есть опен сорсный gerrit).

    Возможно, вы используете классы только как структуры максимум с какими-то тривиальными действиями (типа get_sum, get_value, set_value и т.д.). Когда как в ООП объекты должны инкапсулировать в себе логику и уметь делать нетривиальные вещи. Сама программа должна состоять из взаимодействующих объектов.

    Еще использование stl. Стоит избегать массивов - используются std::vector. Так же вместо char* стоит использовать std::string. Ну и там куча алгоритмов есть: от выбора максимума в массиве до сортировки.
    Ответ написан
    Комментировать
  • Как получить элементы структуры?

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

    Можно облегчить себе жизнь и использовать IDE. Тогда после написания "car_1." любая достаточно хорошая IDE подскажет вам список всех членов этой структуры. Но это по сути просто автоматизация действия "посмотреть в исходник".
    Ответ написан
    Комментировать
  • Как сгенеририовать СЛАУ (система линейных алгебраических уравнений) больших размеров?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Просто сгенерируйте случайную матрицу. Двумя циклами получайте коэффициенты через генератор случайных чисел. Вероятность, что она будет вырождена ничтожна. Потом сгенерируйте сулчайные значения всех переменных, подставьте в уравнения с имеющимеся теперь у вас коэффициентами и получите так правую часть уравнений. Вот и ваша СЛАУ с решением. Если хотите, чтобы решения не было, то можно случайно поменять правую часть в каких-то уравнениях. Если хотите, чтобы система была вырожденной, то замените какие-то строки случайной линейной комбинацией других строк (случайно получив коэффициенты линейной комбинации).

    В C++ есть генератор случайных чисел - функция rand(). Гуглите ее, она вернет случайное целое число. Если вам нужны вещественные и возможно отрицательные коэффициенты, то эти целые числа можно использовать для получения вещественных. Гуглите "C++ случайное вещественное число".
    Ответ написан
  • Сработает ли деструктор, присвоив atomic?

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

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

    Единственный способ бороться с этим, кажется, это использовать умные указатели. Всякие WeakPtr, которые не уничтожают блок счетчиков при удалении объекта. Если же вы опустились до сырых указателей, то это тупо адрес (число). И просто по нему никак не понять, а что по этому адресу лежит - оригинальный объект или что-то левое.
    Ответ написан
  • Не работает "cin" в С++. Как исправить?

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

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

    А дальше, чтобы найти мультипликативную группу, придется делать полный перебор. Перебирайте все полиномы (они у вас, видимо, над полем по модулю 2, их 2^n. Можно их перебирать как биты у целого числа). Потом умножайте на текущий полином в цикле, помечая в массиве уже полученные ранее полиномы. Если получили все 2^n элементов - вы нашли нужную группу. Если наткнулись на уже ранее полученный полином раньше времени - текущий кандидат не подходит.
    Ответ написан
    Комментировать
  • Будет ли большой std::vector быстрее, чем std::vectorstd::vector?

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

    в vector<vector> это фактически указатель на массив указателей. Строки раскиданны по памяти как попало и при обращении к ячейке будет лишнее обращение к памяти, чтобы получить адрес строки.

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

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

    Сначала читаете первую строку и создаете из нее корень дерева.

    А потом в цикле читайте строку и считайте, сколько там пробелов. Их должно быть не больше, чем количество доступных уровней (т.е. элементов в векторе).
    Добавляете текущую строку к узлу, который на уровне равном количеству пробелов (-1, потому что индексация с 0). Укорачиваете вектор до этого узла (все с уровенем ниже та вершина, к которой добавили ребенка - уже недоступно). Добавляете в вектор указатель на только что добавленную вершину.

    В вашем примере.

    Прочитали иван, сделали корень дерева. Вектор будет {"иван"} (указатель на вершину-корень дерева).

    Прочитали алексей. 1 проблел - все хорошо, в векторое 1 элемент, значит может быть до 1 пробела. Добавили "алексей" к вершине "иван". Вектор {"иван", "алексей"}

    Прочитали игорь. Вектор стал {"иван", "алексей", "игорь"}.

    Прочитали андрей. 1 пробел. Может быть до трех пробелов, ведь в векторе 3 элемента. Добавили "андрей" к узлу из вектора по индексу 0 (-1 к количеству пробелов). обрезали вектор до длины 1 и добавили туда новую вершину. Вектор стал {"иван", "андрей"}

    И т.д.

    Для добавления вершины создайте новый TreeNode с нужной строкой и push_back в список детей для нужного отца.
    Ответ написан
    Комментировать
  • Суть макросов в с++?

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

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

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Добавить идентификатор (имя переменной). В указанной строчке Raspisanie - это имя класса.
    Ответ написан
    1 комментарий