按顺序更改数组中的值

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"