按软件版本排序/排序 - 算法/实现

发布于 2024-12-12 07:55:18 字数 405 浏览 0 评论 0原文

我正在寻找一种方法来对定义软件版本的一组字符串进行排序/排序,格式如下:xxx(例如:1.3.12)。

这些字符串位于数据库(mysql)中,但我不确定这是否相关。

我能想到的一个想法是进行字符串 -> 整数(或浮点)转换,然后按整数索引对集合进行排序。但是我不确定这是否可能。

我也在寻找其他想法。

谢谢

更新:我只是想设置一个代表我可以实现的最大版本的数字(我所说的版本是指主要版本,次要版本,修订版)。例如我选择数字 300 ,所以最大版本将为 299.299.299 所以..当我转换时,我可以这样做:major*pow(300,2)+minor*pow(300,1)+revision*pow(300,0)

仍然对想法持开放态度.

I'm looking for a way to order/sort a set of strings that define software versions, in the following format: x.x.x (e.g.: 1.3.12).

Those strings are in an database(mysql) , but I'm not sure if this is even relevant.

One idea I can think of is to make a String ->integer(or float) conversion and than sort the set by the integer index. However I'm not sure if this is possible.

Also I'm looking for other ideas.

Thanks

UPDATE: I just thought about setting a number which represents the maximum version I could implement(and by version I mean major version,minor version, revision). for example I choose the number 300 , so the maximum version will be 299.299.299
so.. when I convert I can do something like this: major*pow(300,2)+minor*pow(300,1)+revision*pow(300,0)

Still opened to ideas.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

洛阳烟雨空心柳 2024-12-19 07:55:18

不要使用多点字符串作为字符串 - 比较它的值时您会非常头疼

在您的情况下,您可以(必须?)将版本扩展为 4 个八位字节字符串(尾随 0)并使用 IP4 相关函数(从前端或内置 MySQL)

来自 MySQL 手册

INET_ATON(表达式)

将 IPv4 网络地址的点分四组表示形式
字符串,返回一个整数,表示该数值
网络字节顺序(大端)的地址。 INET_ATON() 返回 NULL
如果它不理解它的论点。

mysql>选择 INET_ATON('10.0.5.9');
-> 167773449

对于本例,返回值计算为 10×2563 + 0×2562 +
5×256 + 9。

对于短格式 IP,INET_ATON() 可能会也可能不会返回非 NULL 结果
地址(例如“127.1”代表“127.0.0.1”)。
因此,INET_ATON()a 不应用于此类地址。

注意:

要存储 INET_ATON() 生成的值,请使用 INT UNSIGNED 列
而不是 INT,它是有符号的。如果您使用有符号列,则值
对应于第一个八位字节较大的 IP 地址
超过 127 无法正确存储。请参见第 10.6 节“超出范围”
和溢出处理”。

INET_NTOA(表达式)

给定一个按网络字节顺序排列的数字 IPv4 网络地址,返回
地址的点分四元表示形式为二进制字符串。
如果 INET_NTOA() 不理解其参数,则返回 NULL。

Don't use multidotted strings as strings - you'll have big headache on compare it's value

In your case you can (must?) expand version to 4-octets string (with trailing 0) and use IP4-related functions (from frontend or built-in MySQL)

From MySQL manual

INET_ATON(expr)

Given the dotted-quad representation of an IPv4 network address as a
string, returns an integer that represents the numeric value of the
address in network byte order (big endian). INET_ATON() returns NULL
if it does not understand its argument.

mysql> SELECT INET_ATON('10.0.5.9');
-> 167773449

For this example, the return value is calculated as 10×2563 + 0×2562 +
5×256 + 9.

INET_ATON() may or may not return a non-NULL result for short-form IP
addresses (such as '127.1' as a representation of '127.0.0.1').
Because of this, INET_ATON()a should not be used for such addresses.

Note:

To store values generated by INET_ATON(), use an INT UNSIGNED column
rather than INT, which is signed. If you use a signed column, values
corresponding to IP addresses for which the first octet is greater
than 127 cannot be stored correctly. See Section 10.6, “Out-of-Range
and Overflow Handling”.

INET_NTOA(expr)

Given a numeric IPv4 network address in network byte order, returns
the dotted-quad representation of the address as a binary string.
INET_NTOA() returns NULL if it does not understand its argument.

蓝天 2024-12-19 07:55:18

我只能给出没有语言的伪代码,但是......在 mysql 中使用 SUBSTRING_INDEX() 或另一种语言中的类似函数来使用 .作为分隔符。然后使用一组嵌套的 if..then 条件来比较字符串,例如

if(substr1<substr2) return str2;
elseif(subrtr1>substr2) return str1;
elseif(substr1 = substr2)
  if(substr1b<substr2b) return str2;
  elseif(subrtr1b>substr2b) return str1;
  elseif(substr1b = substr2b)

等......

堆是另一种方法。将比较定义为compare() 函数。然后添加值并让堆对它们进行排序。

I can only give pseudocode without a language, but... Use SUBSTRING_INDEX() in mysql or a similar function in another language to break the string up using the . for a delimiter. Then use a set of nested if..then conditionals to compare the strings like

if(substr1<substr2) return str2;
elseif(subrtr1>substr2) return str1;
elseif(substr1 = substr2)
  if(substr1b<substr2b) return str2;
  elseif(subrtr1b>substr2b) return str1;
  elseif(substr1b = substr2b)

etc....

A heap is another way to do it. Define the comparison as the compare() function. then add the values and let the heap sort them.

野生奥特曼 2024-12-19 07:55:18

遇到同样的问题,我最终针对类似情况提供了以下解决方案:

select *
from Softwareedition
order by Softwareedition.IsMostRecentVersion DESC,
INET_ATON(
    CASE (LENGTH(Softwareedition.VersionNumber) - LENGTH(REPLACE(Softwareedition.VersionNumber, ".", "")))
        WHEN 1 then concat(Softwareedition.VersionNumber,".0.0")
        WHEN 2 then concat(Softwareedition.VersionNumber,".0")
        ELSE Softwareedition.VersionNumber
    END) DESC,
Softwareedition.Name DESC

Having the same problem I end up with the following solution for the similar case:

select *
from Softwareedition
order by Softwareedition.IsMostRecentVersion DESC,
INET_ATON(
    CASE (LENGTH(Softwareedition.VersionNumber) - LENGTH(REPLACE(Softwareedition.VersionNumber, ".", "")))
        WHEN 1 then concat(Softwareedition.VersionNumber,".0.0")
        WHEN 2 then concat(Softwareedition.VersionNumber,".0")
        ELSE Softwareedition.VersionNumber
    END) DESC,
Softwareedition.Name DESC
被翻牌 2024-12-19 07:55:18

您可以将这些值存储为 VARCHAR 或 CHAR,然后只需在查询末尾添加 ORDER BY ... DESC 即可在顶部获取最新版本,或者省略 DESC 部分(MySQL 默认为 ASC)以获得最早的版本版本在顶部

伪代码:

SELECT * FROM Table WHERE xxx ORDER BY Version DESC

You can store those values as VARCHAR or CHAR then just add an ORDER BY ... DESC to the end of your query to get the latest version at the top or leave off the DESC part (MySQL defaults to ASC anyway) to get the earliest version at the top

Pseudo code:

SELECT * FROM Table WHERE xxx ORDER BY Version DESC
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文