我有一本人的字典,里面有他们各自的出生和死亡。
我想知道哪一年活着的人最多。
我目前的算法将每个人生活的每一年追加到一个数组中,然后返回出现次数最多的年份。我有一种预感,有一种更简洁的方法可以实现这一目标。
这是我的临时粗暴实现:
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/
我正在编写一个方法,它将在一个类中定义一个实例方法;类似于attr_accessor:classFoocustom_method(:foo)end我通过将custom_method函数添加到Module模块并使用define_method定义方法来实现它,效果很好。但我无法弄清楚如何考虑类(class)的可见性属性。例如,在下面的类中classFoocustom_method(:foo)privatecustom_method(:bar)end第一个生成的方法(foo)必须是公共(public)的,第二个(bar)必须是私有(private)的。我怎么做?或者,如何找到调用我的cust
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
有没有一种简单的方法可以判断ruby脚本是否已经在运行,然后适本地处理它?例如:我有一个名为really_long_script.rb的脚本。我让它每5分钟运行一次。当它运行时,我想看看之前运行的是否还在运行,然后停止第二个脚本的执行。有什么想法吗? 最佳答案 ps是一种非常糟糕的方法,并且可能会出现竞争条件。传统的Unix/Linux方法是将PID写入文件(通常在/var/run中)并在启动时检查该文件是否存在。例如pid文件位于/var/run/myscript.pid然后你会在运行程序之前检查它是否存在。有一些技巧可以避免
我想查找字符串的结尾是否与单独字符串的开头重叠。例如,如果我有这两个字符串:string_1='Peoplesaynothingisimpossible,butI'string_2='butIdonothingeveryday.'如何找到string_1末尾的“butI”部分与string_2开头相同?我可以编写一个方法来遍历这两个字符串,但我希望得到一个包含我错过的Ruby字符串方法或Ruby习惯用法的答案。 最佳答案 将MARKER设置为一些从未出现在您的string_1和string_2中的字符串。有一些方法可以动态地做到这一
基本上,我只是试图在满足特定条件时停止程序运行其余行。unlessraw_information.firstputs"Noresultswerereturnedforthatquery"breakend然而,在程序运行之前我得到了这个错误:Invalidbreakcompileerror(SyntaxError)执行此操作的正确方法是什么? 最佳答案 abort("Noresultswerereturnedforthatquery")unlesscondition或unlessconditionabort("Noresultswer
我需要formtastic来仅显示月份和年份字段,而不显示日期字段。日期选择器很好,但它显示了整个日历。我不想要日期选择器。f.input:accounting_month,:label=>"会计月份",:as=>:datepicker我只需要月份和年份。 最佳答案 有一种方法可以做到这一点:"Accountingmonth",:order=>[:month,:year]这将自动隐藏“天”输入并为其指定默认值1。 关于ruby-on-rails-Rails3Formtastic。如何让f
Enumerable#each和Enumerable#map的区别在于返回的是接收者还是映射后的结果。回到接收者是微不足道的,你通常不需要在each之后继续一个方法链,比如each{...}.another_method(我可能没见过这样的案例。即使你想回到接收者那里,你也可以通过tap来实现)。所以我认为所有或者大部分使用Enumerable#each的情况都可以用Enumerable#map代替。我错了吗?如果我是对的,each的目的是什么?map是否比each慢?编辑:我知道当您对返回值不感兴趣时使用each是一种常见的做法。我对这种做法是否存在不感兴趣,但感兴趣的是,除了从
目标我正在尝试计算自给定日期以来周的距离,而无需跳过任何步骤。我更喜欢用普通的Ruby来做,但ActiveSupport无疑是一个可以接受的选择。我的代码我写了以下内容,这似乎可行,但对我来说似乎还有很长的路要走。require'date'DAYS_IN_WEEK=7.0defweeks_sincedate_stringdate=Date.parsedate_stringdays=Date.today-dateweeks=days/DAYS_IN_WEEKweeks.round2endweeks_since'2015-06-15'#=>32.57ActiveSupport的#weeks
我有两个数组。第一个数组包含排序顺序。第二个数组包含任意数量的元素。我的属性是保证第二个数组中的所有元素(按值)都在第一个数组中,而且我只处理数字。A=[1,3,4,4,4,5,2,1,1,1,3,3]Order=[3,1,2,4,5]当我对A进行排序时,我希望元素按照Order指定的顺序出现:[3,3,3,1,1,1,1,2,4,4,4,5]请注意,重复是公平的游戏。A中的元素不应更改,只能重新排序。我该怎么做? 最佳答案 >>source=[1,3,4,4,4,5,2,1,1,1,3,3]=>[1,3,4,4,4,5,2,1,1
我想生成一个包含数字、字母和特殊字符的给定(长度可能不同)长度的完全随机的“唯一”(我将确保使用我的模型)标识符例如:161551960578281|2.AQAIPhEcKsDLOVJZ.3600.1310065200.0-514191032|有人可以建议在RubyonRails中最有效的方法吗?编辑:重要:如果可能,请评论您提出的解决方案的效率,因为每次用户进入网站时都会使用它!谢谢 最佳答案 将其用于访问token与UUID不同。您不仅需要伪随机性,而且还需要加密安全PRNG.如果您真的不关心您使用的是什么字符(它们不会增加任何