Ios 在Swift中有效地在阵列上生成连续且相同的编号
我在应用程序中有一个例子,它创建了一个数字pin模式,该模式不应该有一个连续的数字和相同的所有数字 被拒绝的引脚图案示例如下: 123456, 234567, 345678, 654321, 765432, 876543, 000000和其他类似的PIN模式Ios 在Swift中有效地在阵列上生成连续且相同的编号,ios,arrays,swift,algorithm,multidimensional-array,Ios,Arrays,Swift,Algorithm,Multidimensional Array,我在应用程序中有一个例子,它创建了一个数字pin模式,该模式不应该有一个连续的数字和相同的所有数字 被拒绝的引脚图案示例如下: 123456, 234567, 345678, 654321, 765432, 876543, 000000和其他类似的PIN模式 var rejectedPinList: [[Int]] = [[Int]]() var consecutiveNumber = [0,1,2,3,4,5,6,7,8,9,0] func incrementNumber(currentIn
var rejectedPinList: [[Int]] = [[Int]]()
var consecutiveNumber = [0,1,2,3,4,5,6,7,8,9,0]
func incrementNumber(currentIndex: Int) -> [Int] {
var rejectedPinPattern: [Int] = [Int]()
for currentIndex in stride(from: currentIndex, to: currentIndex+6, by: 1){
rejectedPinPattern.append(consecutiveNumber[currentIndex])
}
return rejectedPinPattern
}
func decrementNumber(currentIndex: Int) -> [Int] {
var rejectedPinPattern: [Int] = [Int]()
for currentIndex in stride(from: currentIndex, to: currentIndex-6, by: -1){
rejectedPinPattern.append(consecutiveNumber[currentIndex])
}
return rejectedPinPattern
}
func constantNumber(currentIndex: Int) -> [Int] {
var rejectedPinPattern: [Int] = [Int]()
for _ in currentIndex...currentIndex+6 {
rejectedPinPattern.append(consecutiveNumber[currentIndex])
}
return rejectedPinPattern
}
for number in consecutiveNumber {
rejectedPinList.append(constantNumber(currentIndex: number))
if number < 5 {
rejectedPinList.append(incrementNumber(currentIndex: number))
} else if number > 5 {
rejectedPinList.append(decrementNumber(currentIndex: number))
} else {
rejectedPinList.append(incrementNumber(currentIndex: number))
rejectedPinList.append(decrementNumber(currentIndex: number))
}
}
func inputPin(pin: [Int]) {
if rejectedPinList.contains(pin) {
print("Pin Rejected!")
} else {
}
}
inputPin(pin: [8,7,6,5,4,3]) // Should be Rejected!
我要寻找的是,在生成连续且相同的数字时,比我上面所做的算法代码更有效。因为在我看来,我编写的代码太长,效率不高,可能是浪费。谢谢大家! 我想这应该是你想要的。它检查是否有任何连续数字的绝对差值不是1。如果是这样,则在检查重复数字之前,PIN可能有效 要检查重复的数字,请将这些数字添加到NSCountedSet。如果任何数字的计数与位数相同,则PIN无效
func validatePIN(_ candidate: [Int]) -> Bool {
guard !candidate.isEmpty else {
return false
}
let digitSet = NSCountedSet()
var possiblyValid = false
var lastSign: Int?
for i in 0..<candidate.count {
digitSet.add(candidate[i])
if i > 0 && !possiblyValid {
let difference = candidate[i]-candidate[i-1]
let thisSign = difference.signum()
if abs(difference) != 1 {
possiblyValid = true
} else if let sign = lastSign, sign != thisSign {
possiblyValid = true
}
lastSign = thisSign
}
}
for digit in digitSet {
if digitSet.count(for: digit) == candidate.count {
return false
}
}
return possiblyValid
}
print(validatePIN([]))
print(validatePIN([8,7,6,5,3,3]))
print(validatePIN([8,7,6,5,4,3]))
print(validatePIN([2,2,2,2,2,2]))
print(validatePIN([1,2,3,4,3,2]))
给出:
假的
真的
假的
假的
真的
您还可以在guard语句中添加一个最小长度测试我认为这应该满足您的要求。它检查是否有任何连续数字的绝对差值不是1。如果是这样,则在检查重复数字之前,PIN可能有效 要检查重复的数字,请将这些数字添加到NSCountedSet。如果任何数字的计数与位数相同,则PIN无效
func validatePIN(_ candidate: [Int]) -> Bool {
guard !candidate.isEmpty else {
return false
}
let digitSet = NSCountedSet()
var possiblyValid = false
var lastSign: Int?
for i in 0..<candidate.count {
digitSet.add(candidate[i])
if i > 0 && !possiblyValid {
let difference = candidate[i]-candidate[i-1]
let thisSign = difference.signum()
if abs(difference) != 1 {
possiblyValid = true
} else if let sign = lastSign, sign != thisSign {
possiblyValid = true
}
lastSign = thisSign
}
}
for digit in digitSet {
if digitSet.count(for: digit) == candidate.count {
return false
}
}
return possiblyValid
}
print(validatePIN([]))
print(validatePIN([8,7,6,5,3,3]))
print(validatePIN([8,7,6,5,4,3]))
print(validatePIN([2,2,2,2,2,2]))
print(validatePIN([1,2,3,4,3,2]))
给出:
假的
真的
假的
假的
真的
您还可以在guard语句中添加最小长度测试,因为问题是为了提高效率,下面的方法在开始循环数组之前执行一些初始检查,以最小化总迭代次数/时间
func validatePin(_ pin: [Int], minLength: Int = 2 ) -> Bool {
guard pin.count >= max(minLength, 2) else {return false}
guard Set(pin).count != 1 else {return false} //all the same
guard abs(pin.first! - pin.last!) == pin.count - 1 else {return true} //can't be a sequence
let delta = pin.first! < pin.last! ? -1 : 1
for index in (0...pin.count - 2) {
if pin[index] - pin[index + 1] != delta {return true} //items not sequential
}
return false //items are sequential
}
由于问题是为了提高效率,下面的方法在开始在阵列中循环之前执行一些初始检查,以最小化总迭代次数/时间
func validatePin(_ pin: [Int], minLength: Int = 2 ) -> Bool {
guard pin.count >= max(minLength, 2) else {return false}
guard Set(pin).count != 1 else {return false} //all the same
guard abs(pin.first! - pin.last!) == pin.count - 1 else {return true} //can't be a sequence
let delta = pin.first! < pin.last! ? -1 : 1
for index in (0...pin.count - 2) {
if pin[index] - pin[index + 1] != delta {return true} //items not sequential
}
return false //items are sequential
}
您可以通过计算相邻数字的所有差异集来验证给定管脚,而不是预先计算所有无效管脚的列表。如果集仅由-1、0或+1组成,则pin无效:
您可以通过计算相邻数字的所有差异集来验证给定管脚,而不是预先计算所有无效管脚的列表。如果集仅由-1、0或+1组成,则pin无效:
谢谢大家帮助我。我还即兴创作了我的算法。这是我的密码:
func validatePIN(_ pin: [Int]) -> Bool {
if (pin.isEmpty == true) ||
(pin[0] < 5 && pin == Array(pin[0]...pin[0]+5)) ||
(pin[0] > 5 && pin == Array(stride(from: pin[0], through: pin[0]-5, by: -1)) ||
(pin.allSatisfy({ $0 == pin[0] }))) { return false }; return true
}
谢谢大家帮助我。我还即兴创作了我的算法。这是我的密码:
func validatePIN(_ pin: [Int]) -> Bool {
if (pin.isEmpty == true) ||
(pin[0] < 5 && pin == Array(pin[0]...pin[0]+5)) ||
(pin[0] > 5 && pin == Array(stride(from: pin[0], through: pin[0]-5, by: -1)) ||
(pin.allSatisfy({ $0 == pin[0] }))) { return false }; return true
}
为什么不使用随机数Int.randomin:0..是否允许使用任何连续数字或根本不使用?例如,561924有效吗?是否允许任何重复的数字?例如,419314有效吗?我想检查给定的pin是否增加/减少/相同字符比事先创建所有“阻止”pin的列表更容易。您好@Afsaredrisy,我只是更改了变量的名称以避免误解。您可以再次检查。Hi@Paulw11,561924有效,419314也有效。为什么不使用随机数Int.randomin:0..是否允许使用任何连续数字或根本不使用?例如,561924有效吗?是否允许任何重复的数字?例如,419314有效吗?我想检查给定的pin是否增加/减少/相同字符比事先创建所有“阻止”pin的列表更容易。您好@Afsaredrisy,我只是更改了变量的名称以避免误解。您可以再次检查。Hi@paulw11561924有效,419314也有效。请注意,这将拒绝[1,2,3,4,3,2]。抓到了。修复了该问题。请注意,这将拒绝[1,2,3,4,3,2]。捕获效果很好。修正了这个问题。注意这将拒绝[1,2,4,6,3,1]。您只检查第一个和最后一个数字是否相等,而不是所有数字是否相等。此外,pin码[2,5,5,5,1]的代码也会崩溃。您可能希望将插脚[0]<5替换为插脚[0]<5]。最后一次检查可以简化为插脚。AllConfect{$0==pin[0]}太棒了!谢谢。请注意,这将拒绝[1,2,4,6,3,1]。您只检查第一个和最后一个数字是否相等,而不是所有数字是否相等。此外,pin码[2,5,5,5,1]的代码也会崩溃。您可能希望将插脚[0]<5替换为插脚[0]<5]。最后一次检查可以简化为插脚。AllConfect{$0==pin[0]}太棒了!非常感谢。