按顺序更改数组中的值
Change value in array in order
我需要更改最大值才能订购。首先是最大值和最大值 - 1。(100, 99, 100) 必须等于 1。它将是 [5, 55, 1 , 2, 1, 1, 98]。然后我需要将 (98) 更改为 2,因为现在 98 是数组中的最大值。
我的目标是 [4, 3, 1, 5, 1, 1, 2]。我尝试了第一步并收到了这个
var arr = [5, 55, 100, 2, 99, 100, 98]
func toOrder(_ arr: [Int]) -> [Int] {
var arr = arr
var max = arr.max()!
var order = 1
for i in arr.indices {
if arr[i] == max || arr[i] == max - 1 {
arr[i] = order
}
}
return arr
}
toOrder(arr)
我卡住了。我收到 [5, 55, 1, 2, 1, 1, 98],但我怎样才能继续使用保存的值遍历数组?
如果我没看错你的逻辑(因为你给了个例子,答案好像不太对,后面再说):
我会使用递归方法。
- 找到最大的“未处理”值(否则,例如,一旦您有了最终输出,它将一遍又一遍地迭代),如果找不到则停止。
- 更新数组以获得等于最大值或等于最大值 - 1 的值。
- 重做
func iterates(items: inout [Item], iteration: Int = 0) {
let maxValue = items.filter { ![=10=].hasBeenTreated }.max(by: { [=10=].value < .value })
print("maxValue found: \(maxValue)")
guard let maxValue = maxValue else { return } //Check if there are still value max non treated, else, it ends here
let newItems = items.map { anItem -> Item in
if anItem.hasBeenTreated == false && (anItem.value == maxValue.value || anItem.value == maxValue.value - 1) {
return Item(value: iteration + 1, hasBeenTreated: true)
} else {
return anItem
}
}
print("NewItems: \(newItems)")
items = newItems
iterates(items: &items, iteration: iteration + 1)
}
借助于:
struct Item: CustomStringConvertible {
var value: Int
var hasBeenTreated: Bool
var description: String {
return "\(value) (\(hasBeenTreated))"
}
}
测试一下:
var itemsToTest1 = [5, 55, 100, 2, 99, 100, 98].map { Item(value: [=12=], hasBeenTreated: false) }
iterates(items: &itemsToTest1)
print("Output Items1: \(itemsToTest1)")
print("Output Array1: \(itemsToTest1.map({ [=12=].value }))")
var itemsToTest2 = [1, 2, 3, 4, 5, 6, 7, 8, 9].map { Item(value: [=12=], hasBeenTreated: false) }
iterates(items: &itemsToTest2)
print("Output Items2: \(itemsToTest2)")
print("Output Array2: \(itemsToTest2.map({ [=12=].value }))")
输出仅用于调试,但您可以看到计算的进展:
maxValue found: Optional(100 (false))
NewItems: [5 (false), 55 (false), 1 (true), 2 (false), 1 (true), 1 (true), 98 (false)]
maxValue found: Optional(98 (false))
NewItems: [5 (false), 55 (false), 1 (true), 2 (false), 1 (true), 1 (true), 2 (true)]
maxValue found: Optional(55 (false))
NewItems: [5 (false), 3 (true), 1 (true), 2 (false), 1 (true), 1 (true), 2 (true)]
maxValue found: Optional(5 (false))
NewItems: [4 (true), 3 (true), 1 (true), 2 (false), 1 (true), 1 (true), 2 (true)]
maxValue found: Optional(2 (false))
NewItems: [4 (true), 3 (true), 1 (true), 5 (true), 1 (true), 1 (true), 2 (true)]
maxValue found: nil
Output Items1: [4 (true), 3 (true), 1 (true), 5 (true), 1 (true), 1 (true), 2 (true)]
Output Array1: [4, 3, 1, 5, 1, 1, 2]
maxValue found: Optional(9 (false))
NewItems: [1 (false), 2 (false), 3 (false), 4 (false), 5 (false), 6 (false), 7 (false), 1 (true), 1 (true)]
maxValue found: Optional(7 (false))
NewItems: [1 (false), 2 (false), 3 (false), 4 (false), 5 (false), 2 (true), 2 (true), 1 (true), 1 (true)]
maxValue found: Optional(5 (false))
NewItems: [1 (false), 2 (false), 3 (false), 3 (true), 3 (true), 2 (true), 2 (true), 1 (true), 1 (true)]
maxValue found: Optional(3 (false))
NewItems: [1 (false), 4 (true), 4 (true), 3 (true), 3 (true), 2 (true), 2 (true), 1 (true), 1 (true)]
maxValue found: Optional(1 (false))
NewItems: [5 (true), 4 (true), 4 (true), 3 (true), 3 (true), 2 (true), 2 (true), 1 (true), 1 (true)]
maxValue found: nil
Output Items2: [5 (true), 4 (true), 4 (true), 3 (true), 3 (true), 2 (true), 2 (true), 1 (true), 1 (true)]
Output Array2: [5, 4, 4, 3, 3, 2, 2, 1, 1]
现在,继续评论中给出的最后一个示例(已删除的答案):
[1, 2, 3, 4, 5, 6, 7, 8, 9]
应该产生 `[ 5, 5, 4, 4, 3, 3, 2, 2, 1, 1],但我不同意。
迭代应该是:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 1, 1]
[1, 2, 3, 4, 5, 2, 2, 1, 1]
[1, 2, 3, 3, 3, 2, 2, 1, 1]
[1, 4, 4, 3, 3, 2, 2, 1, 1]
[5, 4, 4, 3, 3, 2, 2, 1, 1] (with only one 5 value at start)
我不知道你应该怎么称呼它。
extension Sequence
where Element: AdditiveArithmetic & Comparable & ExpressibleByIntegerLiteral & Hashable {
var : [Int] {
var dictionary: [Element: Int] = [:]
func value(for element: Element) -> Int? {
dictionary[element] ?? dictionary[element + 1]
}
_ = sorted().reversed().reduce(into: 0) { highestValue, element in
if value(for: element) == nil {
highestValue += 1
dictionary[element] = highestValue
}
}
return map(value) as! _
}
}
首先用索引压缩集合元素,然后按元素降序排列。
创建 rank 和 maxValue 变量。
创建一个元素数量完全相同的数组来存储结果。
迭代元素和索引。
如果元素小于 maxValue 减一增加 rank 值,更新 maxValue 并将 rank 存储在结果数组中原始元素的相应位置:
let arr = [5, 55, 100, 2, 99, 100, 98]
let indexedElements = zip(arr.indices, arr).sorted(by: { [=10=].1 > .1 })
var rank = 1
var maxValue = indexedElements.first?.1 ?? .max
var result = Array(repeating: 0, count: arr.count)
for index in indexedElements.indices {
let element = indexedElements[index].1
if element < maxValue - 1 {
rank += 1
maxValue = element
}
result[indexedElements[index].0] = rank
}
print(result) // "[4, 3, 1, 5, 1, 1, 2]\n"
我需要更改最大值才能订购。首先是最大值和最大值 - 1。(100, 99, 100) 必须等于 1。它将是 [5, 55, 1 , 2, 1, 1, 98]。然后我需要将 (98) 更改为 2,因为现在 98 是数组中的最大值。 我的目标是 [4, 3, 1, 5, 1, 1, 2]。我尝试了第一步并收到了这个
var arr = [5, 55, 100, 2, 99, 100, 98]
func toOrder(_ arr: [Int]) -> [Int] {
var arr = arr
var max = arr.max()!
var order = 1
for i in arr.indices {
if arr[i] == max || arr[i] == max - 1 {
arr[i] = order
}
}
return arr
}
toOrder(arr)
我卡住了。我收到 [5, 55, 1, 2, 1, 1, 98],但我怎样才能继续使用保存的值遍历数组?
如果我没看错你的逻辑(因为你给了个例子,答案好像不太对,后面再说):
我会使用递归方法。
- 找到最大的“未处理”值(否则,例如,一旦您有了最终输出,它将一遍又一遍地迭代),如果找不到则停止。
- 更新数组以获得等于最大值或等于最大值 - 1 的值。
- 重做
func iterates(items: inout [Item], iteration: Int = 0) {
let maxValue = items.filter { ![=10=].hasBeenTreated }.max(by: { [=10=].value < .value })
print("maxValue found: \(maxValue)")
guard let maxValue = maxValue else { return } //Check if there are still value max non treated, else, it ends here
let newItems = items.map { anItem -> Item in
if anItem.hasBeenTreated == false && (anItem.value == maxValue.value || anItem.value == maxValue.value - 1) {
return Item(value: iteration + 1, hasBeenTreated: true)
} else {
return anItem
}
}
print("NewItems: \(newItems)")
items = newItems
iterates(items: &items, iteration: iteration + 1)
}
借助于:
struct Item: CustomStringConvertible {
var value: Int
var hasBeenTreated: Bool
var description: String {
return "\(value) (\(hasBeenTreated))"
}
}
测试一下:
var itemsToTest1 = [5, 55, 100, 2, 99, 100, 98].map { Item(value: [=12=], hasBeenTreated: false) }
iterates(items: &itemsToTest1)
print("Output Items1: \(itemsToTest1)")
print("Output Array1: \(itemsToTest1.map({ [=12=].value }))")
var itemsToTest2 = [1, 2, 3, 4, 5, 6, 7, 8, 9].map { Item(value: [=12=], hasBeenTreated: false) }
iterates(items: &itemsToTest2)
print("Output Items2: \(itemsToTest2)")
print("Output Array2: \(itemsToTest2.map({ [=12=].value }))")
输出仅用于调试,但您可以看到计算的进展:
maxValue found: Optional(100 (false))
NewItems: [5 (false), 55 (false), 1 (true), 2 (false), 1 (true), 1 (true), 98 (false)]
maxValue found: Optional(98 (false))
NewItems: [5 (false), 55 (false), 1 (true), 2 (false), 1 (true), 1 (true), 2 (true)]
maxValue found: Optional(55 (false))
NewItems: [5 (false), 3 (true), 1 (true), 2 (false), 1 (true), 1 (true), 2 (true)]
maxValue found: Optional(5 (false))
NewItems: [4 (true), 3 (true), 1 (true), 2 (false), 1 (true), 1 (true), 2 (true)]
maxValue found: Optional(2 (false))
NewItems: [4 (true), 3 (true), 1 (true), 5 (true), 1 (true), 1 (true), 2 (true)]
maxValue found: nil
Output Items1: [4 (true), 3 (true), 1 (true), 5 (true), 1 (true), 1 (true), 2 (true)]
Output Array1: [4, 3, 1, 5, 1, 1, 2]
maxValue found: Optional(9 (false))
NewItems: [1 (false), 2 (false), 3 (false), 4 (false), 5 (false), 6 (false), 7 (false), 1 (true), 1 (true)]
maxValue found: Optional(7 (false))
NewItems: [1 (false), 2 (false), 3 (false), 4 (false), 5 (false), 2 (true), 2 (true), 1 (true), 1 (true)]
maxValue found: Optional(5 (false))
NewItems: [1 (false), 2 (false), 3 (false), 3 (true), 3 (true), 2 (true), 2 (true), 1 (true), 1 (true)]
maxValue found: Optional(3 (false))
NewItems: [1 (false), 4 (true), 4 (true), 3 (true), 3 (true), 2 (true), 2 (true), 1 (true), 1 (true)]
maxValue found: Optional(1 (false))
NewItems: [5 (true), 4 (true), 4 (true), 3 (true), 3 (true), 2 (true), 2 (true), 1 (true), 1 (true)]
maxValue found: nil
Output Items2: [5 (true), 4 (true), 4 (true), 3 (true), 3 (true), 2 (true), 2 (true), 1 (true), 1 (true)]
Output Array2: [5, 4, 4, 3, 3, 2, 2, 1, 1]
现在,继续评论中给出的最后一个示例(已删除的答案):
[1, 2, 3, 4, 5, 6, 7, 8, 9]
应该产生 `[ 5, 5, 4, 4, 3, 3, 2, 2, 1, 1],但我不同意。
迭代应该是:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 1, 1]
[1, 2, 3, 4, 5, 2, 2, 1, 1]
[1, 2, 3, 3, 3, 2, 2, 1, 1]
[1, 4, 4, 3, 3, 2, 2, 1, 1]
[5, 4, 4, 3, 3, 2, 2, 1, 1] (with only one 5 value at start)
我不知道你应该怎么称呼它。
extension Sequence
where Element: AdditiveArithmetic & Comparable & ExpressibleByIntegerLiteral & Hashable {
var : [Int] {
var dictionary: [Element: Int] = [:]
func value(for element: Element) -> Int? {
dictionary[element] ?? dictionary[element + 1]
}
_ = sorted().reversed().reduce(into: 0) { highestValue, element in
if value(for: element) == nil {
highestValue += 1
dictionary[element] = highestValue
}
}
return map(value) as! _
}
}
首先用索引压缩集合元素,然后按元素降序排列。
创建 rank 和 maxValue 变量。
创建一个元素数量完全相同的数组来存储结果。
迭代元素和索引。
如果元素小于 maxValue 减一增加 rank 值,更新 maxValue 并将 rank 存储在结果数组中原始元素的相应位置:
let arr = [5, 55, 100, 2, 99, 100, 98]
let indexedElements = zip(arr.indices, arr).sorted(by: { [=10=].1 > .1 })
var rank = 1
var maxValue = indexedElements.first?.1 ?? .max
var result = Array(repeating: 0, count: arr.count)
for index in indexedElements.indices {
let element = indexedElements[index].1
if element < maxValue - 1 {
rank += 1
maxValue = element
}
result[indexedElements[index].0] = rank
}
print(result) // "[4, 3, 1, 5, 1, 1, 2]\n"