【问题标题】:The most efficient method using the Big O notation to avoid multiple forEach loops使用 Big O 表示法避免多个 forEach 循环的最有效方法
【发布时间】:2020-05-02 01:32:44
【问题描述】:

我已经创建了这两个对象:

struct Person {
    let name: String
    let genderId: Int

}

struct Gender {
    let id: Int
    let sex: String
}

并创建这些数组:

let persons = [
    Person(name: "Steve", genderId: 1),
    Person(name: "Kate", genderId: 2),
    Person(name: "Mark", genderId: 1),
    Person(name: "Pam", genderId: 2)

]

let genders = [
    Gender(id: 1, sex: "girl"),
    Gender(id: 2, sex: "boy"),
]

为了基于这个新对象创建对象数组,使用大 O 表示法的最有效算法应该是什么:

struct PersonWithGenderString {
    let name: String
    let genderString: String
}

我已经使用两个 forEach 循环编写了这个方法,但我正在寻找迭代时间尽可能少的方法:

persons.forEach { (person) in
    genders.forEach { (gender) in
        if person.genderId == gender.id {
            let personWithGenderString = PersonWithGenderString(name: person.name, genderString: gender.sex)
            print(personWithGenderString)
        }

    }
}

【问题讨论】:

  • 最高效的算法其实需要高效的数据结构。即具有 O(1) 查找给定 id 的性别的人。例如哈希表
  • 看起来像 stackoverflow.com/q/61527981/3141234 的副本

标签: swift algorithm foreach big-o


【解决方案1】:

如果您将Gender 对象按Gender.id 的顺序存储在genders 数组中,您可以直接访问它们,而不是使用内部循环:

persons.forEach { (person) in
    let genderIndex = person.genderId - 1
    if genderIndex < 0 || genderIndex > genders.size {
       // handle this error (array out of bounds)
    }
    let personWithGenderString = PersonWithGenderString(name: person.name, genderString: genders[genderIndex].sex)
    print(personWithGenderString)
}

这将是 O(1) 将任何特定的 Person 转换为 PersonWithGenderString 和 O(n) 将 n Persons 转换为 n PersonWithGenderStrings

【讨论】:

  • genderIndex &lt; 0 || genderIndex &gt; genders.size 不要这样写。它超级容易出错。只需使用genders.indices.contains(genderIndex)。顺便说一句,没有投反对票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-21
  • 2020-06-15
  • 2017-09-15
  • 1970-01-01
  • 2016-10-08
相关资源
最近更新 更多