Ответы пользователя по тегу Алгоритмы
  • Можно ли число представить в виде float?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    представимость беззнакового числа в виде float

    Целого? Стандартного типа (int/long/...) или просто последовательности цифр?
    Простейший вариант:
    bool is_representable_as_float(unsigned v)
    {
        return v == (unsigned)(float)v;
    }
    Ответ написан
    Комментировать
  • Как найти частное от деления числа на числа по модулю m?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Имеются два числа a и b, как найти (a/b) mod m?

    Разделить a на b и взять результат деления по модулю m.
    Вот такой почти бесполезный ответ на бесполезно поставленный вопрос.

    Подсказка: другой ответ подразумевает какую-то оптимизацию, а для этого в вопросе не хватает ожидаемых величин a, b и m и ожидаемого быстродействия.
    Ответ написан
    Комментировать
  • Где я ошибаюсь, в описании алгоритма crc32/BZIP2?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Руководство по которому я изучал CRC, реально клёвое: www.ross.net/crc/download/crc_v3.txt
    Обычно путаница возникает с представлением данных (big/little endian) и тем, с какой стороны считать биты.
    Ответ написан
  • Возможно ли создать программу путем перебора символов в файле?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Ответ написан
    Комментировать
  • Как можно оптимизировать алгоритм сокращения дроби?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Классическое решение -- поиск НОД алгоритмом Евклида.
    Ответ написан
    Комментировать
  • Как реализовать приближенный двоичный поиск?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как минимум ваш двоичный поиск может закончиться с r = n+1, из-за чего код в if l <> r не будет работать.
    Ответ написан
  • Как доказать или опровергнуть: 1) 2^(n+1)=O(2^N); 2) 2^2N != O(2^n)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как доказать или опровергнуть

    Воспользоваться определением:
    2^(n+1)=O(2^N) означает, что найдётся x0 и M, такие, что для любого x > x0, 2^(x+1) < M * 2^x. Деля обе части на положительное 2^x получаем 2 < M. Т.е. оно справедливо для любого x0 и M > 2.
    Ответ написан
    Комментировать
  • Какой алгоритм использовать для определения минимального числа перестановок карт в колоде?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Мои мысли на тему и получившийся алгоритм:
    - обозначим для простоты карты их порядковыми номерами в отсортированной колоде, Ai;
    - каждой карте сопоставим расстояние до её конечной желаемой позиции, равное i - Ai;
    - перестановка карты с позиции i на позицию j меняет её расстояние на j - i, и одновременно на sign(i - j) меняет расстояния карт между i и j;
    - перестановка выгодна если она уменьшает суммарное расстояние, которое потребуется пройти картам после неё;
    - для текущей позиции существует по меньшей мере одна наиболее выгодная перестановка -- такая, которая максимально уменьшает оставшееся расстояние; найти её можно тупым перебором исходной и конечной позиции переставляемой карты (но, может быть, можно и быстрее);
    - совершая на каждом шаге наиболее выгодную перестановку мы, скорее всего, упорядочим карты за минимальное число перестановок.

    Код на c:
    #include <limits.h>
    #include <stdio.h>
    #include <string.h>
    
    #define N (sizeof(a) / sizeof(a[0]))
    
    inline int sign(int d)
    {
            if (d == 0)
                    return 0;
            return d < 0 ? -1 : 1;
    }
    
    inline int abs(int v)
    {
            return v < 0 ? -v : v;
    }
    
    int main()
    {
            int a[] = {2, 1, 3, 4, 0};
            int q[N];
    
            for (;;) {
                    int best_profit = INT_MIN;
                    int best_src = -1;
                    int best_dst = -1;
                    int i, src, dst, tmp;
    
                    for (i = 0; i < N; ++i)
                            q[i] = i - a[i];
    
                    for (src = 0; src < N; ++src)
                            for (dst = 0; dst < N; ++dst) {
                                    int d = sign(dst - src);
                                    int profit = abs(q[src]) - abs(q[src] + dst - src);
    
                                    //printf("...%d -> %d: profit = %d", src, dst, profit);
    
                                    for (i = src + d; i != dst + d; i += d) {
                                            if (sign(q[i]) == d) {
                                                    ++profit;
                                                    //printf(" + 1");
                                            } else {
                                                    --profit;
                                                    //printf(" - 1");
                                            }
                                    }
                                    //printf(" = %d\n", profit);
                                    if (profit > best_profit) {
                                            best_src = src;
                                            best_dst = dst;
                                            best_profit = profit;
                                            //printf("... -- new best!\n");
                                    }
                            }
                    printf("%d -> %d (profit = %d)\n", best_src, best_dst, best_profit);
                    if (best_profit == 0)
                            break;
                    tmp = a[best_src];
                    if (best_dst < best_src)
                            memmove(a + best_dst + 1, a + best_dst, (best_src - best_dst) * sizeof(int));
                    else
                            memmove(a + best_src, a + best_src + 1, (best_dst - best_src) * sizeof(int));
                    a[best_dst] = tmp;
    
                    for (i = 0; i < N; ++i)
                            printf("%d ", a[i]);
                    printf("\n");
            }
            return 0;
    }
    Ответ написан
    Комментировать
  • Алгоритм приведения вещественного числа к одинарной точности?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Примерно так это можно сделать:
    • скопировать знак;
    • извлечь порядок, отделить специальные случаи:
      • 0 и денормализованные числа становятся нулём;
      • бесконечность -- бесконечностью;
      • не-числа -- не-числами с обрезанной под новую точность мантиссой
    • в противном случае (обычное значение) убрать смещение порядка для double;
    • проверить, что несмещённый порядок помещается в диапазон float. Возможны 4 варианта:
      • не помещается (больше) -- записать в результат бесконечность;
      • помещается -- извлечь мантиссу;
      • не помещается (меньше, но может поместиться как денормализованное) -- извлечь мантиссу, добавить явный старший бит, сдвинуть вправо на разность порядка, извлечённого из double и минимального порядка float. Заменить извлечённый порядок минимальным порядком float;
      • не помещается (меньше) -- записать в результат 0;
    • добавить смещение порядка для float и запаковать в результат;
    • извлечь мантиссу, округлить, согласно текущей модели округления (см. [3]);
      • если при этом случилось переполнение увеличить порядок float (если тут тоже случилось переполнение, то в результате будет записан INF, что и требовалось);
    • запаковать мантиссу в результат.


    Ссылки:
    [1] https://en.wikipedia.org/wiki/Single-precision_flo...
    [2] https://en.wikipedia.org/wiki/Double-precision_flo...
    [3] https://en.wikipedia.org/wiki/IEEE_floating_point#...
    Ответ написан
    2 комментария
  • Актуально ли писать xml парсер?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    из-за размера файла (например в 3Гб) не хватает памяти и соответственно этот вариант отпадает.

    Воспользуйтесь SAX-парсером.
    Ответ написан
    Комментировать
  • Почему приложение x64 в два раза медленнее x86?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Хотелось бы понять в общих чертах откуда такая разница.

    Обычно ответ на этот вопрос проще всего получить с помощью профилирования, которое укажет вам где программа проводит время. Вам останется лишь понять, почему именно там.
    При использовании gcc это делается добавлением опции -pg к командам компиляции и линковки, запуску приложения и запуску gprof потом. Для VS наверняка тоже есть профайлер.
    Ответ написан
    Комментировать
  • Как работает данный алгоритм?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Есть такой код для двусвязного списка.

    Ошибка здесь: этот код для однозвязного списка.
    Ответ написан
    Комментировать
  • Кто может объяснить теорию музыки языком программирования?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    каждая нота обладает своей частотой

    да.

    шаг между ними одинаковый (N герц)

    нет. В равномерно темперированной шкале 12 полутонов делят одну октаву так, что отношение частот двух соседних нот отстоящих друг от друга на 1 полутон постоянно. Т.е. F(C#) = F(C) * k, F(D) = F(C#) * k = F(C) * k ^ 2, ... F(C') = F(H) * k = F(C) * k ^ 12. Т.к. частота нот отстоящих на октаву отличается вдвое, k = pow(2, 1./12).

    Нота "До" следующей октавы имеет частоту в 2 раза выше ноты "До" текущей.

    да, как и любая другая нота в двух соседних октавах.

    Зная частоту ноты "До" первой октавы, можно вычислить частоты для всех остальных нот.

    да. Зная частоту любой ноты можно вычислить частоты всех остальных нот.

    Подозрительно, что значения частот нигде не упоминаются

    Точные значения частот обычно никого не интересуют. С практической точки зрения интересны интервалы между ними.

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

    Читать здесь: https://ru.wikipedia.org/wiki/Равномерно_темпериро... здесь https://ru.wikipedia.org/wiki/Натуральный_строй и дальше по ссылкам.
    Ответ написан
    3 комментария
  • C++: Как решить задачу про мантиссу и знак float?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    ,мои попытки не увенчались успехом,к сожалению

    не очень-то информативно. Что за попытки? Что именно не увенчалось?

    Смотрим сюда и пишем:

    struct float_parts {
        unsigned fraction:23;
        unsigned exponent:8;
        unsigned sign:1;
    };
    
    union float_and_parts {
        float f;
        struct float_parts parts;
    };

    UPD: поправил для little endian.
    Ответ написан
    1 комментарий
  • Как создать парсер AST допускающий синтаксические ошибки?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Для начала как вооще строятся AST (абстрактное синтаксическое дерево) деревья? Что почитать?

    Книгу дракона.

    Как создать парсер для языка, например SQL, который генерирует AST дерево и прощает синтаксические ошибки?

    Предусмотреть в грамматике правила описывающие синтаксические ошибки и восстановление после них. В bison, например, для этого есть токен "error".
    Ответ написан
    Комментировать
  • Как из польской нотации получить АСТ дерево?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    На входе обратная польская запись включающая в себя операторы, функции, скобочки и числа.

    Нет скобочек в RPN.

    И что тут думать? Нужно тащить стек встреченных терминальных символов и готовых узлов, а при появлении оператора или функции создавать новый узел, снимать со стека столько элементов сколько ожидает пришедший оператор/функция и делать их его детьми, и добавлять обратно в стек только что созданный узел.
    Ответ написан
  • Задачки на "дробление чисел" для бенчмарков?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Странные у вас ассоциации с "дроблением чисел": ваши примеры сплошь целочисленные.
    Я бы предложил обращение матриц, численное решение дифур, рейтрейсинг.
    Ответ написан
    Комментировать
  • Quick sort некорректно сортирует. Где ошибка?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Неправильно выставлены границы интервала в quickSort, должно быть так:
    void quickSort(int arr[], int p, int r)
    {
    	if (p < r) {
    		int q = partition(arr, p, r);
    
    		quickSort(arr, p, q);
    		quickSort(arr, q + 1, r);
    	}
    }


    Тестовое приложеньице:
    int main()
    {
            for (int n = 2; n <= 10; ++n) {
                    int arr[10];
                    for (int i = 0; i < n; ++i)
                            arr[i] = i;
                    printf("n = %d\n", n);
                    do {
                            int sort[10];
    
                            memcpy(sort, arr, sizeof(arr));
                            quickSort(sort, 0, n);
                            for (int i = 1; i < n; ++i)
                                    if (sort[i] < sort[i - 1])
                                            printf("!\n");
                    } while (std::next_permutation(arr, arr + n));
            }
            return 0;
    }
    Ответ написан
    1 комментарий
  • Как найти ближайший элемент в двумерном массиве?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    найти ближайший к координатам точки непустой элемент

    Определитесь с метрикой для определения "ближайшего" элемента. Если это будет, например, манхэттенское расстояние (|dx| + |dy|), то рассматривайте увеличивающиеся ромбы с центром в вашей точке, до нахождения ненулевого элемента.
    Ответ написан
    Комментировать