jjzjj

swift - 给定出生和死亡名单,确定大多数人活着的年份

coder 2023-09-08 原文

我有一本人的字典,里面有他们各自的出生和死亡。

我想知道哪一年活着的人最多。

我目前的算法将每个人生活的每一年追加到一个数组中,然后返回出现次数最多的年份。我有一种预感,有一种更简洁的方法可以实现这一目标。

这是我的临时粗暴实现:

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/

有关swift - 给定出生和死亡名单,确定大多数人活着的年份的更多相关文章

  1. ruby - 即时确定方法的可见性 - 2

    我正在编写一个方法,它将在一个类中定义一个实例方法;类似于attr_accessor:classFoocustom_method(:foo)end我通过将custom_method函数添加到Module模块并使用define_method定义方法来实现它,效果很好。但我无法弄清楚如何考虑类(class)的可见性属性。例如,在下面的类中classFoocustom_method(:foo)privatecustom_method(:bar)end第一个生成的方法(foo)必须是公共(public)的,第二个(bar)必须是私有(private)的。我怎么做?或者,如何找到调用我的cust

  2. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  3. ruby - 确定 ruby​​ 脚本是否已经在运行 - 2

    有没有一种简单的方法可以判断ruby​​脚本是否已经在运行,然后适本地处理它?例如:我有一个名为really_long_script.rb的脚本。我让它每5分钟运行一次。当它运行时,我想看看之前运行的是否还在运行,然后停止第二个脚本的执行。有什么想法吗? 最佳答案 ps是一种非常糟糕的方法,并且可能会出现竞争条件。传统的Unix/Linux方法是将PID写入文件(通常在/var/run中)并在启动时检查该文件是否存在。例如pid文件位于/var/run/myscript.pid然后你会在运行程序之前检查它是否存在。有一些技巧可以避免

  4. ruby - 确定字符串的结尾是否与单独的字符串的开头重叠 - 2

    我想查找字符串的结尾是否与单独字符串的开头重叠。例如,如果我有这两个字符串:string_1='Peoplesaynothingisimpossible,butI'string_2='butIdonothingeveryday.'如何找到string_1末尾的“butI”部分与string_2开头相同?我可以编写一个方法来遍历这两个字符串,但我希望得到一个包含我错过的Ruby字符串方法或Ruby习惯用法的答案。 最佳答案 将MARKER设置为一些从未出现在您的string_1和string_2中的字符串。有一些方法可以动态地做到这一

  5. ruby - 如果满足给定条件,则结束 ruby​​ 程序 - 2

    基本上,我只是试图在满足特定条件时停止程序运行其余行。unlessraw_information.firstputs"Noresultswerereturnedforthatquery"breakend然而,在程序运行之前我得到了这个错误:Invalidbreakcompileerror(SyntaxError)执行此操作的正确方法是什么? 最佳答案 abort("Noresultswerereturnedforthatquery")unlesscondition或unlessconditionabort("Noresultswer

  6. ruby-on-rails - Rails 3 Formtastic。如何让 formtastic 仅显示月份和年份字段而不显示日期? - 2

    我需要formtastic来仅显示月份和年份字段,而不显示日期字段。日期选择器很好,但它显示了整个日历。我不想要日期选择器。f.input:accounting_month,:label=>"会计月份",:as=>:datepicker我只需要月份和年份。 最佳答案 有一种方法可以做到这一点:"Accountingmonth",:order=>[:month,:year]这将自动隐藏“天”输入并为其指定默认值1。 关于ruby-on-rails-Rails3Formtastic。如何让f

  7. ruby - 不能将 `each` 的所有或大多数情况替换为 `map` 吗? - 2

    Enumerable#each和Enumerable#map的区别在于返回的是接收者还是映射后的结果。回到接收者是微不足道的,你通常不需要在each之后继续一个方法链,比如each{...}.another_method(我可能没见过这样的案例。即使你想回到接收者那里,你也可以通过tap来实现)。所以我认为所有或者大部分使用Enumerable#each的情况都可以用Enumerable#map代替。我错了吗?如果我是对的,each的目的是什么?map是否比each慢?编辑:我知道当您对返回值不感兴趣时​​使用each是一种常见的做法。我对这种做法是否存在不感兴趣,但感兴趣的是,除了从

  8. ruby - 如何计算自 Ruby 中给定日期以来的周数? - 2

    目标我正在尝试计算自给定日期以来周的距离,而无需跳过任何步骤。我更喜欢用普通的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

  9. ruby - 根据给定顺序对数字数组进行排序 - 2

    我有两个数组。第一个数组包含排序顺序。第二个数组包含任意数量的元素。我的属性是保证第二个数组中的所有元素(按值)都在第一个数组中,而且我只处理数字。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

  10. ruby-on-rails - 给定长度的完全随机标识符 - 2

    我想生成一个包含数字、字母和特殊字符的给定(长度可能不同)长度的完全随机的“唯一”(我将确保使用我的模型)标识符例如:161551960578281|2.AQAIPhEcKsDLOVJZ.3600.1310065200.0-514191032|有人可以建议在RubyonRails中最有效的方法吗?编辑:重要:如果可能,请评论您提出的解决方案的效率,因为每次用户进入网站时都会使用它!谢谢 最佳答案 将其用于访问token与UUID不同。您不仅需要伪随机性,而且还需要加密安全PRNG.如果您真的不关心您使用的是什么字符(它们不会增加任何

随机推荐