检查数组中的整数是连续的还是按顺序排列的

时间:2017-08-02 19:13:18

标签: arrays swift

有没有最好的方法来检查数组中的元素是否按连续顺序排列?

例如:

[1,2,3,4,5] // returns true 
[1,2,4,3,5] // returns false

目前我实现的是采用不同的元素,如果差异是1,那么我说它是连续的顺序。

我正在寻找任何改进的方法。我想添加Array的扩展名,但不知道如何实现它。

4 个答案:

答案 0 :(得分:7)

给出你的阵列

let list = [1,2,3,4,5]

你可以使用一些功能编程魔术

let consecutives = list.map { $0 - 1 }.dropFirst() == list.dropLast()

答案 1 :(得分:3)

如果这是一次性问题,那么任何小的for循环都可以,但探索通用解决方案是一个有趣的问题。首先,我假设你的意思是每个元素必须比之前的元素大一个,而不仅仅是按顺序。

让我们构建一个通用的方法来回答“这个集合中的所有元素对都遵守一些规则”。首先,有一个通用的方式说“做所有事情”真的很好。

extension Sequence {
    func all(pass predicate: (Element) -> Bool) -> Bool {
        // If nothing is false, everything is true
        return !self.contains(where: { !predicate($0) })
    }
}

这将返回序列的所有元素是否遵循某个规则。

现在我们可以问一个问题:集合中所有成对元素都遵循一些规则:

extension Collection {
    func passesForConsecutiveValues(_ predicate:(Element, Element) -> Bool) -> Bool {
        return zip(self, dropFirst()).all(pass: predicate)
    }
}

zip(x, x.dropFirst()只是创造了“配对元素”,然后我们问“他们都满足我们的统治吗?”例如:

// Are all elements one more than their predecessor?
[1,2,4,5].passesForConsecutiveValues { $1 == $0 + 1 }  // true

现在您可能已经注意到我在中间从Sequence切换到Collection。为什么?因为zip(x, x.dropFirst())未在任意序列上定义。您可能只被允许迭代一次序列。不幸的是,没有办法知道;它被认为是文档中“关于序列的特殊知识”。的Bleh。我想念Scala的TraversableOnce vs. Sequence,将需求转移到类型中。

那就是说,我们绝对可以为Sequence构建这个。我们只需要构建zip(x, x.dropFirst())的替代品。我们将其称为pairwise,它将返回一个迭代器:

extension Sequence {
    func pairwise() -> AnyIterator<(Element, Element)> {
        var it = makeIterator()
        guard var last_value = it.next() else { return AnyIterator{ return nil } }

        return AnyIterator {
            guard let value = it.next() else { return nil }
            defer { last_value = value }
            return (last_value, value)
        }
    }
}

有了这个,我们可以在序列上构建它:

extension Sequence {
    func passesForConsecutiveValues(_ predicate:(Element, Element) -> Bool) -> Bool {
        return pairwise().all(pass: predicate)
    }
}

答案 2 :(得分:1)

  

“目前我实施的是采用不同的元素和if   diff是1然后我说它是按顺序的。“

根据您的上述陈述,对于整数数组,您似乎希望查看所有成员是否连续

您已经描述了此算法的逻辑:您可以实现它,例如使用for ... in ... where循环,只有where子句标识两个不连续顺序的后续元素时才会输入正文。 E.g:

extension Array where Element == Int {
    func numbersAreConsecutive() -> Bool {
        for (num, nextNum) in zip(self, dropFirst())
            where (nextNum - num) != 1 { return false }
        return true
    }
}

var arr = [1, 2, 3, 4, 5]
print(arr.numbersAreConsecutive()) // true

arr = [1, 2, 4, 5]
print(arr.numbersAreConsecutive()) // false

arr = [1]
print(arr.numbersAreConsecutive()) // true

arr = []
print(arr.numbersAreConsecutive()) // true

arr = [2, 1]
print(arr.numbersAreConsecutive()) // false

将扩展程序扩展为符合Integer的所有类型:

extension Array where Element: Integer {
    func numbersAreConsecutive() -> Bool {
        for (num, nextNum) in zip(self, dropFirst())
            where (nextNum - num) != 1 { return false }
        return true
    }
}

答案 3 :(得分:0)

如果序列是预期的,它将返回true,否则它将返回false

有两张支票

 1.Checking whether the array is sequence(Find the array is sequence)

    1.1 Sortedarray[0] + arraycount multiple with sequence (1,2,3, etc) and minus the sequence.
    1.2 compare the above calculated value with last value of sorted array. if it matche we could consider The array is sequence.

 2. Compare the source array and sorted array to confirm it is in order


 isSeq([4,5,6,7],sequence:1) **return True**
isSeq([100,102,104,106,108],sequence:2) **return True**
    isSeq([100,103,106,109,110],sequence:3) **return false**

    func isSeq(_ arrayValue:[Int],sequence:Int) ->Bool{

        let sortedValue = arrayValue.sorted()

        if(sortedValue[0] + (sortedValue.count * sequence) - sequence == sortedValue[sortedValue.count - 1]){
            if(arrayValue == sortedValue){
                return true
            }
        }

        return false;
    }