Как сравнить каждый элемент массива с другими элементами?

#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
}