Парсинг номеров версий к вещественным числам

Я хотел бы определить, больше ли один номер версии, чем другой. Номер версии мог быть любым следующим:

4

4.2

4.22.2

4.2.2.233

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

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

Is 4.7 > 4.2.2

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

Я предпочтительно хотел бы решение ColdFusion, но фундаментальное понятие будет также прекрасно.

7
задан abatishchev 14 June 2010 в 14:17
поделиться

6 ответов

Это скопировано из кода обновления плагина в Mango Blog и немного обновлено. Он должен делать именно то, что вы хотите. Он возвращает 1, если аргумент 1 больше, -1, если аргумент 2 больше, и 0, когда они являются точными совпадениями. (Обратите внимание, что 4.0.1 будет точным совпадением с 4.0.1.0)

Он использует функции списка CF вместо массивов, поэтому вы можете увидеть небольшое увеличение производительности, если вместо этого переключитесь на массивы ... но эй, оно работает!

function versionCompare( version1, version2 ){
    var len1 = listLen(arguments.version1, '.');
    var len2 = listLen(arguments.version2, '.');
    var i = 0;
    var piece1 = '';
    var piece2 = '';

    if (len1 gt len2){
        arguments.version2 = arguments.version2 & repeatString('.0', len1-len2);
    }else if (len2 gt len1){
        arguments.version1 = arguments.version1 & repeatString('.0', len2-len1);
    }

    for (i=1; i lte listLen(arguments.version1, '.'); i=i+1){
        piece1 = listGetAt(arguments.version1, i, '.');
        piece2 = listGetAt(arguments.version2, i, '.');

        if (piece1 neq piece2){
            if (piece1 gt piece2){
                return 1;
            }else{
                return -1;
            }
        }
    }

    //equal
    return 0;
}

Выполнение вашего примера теста:

<cfoutput>#versionCompare('4.7', '4.2.2')#</cfoutput>

выводит:

1

6
ответ дан 6 December 2019 в 23:04
поделиться

Если версия 4 на самом деле означает 4.0.0, а версия 4.2 на самом деле означает 4.2.0, вы можете легко преобразовать версию в простое целое число.

предположим, что каждая часть версии находится в диапазоне от 0 до 99, тогда вы можете вычислить «целочисленную версию» из XYZ следующим образом:

Version = X*100*100 + Y*100 + Z

Если диапазоны больше или меньше, вы можете использовать коэффициенты выше или ниже 100.

Сравнивать версии становится легко.

3
ответ дан 6 December 2019 в 23:04
поделиться

Разберите каждое число отдельно и сравните их итеративно.

if (majorVersion > 4 &&
    minorVersion > 2 &&
    revision > 2)
{
    // do something useful
}

// fail here

Это явно не код CF, но вы поняли идею.

1
ответ дан 6 December 2019 в 23:04
поделиться

Номер версии в основном разделен точкой массив чисел, поэтому вы можете проанализировать обе версии в числовые массивы, а затем сравнить каждый элемент в первом массиве с соответствующим элементом во втором массиве.

Чтобы получить массив, выполните:

<cfset theArrayofNumbers = listToArray(yourVersionString, ".")>

, а затем вы можете провести сравнение.

1
ответ дан 6 December 2019 в 23:04
поделиться

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

Боюсь, я никогда не писал на coldfusion, но это была бы основная логика, которой я бы следовал.

Это грубый неоптимизированный пример:

bool IsGreater(string one, string two)
{
  int count;
  string[] v1;
  string[] v2;

  v1 = one.Split(".");
  v2 = two.Split(".");

  count = (one.Length > two.Length) ? one.Length : two.Length;

  for (int x=0;x<count;x++)
  {
     if (Convert.ToInt32(v1[x]) < Convert.ToInt32(v2[x]))
        return false;
     else if (Convert.ToInt32(v1[x]) > Convert.ToInt32(v2[x])
        return true;
  } // If they are the same it'll go to the next block.

  // If you're here, they both were equal for the shortest version's digit count.
  if (v1.Length > v2.Length)
     return true; // The first one has additional subversions so it's greater.
}
0
ответ дан 6 December 2019 в 23:04
поделиться

Не существует общего способа преобразования номеров версий, состоящих из нескольких частей, в действительные числа, если нет ограничений на размер каждой части (например, 4.702. 0> 4.7.2?).

Обычно вы определяете пользовательскую функцию сравнения, создавая последовательность или массив компонентов с номером версии или компонентов , поэтому 4.7.2 представлен как [4, 7, 2 ] и 4.702.0 равно [4, 702, 0]. Затем вы сравниваете каждый элемент двух массивов до тех пор, пока они не совпадут:

left = [4, 7, 2]
right = [4, 702, 0]

# check index 0
# left[0] == 4, right[0] == 4
left[0] == right[0]
# equal so far

# check index 1
# left[1] == 7, right[1] == 702
left[1] < right[1]
# so left < right

Я не знаю о ColdFusion, но на некоторых языках вы можете проводить прямое сравнение с массивами или последовательностями. Например, в Python:

>>> left = [4, 7, 2]
>>> right = [4, 702, 0]
>>> left < right
True
0
ответ дан 6 December 2019 в 23:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: