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

    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 комментарий
  • Как имитировать разрыв вершин графа?

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

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

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

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

    template <int a, int b>
    class A {
        public:
        template<bool tmp = true>
        typename std::enable_if<a==b && tmp, int>::type F() {
           return 1;   
        }
    };
    
    ...
    
    A<1,1> a;
    std::cout << a.F();  // OK.
    A<2,100> b;
    std::cout << b.F(); // Ошибка A<2,100> не имеет метода F().


    Мне сложно объяснить, чтобы было понятно, почему работает именно это, но я попробую.

    Во-первых, метод дложен быть обернут в шаблон, потому что если там будет ошибка, то не инстанцируется шаблон для вашего типа Matrix, а он должен быть даже если размерности не равны.

    Далее, хотелось бы что бы просто работало вот это:
    template<>
     typename std::enable_if<a==b, int>::type F()

    Тут все понятно, enable_if не имеет type, если a неравно b. Шаблон никак не инстанциировать и метод не должен был бы генерироваться. Но это было бы слишком просто.

    Вместо этого, надо там завести какой-то вообще ненужный как бы параметр шаблона tmp, и обязательно использовать его в enable_if. Это потому что если в этом шаблоне не будет никак использоваться параметр шаблона, то SFINAE не срабатывает, и вылезает ошибка компиляции.
    Ответ написан
  • Будет ли std::swap(vector[0], vector[1]) быстрее, чем vector[1] = vector[0]?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    В общем случае - будет.
    std::swap работает за константу:
    Complexity
    1) Constant.


    Присвоение за линию:
    Complexity
    1) Linear in the size of *this and other.


    Edit: это если присваемые штуки - вектора. Или какие-то большие объекты с семантикой перемещения. Если у вас тупо числа, то одно присвоение будет быстрее swap.
    Ответ написан
  • Как с помощью шаблонов проверить, что два числа равны?

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

    template <int a, int b>
    class A {
        public:
        template<bool tmp = true>
        typename std::enable_if<a==b && tmp, int>::type F() {
           return 1;   
        }
    };
    
    ...
    
    A<1,1> a;
    std::cout << a.F();  // OK.
    A<2,100> b;
    std::cout << b.F(); // Ошибка A<2,100> не имеет метода F().


    Мне сложно объяснить, чтобы было понятно, почему работает именно это, но я попробую.

    Во-первых, метод дложен быть обернут в шаблон, потому что если там будет ошибка, то не инстанцируется шаблон для вашего типа Matrix, а он должен быть даже если размерности не равны.

    Далее, хотелось бы что бы просто работало вот это:
    template<>
     typename std::enable_if<a==b, int>::type F()

    Тут все понятно, enable_if не имеет type, если a неравно b. Шаблон никак не инстанциировать и метод не должен был бы генерироваться. Но это было бы слишком просто.

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Сначала каждую строку resize до размера size()+w0+w1. Потом сдвигайте элементы на w0 позиций вправо (цикл надо гнать с конца). Потом заполните пустые места нулями.

    То же самое в самом векторе векторов. Только вместо чисел надо сдвигать вектора на h0 позиций. На пустые места надо будет записывать std::vector(n+w0+w1, 0);

    Edit: А вообще, тут и добавлять в массив ничего не надо. Вы нужный вам ответ можете нулями прямо во время вывода добить.
    Ответ написан
    Комментировать
  • Как разбить объявление класса и его реализацию?

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

    Чтобы это исправить нужно или засунуть все в h файл, или в cpp файле прописать специализации шаблона со всеми типами, которые где-либо еще используются, вот так:
    using A<int>;
    using A<double>;
    // etc


    Далее, как именно и зачем вы хотите этот внутренний класс скрыть?
    Иногда вам может быть достаточно сделать член этого типа private и все. Факт того, что кто-то где-то сможет завести переменную этого типа обычно не является проблемой. Для списка уж точно. Если же это проблема и внутренний класс является friend внешнего и что-то такое делает, что нарушает инкапсуляцию (например при учнитожении, что-то меняет в родительском классе), то просто сделав вложенный класс private, вы ничего не добъетесь. Переменные этого типа все-равно можно будет использовать и к ним обращатся (иногда через хаки). Обычно у внутренних классов просто делают приватным конструктор и нужные методы и прописывают внешний класс как friend. Тогда вы в самом классе сможете переменные этого типа создавать и использовать, но никто снаружи ничего с ним сделать не может.

    И кстати, в вашем случае вам совсем нет смысла делать вложенный класс шаблоном. Он уже в шаблоне же, просто используйте внутри тип T.
    Ответ написан
    Комментировать
  • Как передать list в функцию c++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    В параметрах функции:
    list ItemsList
    но в другом месте:
    list <int> ItemsList

    list - это шаблон или как?
    Ответ написан
  • Проверить первые 2 байта?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Окройте файл в ifstream в бинарном режиме и читайте 2 байта через read.

    Или используйте fread. Читайте 2 байта в буфер длинной 2.
    Ответ написан
    Комментировать
  • Рекурсия.По какой причине ответ всегда 0?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Аккуратно расставьте отступы. У вас там логика if else напутана, и программа делает совсем не то, что бы вам хотелось. Кроме того, посмотрите внимательно на warning-и от компилятора (он точно скажет, что power иногда не возвращает никаких значений, хотя вам кажется, что return есть во всех ветках if else). Это как раз потому, что у вас скобки не так расставлены и else относится совсем не к тому if, как вы хотели бы.
    Ответ написан
    Комментировать