Задать вопрос
Ответы пользователя по тегу C++
  • Ошибка xmemory при return, как пофиксить?

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

    Вам придется писать руками ввод и вывод типа из файла.
    Ответ написан
    1 комментарий
  • Как передать в лямбда функцию два аргумента?

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

    Передавайте в partition
    std::bind(predicate, item.first, std::placeholders::_1)
    в качестве предиката.

    Edit:

    Но тут у вас будет другая проблема. set - не vector. Вы не сможете его передать stable_partition. Вместо ручного применения stable_partition, используйте erase_if. Предикат туда также через std::bind передавайте.
    Ответ написан
    2 комментария
  • Как сделать вектор char беззнаковым числом?

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

    Единственное исключение, которое я нашел - std::from_chars. Только оно далеко не везде доступно и надо подключать charconv.

    Еще можно руками, если точно известно, что никаких ошибок в числе нет:
    unsigned int vtoi(const std::vector<char> &a) {
      unsigned int res = 0;
      for (const auto& c: a) {
        res = 10*res + static_cast<unsigned int>(c) - static_cast<unsigned int>('0');
      }
      return res;
    }


    Проверки на переполнение и левые символы добавьте сами, если надо.
    Ответ написан
    Комментировать
  • Можно ли объявить и реализовать шаблонный метод класса в исходном файле в C++?

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

    Можно еще перенести в cpp файл определение шаблонных классов/методов/функций, но для этого надо в хедере указать через forward declaration все используемые специализации шаблона. Например так:
    template <>
    int Database::RemoveIf<bool>(bool predicate);


    Конечно, там должен быть не bool а тип вашего предиката. И надо такие штуки воткнуть в хедер для ВСЕХ типов, которые в других файлах пихаются в шаблон.

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

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

    Вот пример: уже обновленная и отсортированная часть {1, 2, 3, 5, 6, 7}. Только что обновленный элемент имеет значение 4. lower_bound вернет итератор на 5. Вы поменяете 5 и 4 и получите {1, 2, 3, 4, 6, 7, 5} - не отсортировано уже.

    Можно удалить элемент в it и вставить на новое место через insert, но тогда могут быть проблемы с итератором цикла. Можно ручками через swap сдвигать элементы в цикле:
    T tmp = it->value;
    for (auto cur = std::lower_bound(vector.begin(), it, (*it)); cur < it; ++cur) {
       swap(tmp, cur->value);
    }
    it->value = tmp;


    Это, фактически, будет сортировкой вставкой за O(N^2). lower_bound за логарифм тут на самом деле даже лишнее и только замедляет сортировку. Лучше одним циклом сразу и swap-ать и сравнивать элементы.

    Но еще быстрее будет отдельно пройтись по массиву и обновить его целиком и потом вызвать std::sort для сортировки по value.
    Ответ написан
    Комментировать
  • Массив: Повернуть массив V на 90° и занести в массив Н все парные элементы?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Ну нарисуйте на бумажке матрцу, скажем 4x4, заполните числами от 1 до 16 и рядом нарисуйте ее же повернутую на 90 градусов. Посмотрите внимательно, куда попадают числа. Возьмите произвольную ячейку [i][j] и подумайте, куда она в итоге попадает. Если не можете так сообразить, выпишите для чисел 1,2,5,7,13 их индексы в первой и второй матрице в 4 столбика и посмотрите на закономерности между индексами.
    Ответ написан
    Комментировать
  • Как оптимизировать поиск в ширину?

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

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

    Вместо SegmentTree tree = new SegmentTree(a, n);
    надо
    SegmentTree tree(a, n); или SegmentTree *tree = new SegmentTree(a, n);

    new - создает указатель. Инициализировать им нужно, соответственно, указатель.
    Ответ написан
  • В чем причина возникновения ошибки std::bad_alloc при поиске в графе?

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

    Вы там еще очередь pop-аете раньше времени.
    Ответ написан
  • Что означает traits_type::eof()?

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

    type_traits::eof() - возвращает код конца файла, для текущего параметра шаблона.

    Вся эта шаблонная магия взялась для того, чтобы можно было читать из файла или char, или wchar, или еще черт знает что, в зависимости от кодировки. Раз читаемые символы могут быть какими угодно, то и код конца файла нужен свой собственный для разных типов символов. Поэтому eof() является частью type_traits в streambuf.
    Ответ написан
    Комментировать
  • В чем проблема обхода в ширину и глубину?

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вы передаете структуре в конструктор ее саму! Ее еще не создано, а вы ее передаете куда-то. Зачем вам вообще в структуре хранить ссылку на другую структуру? Это вы из питона, что ли взяли? В C++ не надо методам класса/структуры передавать указатель на нее, они средствами языка привязаны уже к экземпляру. Можно обращаться просто к членам структуры напрямую из методов. Или через this->, если есть конфликт имен.
    Ответ написан
    4 комментария
  • Как вывести часть bitset-a?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    С битсетом можно работать, как с массивом. У него есть operator[]. Просто пройдитесь циклом в 3 итерации и выводите x[i].
    Ответ написан
    Комментировать
  • Как реализовать "копирование" файла на C++?

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

    Используйте, например, ifstream и ofstream. Только нужно работать в бинарном режиме. Открывайте файлы, передавая std::ios::binary в конструкторы. Используйте read для чтения и write для записи. Там даже примеры есть вам релевантные в документации.

    Еще можно всякие итераторы использовать и std::copy.
    Ответ написан
  • Как мне сделать чтоб вибирались числа из промежутка между найменшим и найбольшем в двумерном масиве?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    if (max >= arr[i][j]) {
            max; 
          }
          else if (max <= arr[i][j]) {
            swap(max, arr[i][j]);
            maxii = i; maxjj = j;
          }


    ЧТО ТУТ ВООБЩЕ ПРОИСХОДИТ?
    Понятно, что пытались найти индекс максимума в массиве, но тут такой бред написан...

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

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

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

    Бинарным поиском находите в первом массиве индекс значения и выдаете ответ из второго массива по тому же индексу.

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

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

    Клиент после отсылки данных должен из сокета читать ответ.
    Ответ написан
    Комментировать
  • Код не успевает выполниться.С++.Что делать?

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

    Можно поиск символов перевода строки ускорить всякими SIMD инструкциями.

    Но вообще, у вас файл маленький, не должно быть проблем со скоростью.
    Ответ написан
    Комментировать
  • Есть ли в C++ функция преобразующая текст в байты и байты в текст по заданной кодировке?

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

    С помощью его можно читать файлы в utf_8, например, так:
    std::ifstream f("file.txt");
    std::wbuffer_convert<std::codecvt_utf8<wchar_t>> conv(f.rdbuf());
    std::wistream wf(&conv);


    Потом читаете из wistream, как будто это обычный cin. Только вместо char нужен wchar_t, а вместо string - wstring.
    Ответ написан
    3 комментария
  • Почему неправильно считывается строка?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    file.get() читает один символ, возвращает его и переходит к следующему символу ввода. Поэтому код:
    while (file.get() != ']')
    {
       temp += file.get();
    }


    читает первый символ, сравнивает со скобкой, потом приписывает в temp второй символ. Потом читает третий и, возможно, приписывает четвертый и т.д. Два вызова file.get() выполняют два чтения.

    Правильно делать так:

    while ( (с = file.get()) != ']')
    {
       temp += с;
    }


    И похожим образом обрабатывайте '[' перед этим. Читайте в переменную, сравнивайте и не забудьте прочтенный символ засунуть в строку.

    Ну, или используйте в условиях istream::peek.
    Ответ написан
    Комментировать