Я решаю следующую проблему:
Предположим, у меня есть список пакетов программ, и их имена могут выглядеть следующим образом (единственное известное, что эти имена сформированы как SOMETHING + VERSION
, что означает, что версия всегда приходит после имя) :
Efficient.Exclusive.Zip.Archiver-PROPER.v.122.24-EXTENDED
Efficient.Exclusive.Zip.Archiver.123.01
Efficient-Exclusive.Zip.Archiver(2011)-126.24-X
Zip.Archiver14.06
Zip-Archiver.v15.08-T
Custom.Zip.Archiver1.08
Custom.Zip.Archiver1
Теперь мне нужно проанализировать этот список и выбрать только последние версии каждого пакета. Для этого примера ожидаемый результат будет:
Efficient-Exclusive.Zip.Archiver(2011)-126.24-X
Zip-Archiver.v15.08-T
Custom.Zip.Archiver1.08
Текущий подход, который я использую, можно описать следующим образом:
Split the initial strings into groups by their starting letter,
ignoring spaces, case and special symbols.
(`E`, `Z`, `C` for the example list above)
Foreach element {
Apply the regular expression (or a set of regular expressions),
which tries to deduce the version from the string and perform
the following conversion `STRING -> (VERSION, STRING_BEFORE_VERSION)`
// Example for this step:
// 'Efficient.Exclusive.Zip.Archiver-PROPER.v.122.24-EXTENDED' ->
// (122.24, Efficient.Exclusive.Zip.Archiver-PROPER)
Search through the corresponding group (in this example - the 'E' group)
and find every other strings, which starts from the 'STRING_BEFORE_VERSION' or
from it's significant part. This comparison is performed in ignore-case and
ignore-special-symbols mode.
// The matches for this step:
// Efficient.Exclusive.Zip.Archiver-PROPER, {122.24}
// Efficient.Exclusive.Zip.Archiver, {123.01}
// Efficient-Exclusive.Zip.Archiver, {126.24, 2011}
// The last one will get picked, because year is ignored.
Get the possible version from each match, ***pick the latest, yield that match.***
Remove every possible match (including the initial element) from the list.
}
Этот алгоритм (как я предполагаю) должен работать для чего-то вроде O(N * V + N lg N * M)
, где M
обозначает среднее время сопоставления строк, а V
обозначает рабочее время регулярного выражения версии.
Тем не менее, я подозреваю, что есть лучшее решение (всегда есть!) , возможно, конкретная структура данных или лучший подход к сопоставлению.
Если вы можете что-то предложить или , сделайте несколько заметок о текущем подходе , пожалуйста, не стесняйтесь делать это.