合并两个不同号码的牌组



我必须合并一组链,我有点卡住了,让我们以一副牌为例。假设我有两组数字:

deck1 = [1, 2]
deck2 = [1, 15, 2]

我想找到其中所有相等和不同的#并将其存储到一个新的套牌中,预期的结果是:

[1, 15, 2]

我关心数组的前一个顺序ex:[1, 2]但不关心新数组,所以新数组应该是[1,2,15]或[1,15,2]只有这两种情况

我创建了一个双循环:

var newDeck = []
for deck1 in deck1 {
for deck2 in deck2 {
if(deck1 == deck2) {
newDeck.append(deck1)
} else {

}
}
}

我知道如何做==部分,但我不确定其他部分。我想出的一个解决方案是在else中添加另一个循环(lol),然后我意识到我需要帮助。我怎么解决这个小难题呢?

感谢编辑:我现在想的另一个想法是将第一个循环的值添加到字典中,如果它不存在,那么添加它,但性能不会随之下降吗?

一种可能的方法是使用CollectionDifference获取差异并仅应用插入

let deck1 = [1, 2]
let deck2 = [1, 15, 2]
var result = deck2
let difference = deck1.difference(from: deck2)
for change in difference {
if case let .insert(offset, newElement, _) = change {
result.insert(newElement, at: offset)
}
}
print(result)

如果我理解了你没有完全解释的逻辑…

我认为逻辑是:
我们检查两个数组索引为0的元素,如果它还没有出现,我们将它们插入结果中。
检查两个数组中索引为1的元素,如果该元素不存在,则将其插入结果中。
检查两个数组中索引为2的元素,如果该元素不存在,则将其插入结果中。
等等…

但是正如评论中所说,我不确定,你没有完全解释它,你的样本可能会被误解,因为它们没有涵盖所有的情况(并且没有解释为什么某些值应该存在或不存在)。

所以,这两种方法都可以达到目的。我保留了Set版本来说明,因为它们没有副本,然后查找应该更快…

为了避免越界,我检查了较小的数组,并将最后的值保留在rest中。

func merge(deck1: [Int], deck2: [Int]) {
var valuesAlreadySaved: Set<Int> = Set()
var result: [Int] = []
var rest: [Int] = []
let min = min(deck1.count, deck2.count)
if deck1.count > min {
rest.append(contentsOf: deck1.dropFirst(min))
} else {
rest.append(contentsOf: deck2.dropFirst(min))
}
print("Rest: (rest)")
for index in 0..<min {
let value1 = deck1[index]
let value2 = deck2[index]
if !valuesAlreadySaved.contains(value1) {
result.append(value1)
valuesAlreadySaved.insert(value1)
}
if !valuesAlreadySaved.contains(value2) {
result.append(value2)
valuesAlreadySaved.insert(value2)
}
}
for aValue in rest {
if !valuesAlreadySaved.contains(aValue) {
result.append(aValue)
valuesAlreadySaved.insert(aValue)
}
}
print("Input: (deck1) - (deck2)")
print("Result: (result)")
}
merge(deck1: [1, 2], deck2: [1, 15, 2])
merge(deck1: [1, 3, 2], deck2: [1, 15, 2])
func mergeWithoutSet(deck1: [Int], deck2: [Int]) {
var result: [Int] = []
var rest: [Int] = []
let min = min(deck1.count, deck2.count)
if deck1.count > min {
rest.append(contentsOf: deck1.dropFirst(min))
} else {
rest.append(contentsOf: deck2.dropFirst(min))
}
print("Rest2: (rest)")
for index in 0..<min {
let value1 = deck1[index]
if !result.contains(value1) {
result.append(value1)
}
let value2 = deck2[index]
if !result.contains(value2) {
result.append(value2)
}
}
for aValue in rest {
if !result.contains(aValue) {
result.append(aValue)
}
}
print("Input2: (deck1) - (deck2)")
print("Result2: (result)")
}
mergeWithoutSet(deck1: [1, 2], deck2: [1, 15, 2])
mergeWithoutSet(deck1: [1, 3, 2], deck2: [1, 15, 2])

可以因式分解为:

func mergeWithoutSet2(deck1: [Int], deck2: [Int]) {
var result: [Int] = []
let min = min(deck1.count, deck2.count)
let rest = deck1.count > min ? deck1.dropFirst(min) : deck2.dropFirst(min)
print("Rest3: (rest)")
func appendIfNeeded(_ value: Int, to array: inout [Int]) {
guard !array.contains(value) else { return }
array.append(value)
}
for index in 0..<min {
appendIfNeeded(deck1[index], to: &result)
appendIfNeeded(deck2[index], to: &result)
}
for aValue in rest {
appendIfNeeded(aValue, to: &result)
}
print("Input3: (deck1) - (deck2)")
print("Result3: (result)")
}

第一种方法是对两个数组求和,然后使用contains函数检查新数组的值,消除冗余。

let deck1 = [1, 2]
let deck2 = [1, 15, 2]
var deck = deck1 + deck2
var newDeck = [Int]()
for i in deck {
if newDeck.contains(i) == false {
newDeck.append(i)
}
}
print(newDeck)

第二种方法是使用Set。将两个数组组合并将其转换为集合。该集合不允许冗余,因此重复的值将被自动删除。然后,把它改回原来的排列方式。

let deck1 = [1, 2]
let deck2 = [1, 15, 2]
var deck = deck1 + deck2
let newDeck: Set = Set(deck)
Array(newDeck)

最新更新