Задать вопрос
  • Как завершить все потоки сразу после завершения одного из потоков в си, используя толлько pthread_detach и pthread_join?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Если вызвать exit какой-нибудь, то программа завершится и система прибъет все потоки.
    Ответ написан
  • Почему можно обратиться к объекту через указатель со значением nullptr?

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

    P.s. сказанное выше не относится к виртуальным функциям. Там указатель на функцию храниться в vtable в экземпляре класса и вызов через nullptr скорее всего упадет.
    Ответ написан
    Комментировать
  • Как сделать сортировку двухмерного массива по столбцам?

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

    Вам осталось по одному числу - индексу в этом виртуальном одномерном массиве получать индексы исходного двумерного массива.

    Номер столбца будет i / M, Где M - количество строк. Номер строки будет i % M.

    Вам надо только написать алгоритм сортировки одномерного массива и везде, где там идет обращение к [i], вам надо сделать [i % M][i / M].
    Ответ написан
  • Как использовать socket в gcc на windows?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Если вы используете cygwin для компиляции, то можно и линуксовый socket использовать. Будет чуть менее эффективно из-за фактически эмуляции posix api.

    Ну или, если через visual studio компилируете, то используйте winsocket API
    Ответ написан
    Комментировать
  • Как решить задачу по математике с помощью python?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Это не задача на программирование, а задача на математику. Решение - одна формула.

    Сначала решите уравнение, при какой величине вклада X доход от бумаги и от банковского вклада будет одинаков?

    1.1X+2000 = 1.12X

    До этой суммы выгоднее брать бумагу - после - вклад.
    Далее надо 4 раза взять одно из двух, сравнивая текущую сумму с пороговым значением выше.

    От питона вам надо уметь выполнять действие 4 раза:
    for i in range(0, 4):

    Сравнивать 2 значения и делать в зависимости от этого разные действия.
    if a < b:
      foo
    else:
      bar


    Ну, вряд ли вы не знаете, еще надо уметь присваивать переменные и выполнять арифметику - умножение и сложение.
    Ответ написан
    Комментировать
  • Почему в СТЕКЕ разрешается выделять достаточно мало памяти?

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

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

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

    А так, для ускорения выделения памяти есть, например, аллокаторы на стеке: Заводится локальный массив и специальный менеджер памяти вместо выделения ее в куче, выделяет куски из этого массива. Но их не используют для хранения больших объемов данных по первой причине - это очень расточительно по памяти.

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

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

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

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

    Когда для каждой точки вы знаете где ее прошлое и следующее положение, у вас задача найти минимум функции
    sum_i (xp_i-xp'_i)^2+(yp_i-yp'_i)^2, где
    xp' = xn*cosa - yn*sina + dx
    yp' = xn*sina + yn*cosa + dy.

    Тут (xp, yp) - координаты i-ой точки в прошлом кадре, (xn, yn) - координаты в следующем кадре, cosa,sina,dx,dy - неизвестные. Берете производные по dx, dy и a приравниваете к 0. Получаете 3 уравнения с 3 неизвестными. Их двух первых элементарно выразить dx, dy через cosa/sina. Подставив в последнее вы получите уравнение вида cosa^2 A + sina cosa B + sina^2C + D = 0. Можно домножить D на cosa^2+sina^2, потом поделить все на sin^2 и решать квадратное уравнение относительно тангенса. Потом через арктангенс найти решение.

    Если изменения от кадра к кадру могут быть большими, то надо минимизировать чуть чуть другую функцию:

    sum_i min_j ((xp_j-xp'_i)^2+(yp_j-yp'_i)^2) - для каждой точки берем минимум по всем возможным прообразам и это суммируем. Поскольку оно уже не диффиренцируемо, придется использовать какой-то более хитрый метод оптимизации по dx, dy, a.
    Ответ написан
    Комментировать
  • Почему после вызова Message Box, GetKeyState() не считывает состояние клавиши?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Диалоговое окно-то появляется?

    Я подозреваю, что MessageBox возвращает 0, что происходит происходит при ошибке:
    If the function fails, the return value is zero.


    Поэтому цикл while завершается. Т.е. проблема не с GetKeyState, а логикой программы.
    Ответ написан
  • Как реализовать copy on write class?

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

    Нужен счетчик ссылок на буфер. Перед записью проверяйте, что счетчик равен 1. Иначе копируете данные и в текущем объекте заменяете указатель на новый буфер.

    Счетчик должен храниться где-то вместе с буфером и является частью умного указателя.

    Можно использовать std::shared_ptr - там уже этот счетчик реализован (use_count).
    Ответ написан
    Комментировать
  • Как копировать список в си (C)?

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

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

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

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

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Я бы посоветовал делать абстракцию не на уровне пикселя, а на уровне картинки. Ибо так можно оптимальнее организовывать расположение пикселей в памяти да и обрабатывать изображение быстрее. Вместо функции, которая для каждого пикселя проверяет, а что там у него брать R или Y, используют функции, которым передается plane - один канал. Что там конкретно R, G, Y, V - обычно не важно. Если вы ищете контур или сглаживаете изображение, то работа идет абсолютно одинаково в каждом канале.

    В качестве примера можно посмортреть вот тут или тут.
    Ответ написан
    Комментировать
  • Что делать если при отладке сработала точка останова по исключению?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    char str = 0, *pStr = &str;

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

    Надо выделять память под строку. Или статический массив, или malloc.
    Ответ написан
    Комментировать
  • Как вырезать область изображения под контуром, Алгоритм?

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

    Сначала одним циклом покрасьте все точки контура.
    Потом берите любую точку внутри полигона, красьте ее и кладите в очередь. Пока очередь не пуста берете точку оттуда, берете 4 или 8 ее соседей и если они не покрашены еще - красите их и кладете в очередь.

    Может быть сложность с выбором самой первой точки внутри полигона. Но тут можно аккуратно пройтись вдоль полигона против часовой стрелки и взять первую непокрашенную точку слева относительно обхода. Тут можно для каждой точки найти вектора на двух соседей по контуру, потом перебрать 4-8 соседних пиксилей и взять тот непокрашенный, вектор на который лежит между двумя векторами вдоль контура.
    Ответ написан
    Комментировать
  • Почему в массив записываются числа не и указанного диапазона?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    *p = (rand( )%100 - 50);
    for (int i = 1; i < k; i++) {
      *(p + 1) = -i * * (p + i - 1);
    }


    Можете вообще объяснить, что этот код делает? Зачем он это делает? Что вы хотели, чтобы он делал?

    Помимо этого, вместо *(p+X) можно писать p[X]. Так понятнее. У вас тут явно не к месту арифметика указателей приплетена.

    А так, код работает так, как написан. Первое число в массиве заполняется случайным от -50 до 49, второе число много раз переписывается чем-то умноженным на какое-то другое число массива, остальные числа не заполняются вообще.

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    В деструкторе удаляйте, только если память не nullptr или длина не 0.
    Ответ написан
    Комментировать
  • Из-за чего может быть access violation при решении этой задачи?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    access violation явно говорит о проблеме работы с памятью.

    Единственное спорное место - это ввод. Может в файле есть лишние переводы строк или кривые тесты (пропущено какое-то число). Ваша программа, похоже, в этом случае попытается обратиться к N[1] и упадет, потому что в строке только 1 или вообще 0 чисел.

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

    Ну или читайте тупо функциями чтения чисел. В этой задаче входной файл маленький - можно спокойно читать по одному числу, даже если это будет медленнее.
    Ответ написан
  • Из за чего появляется ошибка ошибка ld returned 1 exit status?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Выше написанно undefined reference to 'processingArray(int*, int)'


    Ну вот. У вас функция processingArray объявлена, но нигде не реализована. Тело функции где? Поскольку вы ее объявили, компилятор это безобразие проглатил и понадеялся, что эта функция реализована в другом файле и на этапе линковки она найдется. Но линкер ее не нашел, потому что ее нигде и нет.

    Вы, видимо, не все из учебника переписали. Там после функции main скорее всего идет реализация функции processingArray.
    Ответ написан
    7 комментариев
  • Как решить проблему Segmention Fault?

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

    Я подозреваю, что в файле у вас не 50 строк (мне лень считать). Вот вы и вылезаете за границу массива.

    Ну или там какие-то лишние переводы строк, пробелы имеются. поэтому fin.eof() не выполняется после считывания последней строки. Потом вы пытаетесь что-то еще прочитать, но получаете назад пустую строку. Это бы не было проблемой, но вы потом пытаетесь это все запихать в 51-ый элемент массива.

    Советую вместо define N и статического массива использовать std::vector. В цикле считывания файла делайте push_back нового объекта в вектор (а еще лучше, emplace_back для экономии лишнего копирования).

    При выводе берите size() у вашего вектора.

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

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