- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有一本人的字典,里面有他们各自的出生和死亡。
我想知道哪一年活着的人最多。
我目前的算法将每个人生活的每一年追加到一个数组中,然后返回出现次数最多的年份。我有一种预感,有一种更简洁的方法可以实现这一目标。
这是我的临时粗暴实现:
var people = [ "Nicolas": (birth: 1900, death: 1975),
"Vladimir": (birth: 1970, death: 2000),
"Julius": (birth: 1950, death: 1985),
"Alexander": (birth: 1900, death: 1920),
"Obama": (birth: 1910, death: 1920),
"George": (birth: 1915, death: 1920),
"Benjamin": (birth: 1919, death: 1925)]
var yearsArray = [Int]()
var yearOccurrences: [Int:Int] = [:]
for life in people.values {
var birth = life.birth
var death = life.death
for year in birth..<death {
yearsArray.append(year)
}
}
for year in yearsArray {
yearOccurrences[year] = (yearOccurrences[year] ?? 0) + 1
}
(yearOccurrences as! NSDictionary).allKeysForObject(yearOccurrences.values.maxElement()!)
预期结果是 1919 年和 1920 年。
无论是代码还是流程,都在寻找更简洁优雅的解决方案
最佳答案
您必须检查的实际值(年)是数字变化的年份,即只有某人出生或某人死亡的年份。
让我们用结构来表示变化(您也可以使用命名元组)。
struct PeopleAliveChange {
var year: Int
var change: Int
}
变化将是 +1 或 -1。
让我们从您的数据中生成这些结构的数组,例如使用 reduce
调用,但您可以使用简单的 for
迭代。
let changes = people.values.reduce([PeopleAliveChange]()) {
aggregate, personLife in
let birthChange = PeopleAliveChange(year: personLife.birth, change: 1)
let deathChange = PeopleAliveChange(year: personLife.death, change: -1)
return aggregate + [birthChange, deathChange]
}
然后让我们按日期(年份)对更改进行排序:
let sortedChanges = changes.sort { $0.year < $1.year }
现在,我们有了一个非常好的结构,可以让我们进行很多操作。例如,要获得大多数人活着的年份,您可以
var numPeopleAlive = 0;
var maxPeopleAlive: Int = 0
var yearWithMaxPeopleAlive: Int? = nil
for lifeChange in sortedChanges {
numPeopleAlive += lifeChange.change
if (numPeopleAlive > maxPeopleAlive) {
maxPeopleAlive = numPeopleAlive
yearWithMaxPeopleAlive = lifeChange.year
}
}
print("Most people were alive in \(yearWithMaxPeopleAlive)")
为了处理整个区间,我们可以这样跟踪
var maxPeopleAlive: Int = 0
var currentMaxIntervalStart: Int? = nil
var intervalsWithMostPeopleAlive: [(Int, Int)] = []
for lifeChange in sortedChanges {
if (currentMaxIntervalStart != nil && lifeChange.change < 0) {
intervalsWithMostPeopleAlive.append((currentMaxIntervalStart!, lifeChange.year))
currentMaxIntervalStart = nil
}
numPeopleAlive += lifeChange.change
if (numPeopleAlive > maxPeopleAlive) {
maxPeopleAlive = numPeopleAlive
intervalsWithMostPeopleAlive = []
currentMaxIntervalStart = lifeChange.year
}
}
当然,我们还应该确保同一个人的出生和死亡排序正确(如果该人在同一年出生和死亡,这是一个问题)。
这是一个简单的问题,可以通过多种方式解决。重要的是,只有出生日期和死亡日期才是您真正想要关心的。
您的解决方案实际上还不错。这是一个有效的解决方案。
关于swift - 给定出生和死亡名单,确定大多数人活着的年份,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32896439/
抱歉我的英语不好......我尝试使用 Google Apps 脚本 - 通讯录服务读取通讯录中的信息。 姓名、电子邮件、地址、电话没有问题,但我无法读取日期(我想获取联系人的出生日期)。如何读取“日
我有一个包含字段生日(DATE) 的用户表。 目前,我像这样选择生日在当前日期之前或之后 7 天内的用户: SELECT * FROM users WHERE DATE_FORMAT(birt
我是一名优秀的程序员,十分优秀!