#arrays #swift
#массивы #swift
Вопрос:
Мне нужно найти пары в массиве, я хотел сделать это, сравнив arr [i] с другими, начинающимися с arr [i 1], поэтому я не буду проверять одно и то же значение дважды, но я не могу этого добиться. Вот что я пробовал
func findPairs(_ ar: [Int]) -> Int {
var pairs = 0
for i in 0..<ar.count {
var k = i 1
for k in 0..<ar.count {
if ar[i] == ar[k] {
pairs = 1
}
}
}
return pairs/2
}
Упд
чтобы уточнить, в примере, который у меня есть, это было дано как в массиве [1,2,3,1,2,3,4,5,1] у нас есть 3 пары [1,1] [2,2] [3,3]
Комментарии:
1. Этот вопрос требует дополнительных разъяснений относительно того, как определяются пары и как может выглядеть входной массив (гарантированно ли он содержит только одиночные или парные элементы или может содержать триплеты или больше).
Ответ №1:
Вероятно, вам нужно использовать i 1
в качестве начального индекса в вашем внутреннем цикле, вот так:
func findPairs(_ ar: [Int]) -> Int {
var pairs = 0
for i in 0..<ar.count {
let m = i 1
for k in m..<ar.count {
if ar[i] == ar[k] {
pairs = 1
}
}
}
return pairs
}
Кроме того, вы можете использовать другой массив для хранения индексов пар, чтобы не использовать тот же элемент для другой пары:
func findPairs(_ ar: [Int]) -> Int {
var pairs = 0
var pairIndexes = [Int]()
for i in 0..<ar.count where !pairIndexes.contains(i) {
let m = i 1
for k in m..<ar.count where !pairIndexes.contains(k) {
if ar[i] == ar[k] {
pairs = 1
pairIndexes.append(contentsOf: [i, k])
break
}
}
}
return pairs
}
Комментарии:
1. Это отчасти зависит от определения пары. Если я вызову вашу первую функцию с
findPairs([4, 4, 4, 4, 4])
, я получу ответ 10, который является правильным для одного определения. Или, может быть, ответ должен быть 2. Или 4, как вы получаете со своей 2-й функцией.2. @PhillipMills да, я согласен, чтобы уточнить, в примере, который у меня есть, это было приведено как в массиве [1,2,3,1,2,3,4,5,1] у нас есть 3 пары [1,1] [2,2] [3,3]
3. @gcharita Не совсем. Второй найдет 4 пары, сопоставив [1, 1] дважды. Я думаю, что правильный код должен будет удалить соответствующие элементы, прежде чем искать больше.
4. @gcharita так что даже с вводом [4, 4, 4, 4, 4] он возвращает 4, это то, о чем говорил pairs / 2 в моем примере кода, хотя в любом случае это не сработало хорошо…
5. @PhillipMills совершенно верно, я забыл
break
🙂 Ответ обновлен.
Ответ №2:
Функциональный подход состоял бы в том, чтобы получить общее количество вхождений элементов и суммировать половину из них:
func findPairs(_ ar: [Int]) -> Int {
ar.reduce(into: [Int:Int]()) { $0[$1, default: 0] = 1 }.values.reduce(0) { $0 $1/2 }
}
findPairs([1,2,3,1,2,3,4,5,1]) // 3
findPairs([4, 4, 4, 4, 4]) // 2
Или расширение коллекции, ограничивающей элементы хэшируемыми:
extension Collection where Element: Hashable {
var numberOfPairs: Int {
reduce(into: [Element:Int]()) { $0[$1, default: 0] = 1 }.values.reduce(0) { $0 $1/2 }
}
}
[1,2,3,1,2,3,4,5,1].numberOfPairs // 3
[4, 4, 4, 4, 4].numberOfPairs // 2
Ответ №3:
Я думаю, вам нужно только найти количество пар в массиве. Итак, для вас может сработать следующее:
func findPairs(_ ar: [Int]) -> Int {
var pairs = 0
for i in 0..<ar.count {
for k in (i 1)..<ar.count {
if ar[i] == ar[k] {
pairs = 1
break
}
}
}
return pairs
}