Ответы пользователя по тегу Алгоритмы
  • Есть ли эффективная реализация словаря у которого ключ регулярное выражение?

    lam0x86
    @lam0x86
    Регулярное выражение - это частный случай конечного автомата. Перед вами по сути стоит задача объединения всех выражений в один автомат, где начальным будет epsilon-состояние, т.е. в недетерминированный конечный автомат. Из него потом надо построить детерминированный КА с терминальными состояниями с соответствующими значениями из словоря. В общем, довольно непростое решение, но будет быстрее линейного перебора.
    Как вариант, можно объединить все ключи словаря в одно регулярное выражение по принципу "(a1)|(a2)|...|(aN)", и затем определить, какая из групп окажется не пустой после матчинга. Это, по сути, то же самое, что я написал вначале, только гораздо проще.
    Ответ написан
  • Как обработать огромный текстовый файл?

    lam0x86
    @lam0x86
    Если строки короткие, то, в принципе, подойдёт такое решение:
    var secondFileLines = new HashSet<string>(File.ReadLines("<файл2>"));
    using (var writer = new StreamWriter("<файл3>"))
    {
        foreach (var line in File.ReadLines("<файл1>"))
        {
            if (!secondFileLines.Contains(line))
            {
                writer.WriteLine(line);
            }
        }
    }


    Если длина строк неограничена, то могут возникнуть проблемы с расходом памяти. В этом случае, всё сильно усложняется. Вам, вероятно, придётся хранить набор хэш-кодов строк из второго файла и сравнивать с хэш-кодом каждой строки из первого. Но тут могут возникнуть ложно-положительные срабатывания, если у разных строк хэши будут совпадать. В этом случае, необходимо будет сравнивать строки посимвольно. Это при идеальной реализации. Впрочем, вероятность совпадения хэшей - 1/2^32. Ну, и надо умножить на 70 миллионов. Если задача позволяет добавить пару лишних строк в результирующий файл, я бы так и поступил.
    Можно немного улучшить алгоритм с хэшами: если, например, использовать 256-битную хэш-функцию, а не стандартную (GetHashCode), можно снизить вероятность ложного срабатывания до 1e-77 (в случае использования SHA1). Думаю, такой мизерной вероятности будет достаточно, чтобы считать задачу решённой. Правда, придётся немного усложнить алгоритм сравнения хэшей - придётся сравнивать массивы.
    Ответ написан
    3 комментария
  • Алгоритмический вопрос от будущего C#.NET-джуниора. С чего начать исследование?

    lam0x86
    @lam0x86
    Последовательность действий такая:
    1) разбиение текста на лексические единицы (в вашем случае значимыми единицами являются слова). Удобно на выходе получать IEnumerable, представляющий ленивый итератор по словам в тексте.
    2) приведение слова к нормальной форме, т. е. к нижнему регистру и, опционально, к общей словоформе (например, для существительных - им. падеж, ед. число, и т.д.)
    3) добавление слова в Dictionary, где ключом является само слово, а значением - счётчик:
    int count;
    dictionary.TryGetValue(word, out count);
    dictionary[word] = count + 1;
    Ответ написан
    Комментировать
  • Алгоритм распределения точек на плоскости

    lam0x86
    @lam0x86
    Ответ написан
    Комментировать