在CMake中以数字方式对数字列表进行排序

里克·德·沃特

我有一个包含版本号列表的变量:

1.1;10.0;11.0;12.0;12.1;2.0;2.1;3.0;3.1;3.2;4.0;4.1;5.0;5.1;5.2;6.0;6.1;6.2;6.3;7.0;8.0;9.0

如您所见,该列表按字母顺序排序。我希望列表按数字排序:

1.1;2.0;2.1;3.0;3.1;3.2;4.0;4.1;5.0;5.1;5.2;6.0;6.1;6.2;6.3;7.0;8.0;9.0;10.0;11.0;12.0;12.1

在CMake中有一种简单的方法吗?

九柱游戏

编辑:从CMake 3.18开始,内置功能可以对数字进行数字排序。您可以将list(SORT ...)命令与命令一起使用NATURAL

set(sort_list 1.1;10.0;11.0;12.0;12.1;2.0;2.1;3.0;3.1;3.2;4.0;4.1;5.0;5.1;5.2;6.0;6.1;6.2;6.3;7.0;8.0;9.0)
list(SORT sort_list COMPARE NATURAL)

对列表进行数字排序。


对于CMake 3.17及更低版本,没有内置的数字排序,因此您必须编写自己的数字排序。这是我刚刚根据此处描述的递归插入排序算法写的一个

function(insertionSortRecursive sort_list len)
  # Base case, return.
  if(${len} LESS_EQUAL 1)
    return()
  endif()

  math(EXPR len_minus_one "${len} - 1")
  # Recursively sort the sublist of size (len - 1).
  insertionSortRecursive("${sort_list}" ${len_minus_one})
  set(_sort_list ${sort_list})

  # Get the last element in the sublist.
  list(GET _sort_list ${len_minus_one} last_element)
  # Define a counter for the sublist we will operate on.
  math(EXPR sublist_counter "${len} - 2")
  # Get the element at the counter index.
  list(GET _sort_list ${sublist_counter} counter_element)

  # Loop to move those elements greater than last_element up one position.
  while((${sublist_counter} GREATER_EQUAL 0) AND (${counter_element} GREATER ${last_element}))
    # Move elem at counter index up one position in list.
    math(EXPR counter_plus_one "${sublist_counter} + 1")
    list(REMOVE_AT _sort_list ${counter_plus_one})
    list(INSERT _sort_list ${counter_plus_one} ${counter_element})
    # Decrement the sublist counter.
    math(EXPR sublist_counter "${sublist_counter} - 1")
    # Get the element at the new counter value.
    list(GET _sort_list ${sublist_counter} counter_element)
  endwhile()

  # Place the last element at the correct position.
  math(EXPR counter_plus_one "${sublist_counter} + 1")
  list(REMOVE_AT _sort_list ${counter_plus_one})
  list(INSERT _sort_list ${counter_plus_one} ${last_element})
  # Send the modified list back up to parent scope.
  set(sort_list ${_sort_list} PARENT_SCOPE)    
endfunction()

只需将未排序的列表传递给此insertionSortRecursive()CMake函数即可对其进行排序:

set(sort_list 1.1;10.0;11.0;12.0;12.1;2.0;2.1;3.0;3.1;3.2;4.0;4.1;5.0;5.1;5.2;6.0;6.1;6.2;6.3;7.0;8.0;9.0)
message("Unsorted: ${sort_list}")

# Get the list length
list(LENGTH sort_list LIST_LEN)
# Call the recursive sort function.
insertionSortRecursive("${sort_list}" ${LIST_LEN})

message("Sorted:   ${sort_list}")

这将打印以下内容,验证列表是否已排序:

Unsorted: 1.1;10.0;11.0;12.0;12.1;2.0;2.1;3.0;3.1;3.2;4.0;4.1;5.0;5.1;5.2;6.0;6.1;6.2;6.3;7.0;8.0;9.0
Sorted:   1.1;2.0;2.1;3.0;3.1;3.2;4.0;4.1;5.0;5.1;5.2;6.0;6.1;6.2;6.3;7.0;8.0;9.0;10.0;11.0;12.0;12.1

CMake中还有其他一些数字排序实现,例如Insertion SortBubble Bubble

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章