Получить верхние значения x (независимо от знака) из списка со знаком, используя TCL или sqlite - PullRequest
1 голос
/ 11 октября 2019

Имея список с положительными и отрицательными числами, цель - получить верхние значения x, основанные на значении abs чисел, но со знаком. например,

set Input [list -3122.0 -1618.0 -1551.0 -894.2 296.4 2226.0 1855.0 1318.0 872.5 2004.0 2026.0 2828.0 ]

Вывод должен быть (при запросе только первых 10):

Output [ list -3122.0 2828.0 2226.0 2026.0 2004.0 1855.0 -1618.0 -1551.0 1318.0 -894.2 ]

Я использую следующий код,

set ForceIDsPosetiv [ DB eval {  SELECT Forcec FROM MaxForces WHERE Force > 0} ]
set ForceIDsNegativ [ DB eval {  SELECT Forcec FROM MaxForces WHERE Force < 0} ]
set ForceIDsPosetiv [lsort -decreasing -real $ForceIDsPosetiv]
set ForceIDsNegativ [lsort -increasing -real $ForceIDsNegativ]
set SortedForcList ""

for {set row 0 } { $row <= 9   } {incr row} {
    set firstForcePos [lindex $ForceIDsPosetiv 0]
    set firstForceNeg [lindex $ForceIDsNegativ 0]
    if { $firstForcePos == "" }  {
        lappend SortedForcList $firstForceNeg
        set ForceIDsNegativ [lreplace $ForceIDsNegativ 0 0]
    } else {
        if { $firstForceNeg == "" }  {
            lappend SortedForcList $firstForcePos
            set ForceIDsPosetiv [lreplace $ForceIDsPosetiv 0 0]
        } else {
            if { abs($firstForcePos) > abs($firstForceNeg)  }  {
                lappend SortedForcList $firstForcePos
                set ForceIDsPosetiv [lreplace $ForceIDsPosetiv 0 0]
            } else {
                lappend SortedForcList $firstForceNeg
                set ForceIDsNegativ [lreplace $ForceIDsNegativ 0 0]
            }
        }
    } 
}

, но у меня естьощущение, что есть гораздо более эффективный способ решить эту проблему. У Вас есть какие-то предложения? Как вы можете видеть, я использую sqlite db в начале. В таблице есть только один столбец со всеми силами. Таким образом, решение с использованием sqlite также будет оценено.

1 Ответ

4 голосов
/ 11 октября 2019

Я не знаю о TCL, но запрос SQL будет выглядеть примерно так:

SELECT Forcec
FROM Maxforces
ORDER BY abs(Forcec) DESC
LIMIT 10

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


Редактировать: Теперь я знаю о TCL:

set Input [list -3122.0 -1618.0 -1551.0 -894.2 296.4 2226.0 1855.0 1318.0 872.5 2004.0 2026.0 2828.0 ]
proc abscomp {a b} {
  set a [::tcl::mathfunc::abs $a]
  set b [::tcl::mathfunc::abs $b]
  if {$a < $b} {
    return -1
  } elseif { $a > $b } {
    return 1
  } else {
    return 0
  }
}
set Output [lrange [lsort -decreasing -command abscomp $Input] 0 9]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...