【问题标题】:Check whether integers in array are consecutive or in sequence检查数组中的整数是连续的还是顺序的
【发布时间】:2017-10-14 01:14:46
【问题描述】:

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

例如:

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

目前我实现的是元素的差异,如果差异为 1,那么我说它是连续的。

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

【问题讨论】:

  • 你的意思是说要看看它们是不是升序排列的?
  • 只做一个循环检查下一个元素是否是当前元素+1
  • array == array.sorted()?
  • 或者只检查每两个元素 a <= b 是否成立。
  • “按顺序”究竟是什么意思?是按递增顺序还是连续递增整数? [1, 3, 7] 算不算“按顺序”?

标签: arrays swift


【解决方案1】:

给定你的数组

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

你可以使用一些函数式编程魔法

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

【讨论】:

    【解决方案2】:

    如果这是一次性问题,那么任何小的 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()) 没有在任意序列上定义。您可能只被允许对一个序列进行一次迭代。不幸的是,没有办法知道;它在文档中被认为是“关于序列的特殊知识”。呜呜。我想念 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)
            }
        }
    }
    

    这样,我们可以在 Sequence 上构建它:

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

    【讨论】:

    • 次要评论:我会把first(where: { !predicate($0)}) == nil写成!contains(where: { !predicate($0)})——但这可能是个人喜好问题。
    • 是的;那更好。谢谢。
    【解决方案3】:

    "目前我实现的是对元素进行差异化,如果 差异是1 然后我说它是按顺序排列的。”

    根据您上面的陈述,您似乎想要,对于一个整数数组,查看所有成员是否连续

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

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

    【讨论】:

      【解决方案4】:

      如果序列是预期的,它会返回真,否则它会返回假

      它有两个检查

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

      【讨论】:

      • 如果您也解释,您的回答会更有帮助。顺便说一句,isSeq([4,4,7,7],sequence:1) 返回什么?
      猜你喜欢
      • 2013-04-27
      • 1970-01-01
      • 2018-12-20
      • 1970-01-01
      • 1970-01-01
      • 2011-06-23
      • 2019-11-03
      • 2018-09-23
      • 1970-01-01
      相关资源
      最近更新 更多