我有一个问题要排序一些数字,这是首先是字符串。这个数字对于UInt64来说太大了,所以我将字符串数转换为float然后对其进行排序。这很好。但是我需要打印这些没有小数的数字。所以我试着格式化数字。但是更大的数字在格式化后会改变它的值。
这是要排序的输入数组 -
[" 6"" 31415926535897932384626433832795"" 1"" 3"" 10"" 3"" 5"]
我需要以这种格式打印输出 -
1
3
3
5
10
31415926535897932384626433832795
这是我在swift中的代码 -
import Foundation
var a = Array<Float>()
var b = ["6","31415926535897932384626433832795","1","3","10","3","5"]
a = b.map{ Float($0)! }
for i in 0..<(a.count-1){
var min = i
for j in (i+1)..<a.count{
if a[j] < a[min] {
min = j
}
}
var temp = a[i]
a[i] = a[min]
a[min] = temp
}
for val in a{
print(String(format: "%.0f",val.rounded(.down)))
}
我的输出是 -
1
3
3
5
6
10
31415927314585224784361549725696
如果您发现最后一个最大数字已从原始输入更改。我们欢迎所有的建议!谢谢!
答案 0 :(得分:4)
您可以使用数字比较:
let values = ["6","31415926535897932384626433832795","1","3","10","3","5"]
let sortedValues = values.sorted { (value1, value2) in
let order = value1.compare(value2, options: .numeric)
return order == .orderedAscending
}
print(sortedValues) // ["1", "3", "3", "5", "6", "10", "31415926535897932384626433832795"]
答案 1 :(得分:2)
使用float时,大整数之间的订单可能会产生意外结果:
var str = "Hello, playground"
let inArray = [
"6",
"31415926535897932384626433832797",
"31415926535897932384626433832796",
"31415926535897932384626433832795",
"1",
"3"
]
let outArray = inArray.sorted {Float($0)! < Float($1)!}
print(outArray)
//->["1", "3", "6", "31415926535897932384626433832797", "31415926535897932384626433832796", "31415926535897932384626433832795"]
正如mag_zbc的答案中所述,Float
只有大约7位有效数字,因此所有不太重要的数字都会丢失。
Float("31415926535897932384626433832797") == Float("31415926535897932384626433832795")
//->true
如果您的号码的数字最多为38,则可以使用Decimal
(同样在mag_zbc&#39的答案中建议)。
let outWithDecimal = inArray.sorted {Decimal(string: $0)! < Decimal(string: $1)!}
print(outWithDecimal)
//->["1", "3", "6", "31415926535897932384626433832795", "31415926535897932384626433832796", "31415926535897932384626433832797"]
否则,如果您的数据包含超过38位的数字,String
比较可以使用一些预处理:
(假设你的所有数字都是非负整数。)
extension String {
func fillZeroLeft(_ length: Int) -> String {
if self.characters.count < length {
return String.init(repeating: "0", count: length-self.characters.count) + self
} else {
return self
}
}
}
let maxLen = inArray.lazy.map{$0.characters.count}.max()!
let outWithString = inArray.sorted {$0.fillZeroLeft(maxLen) < $1.fillZeroLeft(maxLen)}
print(outWithString)
//->["1", "3", "6", "31415926535897932384626433832795", "31415926535897932384626433832796", "31415926535897932384626433832797"]
(但Sulthan的答案中的数字比较对我来说似乎更好!)
答案 2 :(得分:0)
在Swift中使用原始类型准确表示这么大的数字是不可能的。
你的价值是〜3e + 32
UInt64
的最大值为~18e + 18
Float
使用24位作为有效值,这允许准确地表示高达~1.6e + 8的数字
Double
使用53位作为有效值,这允许准确地表示高达~9e + 15
浮点类型(Float
和Double
)能够容纳更多的值,但是它们的精确度会高于其重要数据所能保持的数字。
除了使用一些外部库之外,我建议使用NSDecimalNumber
类,它应该能够容纳多达38个十进制数字 - 这对于你的例子中的数字来说已经足够了。但是,如果你需要更大的数字,那么你需要寻找一些外部库。