Сравнение версий программы
Условие
Напишите функцию, которая сравнивает две версии программы в формате x.x.x.x (например, 8.1.4.2) и определяет, какая из них более свежая.
Функция должна вернуть:
- 1, если первая версия новее
- -1, если вторая версия новее
- 0, если версии равны
Пример
Вход: "8.1.4.2" и "8.2.3.1" Выход: -1 (вторая версия новее)
Вход: "8.3.19.1" и "8.3.18.5" Выход: 1 (первая версия новее)
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение
Обзор задачи
Сравнение версий — это критическая операция в системе управления софтом, обновлений и совместимости. В 1С это особенно важно при работе с конфигурациями, расширениями и интеграциями. Версия имеет иерархическую структуру, где каждый номер разной значимости: major (8), minor (1), patch (4), build (2).
Структура версии
Формат x.x.x.x состоит из четырёх частей:
- x₁ — Major версия (основной выпуск)
- x₂ — Minor версия (функциональные дополнения)
- x₃ — Patch версия (исправления ошибок)
- x₄ — Build номер (номер сборки)
Сравнение идёт слева направо — первый отличающийся номер определяет результат.
Реализация 1: Базовый вариант
Функция СравнитьВерсии(Версия1, Версия2)
// Разбиваем версии на компоненты
КомпонентыВерсии1 = РазбитьВерсию(Версия1);
КомпонентыВерсии2 = РазбитьВерсию(Версия2);
// Сравниваем каждый компонент
Для И = 0 По 3 Цикл
Если КомпонентыВерсии1[И] > КомпонентыВерсии2[И] Тогда
Возврат 1; // Первая версия новее
ИначеЕсли КомпонентыВерсии1[И] < КомпонентыВерсии2[И] Тогда
Возврат -1; // Вторая версия новее
КонецЕсли;
КонецЦикла;
Возврат 0; // Версии равны
КонецФункции
Функция РазбитьВерсию(ВерсияСтрока)
// Разбиваем строку по точке
Компоненты = Новый Массив(4);
ПозицияТочки1 = Найти(ВерсияСтрока, ".");
ПозицияТочки2 = Найти(ВерсияСтрока, ".", , ПозицияТочки1 + 1);
ПозицияТочки3 = Найти(ВерсияСтрока, ".", , ПозицияТочки2 + 1);
Компоненты[0] = Число(Лево(ВерсияСтрока, ПозицияТочки1 - 1));
Компоненты[1] = Число(Середина(ВерсияСтрока, ПозицияТочки1 + 1, ПозицияТочки2 - ПозицияТочки1 - 1));
Компоненты[2] = Число(Середина(ВерсияСтрока, ПозицияТочки2 + 1, ПозицияТочки3 - ПозицияТочки2 - 1));
Компоненты[3] = Число(Середина(ВерсияСтрока, ПозицияТочки3 + 1));
Возврат Компоненты;
КонецФункции
Реализация 2: С использованием встроенных функций 1С
Функция СравнитьВерсииУлучшенная(Версия1, Версия2)
// Используем встроенную функцию УмножитьНа для отладки (если нужна)
КомпонентыВерсии1 = СтроковыеФункции.РазделитьСтроку(Версия1, ".");
КомпонентыВерсии2 = СтроковыеФункции.РазделитьСтроку(Версия2, ".");
// Убедимся, что оба массива имеют одинаковую длину
ОжидаемаяДлина = 4;
Если КомпонентыВерсии1.Количество() <> ОжидаемаяДлина ИЛИ КомпонентыВерсии2.Количество() <> ОжидаемаяДлина Тогда
ВызватьОшибку("Неверный формат версии. Ожидается формат x.x.x.x");
КонецЕсли;
// Сравниваем компоненты
Для И = 0 По ОжидаемаяДлина - 1 Цикл
ЧисловоеЗначение1 = Число(КомпонентыВерсии1[И]);
ЧисловоеЗначение2 = Число(КомпонентыВерсии2[И]);
Если ЧисловоеЗначение1 > ЧисловоеЗначение2 Тогда
Возврат 1;
ИначеЕсли ЧисловоеЗначение1 < ЧисловоеЗначение2 Тогда
Возврат -1;
КонецЕсли;
КонецЦикла;
Возврат 0;
КонецФункции
Реализация 3: С гибкой поддержкой разных форматов
Функция СравнитьВерсииГибкая(Версия1, Версия2, Минимальнокомпонентов = 4)
КомпонентыВерсии1 = СтроковыеФункции.РазделитьСтроку(Версия1, ".");
КомпонентыВерсии2 = СтроковыеФункции.РазделитьСтроку(Версия2, ".");
// Приведём оба массива к одной длине, дополнив нулями
МаксимальнаяДлина = Макс(КомпонентыВерсии1.Количество(), КомпонентыВерсии2.Количество());
Пока КомпонентыВерсии1.Количество() < МаксимальнаяДлина Цикл
КомпонентыВерсии1.Добавить("0");
КонецЦикла;
Пока КомпонентыВерсии2.Количество() < МаксимальнаяДлина Цикл
КомпонентыВерсии2.Добавить("0");
КонецЦикла;
// Сравниваем
Для И = 0 По МаксимальнаяДлина - 1 Цикл
ЧисловоеЗначение1 = Число(КомпонентыВерсии1[И]);
ЧисловоеЗначение2 = Число(КомпонентыВерсии2[И]);
Если ЧисловоеЗначение1 > ЧисловоеЗначение2 Тогда
Возврат 1;
ИначеЕсли ЧисловоеЗначение1 < ЧисловоеЗначение2 Тогда
Возврат -1;
КонецЕсли;
КонецЦикла;
Возврат 0;
КонецФункции
Реализация 4: С преобразованием в число для быстрого сравнения
Функция СравнитьВерсииЧисловоеПредставление(Версия1, Версия2)
// Преобразуем версии в единое числовое представление
ЧисловоеПредставление1 = ПреобразоватьВерсиюВЧисло(Версия1);
ЧисловоеПредставление2 = ПреобразоватьВерсиюВЧисло(Версия2);
Если ЧисловоеПредставление1 > ЧисловоеПредставление2 Тогда
Возврат 1;
ИначеЕсли ЧисловоеПредставление1 < ЧисловоеПредставление2 Тогда
Возврат -1;
Иначе
Возврат 0;
КонецЕсли;
КонецФункции
Функция ПреобразоватьВерсиюВЧисло(ВерсияСтрока)
КомпонентыВерсии = СтроковыеФункции.РазделитьСтроку(ВерсияСтрока, ".");
// Объединяем числа в единое число, выделяя по 5 бит на каждый компонент
// Например: 8.1.4.2 → 8*1000000 + 1*10000 + 4*100 + 2
ЧисловоеПредставление = 0;
Для И = 0 По КомпонентыВерсии.Количество() - 1 Цикл
КоэффициентМасштабирования = Pow(100, КомпонентыВерсии.Количество() - И - 1);
ЧисловоеПредставление = ЧисловоеПредставление + Число(КомпонентыВерсии[И]) * КоэффициентМасштабирования;
КонецЦикла;
Возврат ЧисловоеПредставление;
КонецФункции
Реализация 5: Объект для работы с версиями
Класс Версия
Major;
Minor;
Patch;
Build;
Процедура ПриСоздании(ВерсияСтрока)
Компоненты = СтроковыеФункции.РазделитьСтроку(ВерсияСтрока, ".");
Если Компоненты.Количество() = 4 Тогда
Major = Число(Компоненты[0]);
Minor = Число(Компоненты[1]);
Patch = Число(Компоненты[2]);
Build = Число(Компоненты[3]);
Иначе
ВызватьОшибку("Неверный формат версии");
КонецЕсли;
КонецПроцедуры
Функция СравнитьС(ДругаяВерсия) Экспорт
Если Major <> ДругаяВерсия.Major Тогда
Возврат ?(Major > ДругаяВерсия.Major, 1, -1);
КонецЕсли;
Если Minor <> ДругаяВерсия.Minor Тогда
Возврат ?(Minor > ДругаяВерсия.Minor, 1, -1);
КонецЕсли;
Если Patch <> ДругаяВерсия.Patch Тогда
Возврат ?(Patch > ДругаяВерсия.Patch, 1, -1);
КонецЕсли;
Если Build <> ДругаяВерсия.Build Тогда
Возврат ?(Build > ДругаяВерсия.Build, 1, -1);
КонецЕсли;
Возврат 0;
КонецФункции
Функция ЭтоНовее(ДругаяВерсия) Экспорт
Возврат СравнитьС(ДругаяВерсия) > 0;
КонецФункции
Функция ЭтоСтарше(ДругаяВерсия) Экспорт
Возврат СравнитьС(ДругаяВерсия) < 0;
КонецФункции
КонецКласса
Примеры использования
// Пример 1: базовое сравнение
Результат1 = СравнитьВерсииУлучшенная("8.1.4.2", "8.2.3.1");
Сообщить(Результат1); // -1 (вторая версия новее)
Результат2 = СравнитьВерсииУлучшенная("8.3.19.1", "8.3.18.5");
Сообщить(Результат2); // 1 (первая версия новее)
Результат3 = СравнитьВерсииУлучшенная("1.0.0.0", "1.0.0.0");
Сообщить(Результат3); // 0 (версии равны)
// Пример 2: с использованием класса
Версия1 = Новый Версия("8.1.4.2");
Версия2 = Новый Версия("8.2.3.1");
Если Версия1.ЭтоНовее(Версия2) Тогда
Сообщить("Первая версия новее");
ИначеЕсли Версия1.ЭтоСтарше(Версия2) Тогда
Сообщить("Вторая версия новее");
Иначе
Сообщить("Версии равны");
КонецЕсли;
Рекомендация
Для production-кода рекомендую использовать реализацию 5 (класс Версия) — она обеспечивает:
- Объектно-ориентированный подход
- Переиспользуемость
- Чистоту кода
- Удобство использования через методы
Для быстрого решения — реализация 2 (улучшенная) простая и надёжная.