[swift-users] [swift-evolution] Low efficiency multidimensional array problem
www.hbu.cn at 163.com
www.hbu.cn at 163.com
Fri Apr 21 09:41:08 CDT 2017
Hi Jaden Geller, Saagar ,
Thanks for the reply and advice. Array2D is really faster than the
default two dimension. But I think as a general language, Swift should
provide default efficient ways for multiple dimension array.
I found this problem when I write an algorithm. It is a DP problem and
the description is here
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/
My code is as following, a little long. It define Array3D, including two
strategies to implement it. One is with default Array way: another is,
like Jaden said, using one dimension array. The second one is twice faster
comparing to the first one. I think swift should optimize swift array.
Implementing the very basic multiple dimension array is not developer
friendly.
import Foundation
enum Strategy {
case defaultImpletions
case useOneDemensionArray
}
class Solution {
static func maxProfit(_ k: Int, _ prices: [Int], strategy:Strategy) ->
Int {
if (k <= 0 || prices.count <= 1) {
return 0
}
if (k >= prices.count) {
return quickSolve(prices)
}
let profit = Array3D<Int>(x: 2, y: k + 1, z: 2, value: 0, strategy:
strategy)
for j in 0 ... k { profit[0, j, 1] = -prices[0] }
for i in 1 ... prices.count - 1 {
for j in 0 ... k {
profit[i & 1, j, 0] = max(profit[(i - 1) & 1, j, 0], j > 0
? profit[(i - 1) & 1 , j - 1, 1] + prices[i] : 0)
profit[i & 1, j, 1] = max(profit[(i - 1) & 1, j, 1], profit[(i
- 1) & 1, j, 0] - prices[i])
}
}
return profit[(prices.count - 1) & 1, k, 0]
}
static func quickSolve(_ prices:[Int]) -> Int {
var sum = 0
for i in 1 ... prices.count - 1 {
if prices[i] - prices[i - 1] > 0 {
sum += prices[i] - prices[i - 1]
}
}
return sum
}
static func randomArrayWithCount(count: Int) -> [Int] {
var result = [Int]()
for _ in 0 ... count - 1 {
result.append(Int(arc4random() % UInt32(1000)))
}
return result
}
}
class Array3D <T> {
let x: Int
let y: Int
let z: Int
var array: [T]!
var threeDemsionArray: [[[T]]]!
var strategy: Strategy
init(x:Int, y:Int, z:Int, value: T, strategy: Strategy) {
self.x = x
self.y = y
self.z = z
self.strategy = strategy
if strategy == .useOneDemensionArray {
array = Array.init(repeating: value, count: x * y * z)
} else {
threeDemsionArray = Array(repeating: Array(repeating:
Array(repeating:
value, count: z), count: y), count: x)
}
}
subscript(i:Int, j:Int, k: Int) -> T {
get {
if strategy == .useOneDemensionArray {
return array[offset(i: i, j: j, k: k)]
} else {
return threeDemsionArray[i][j][k]
}
}
set {
if strategy == .useOneDemensionArray {
array[offset(i: i, j: j, k: k)] = newValue
} else {
threeDemsionArray[i][j][k] = newValue
}
}
}
func offset(i: Int, j: Int, k: Int) -> Int {
var offset = i * y * z
offset += j * z
offset += k
return offset
}
}
var count = 10
for i in 1 ... 5 {
let array = Solution.randomArrayWithCount(count: count)
var lastDate = Date()
_ = Solution.maxProfit(6, array, strategy: .useOneDemensionArray)
let oneDemensionArrayRunTime = Date().timeIntervalSince(lastDate) * 1000
lastDate = Date()
_ = Solution.maxProfit(6, array, strategy: .defaultImpletions)
let defaultImpletionsRuntime = Date().timeIntervalSince(lastDate) * 1000
print("count: \(count) run time: oneDemension: \(
oneDemensionArrayRunTime), defaultImpl:\(defaultImpletionsRuntime)
ratio:\(defaultImpletionsRuntime
/ oneDemensionArrayRunTime)")
count *= 10
}
*best wishes for you *
2017-04-19 17:55 GMT+08:00 Jaden Geller <jaden.geller at gmail.com>:
> Hi Hbucius,
>
> You can define your own `Array2D` type that uses a 1-dimensional array as
> backing (for fast performance) but exposes a high-level 2-dimensional array
> API.
>
> Here’s a really primitive starting point I found on GitHub:
> https://github.com/raywenderlich/swift-algorithm-club/blob/master/Array2D/
> Array2D.swift
>
> Cheers,
> Jaden Geller
>
> On Apr 18, 2017, at 11:39 PM, Saagar Jha via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> It might be helpful if you showed a bit more of the code you’re working
> on, so that we can better see what you’re trying to do. Is there any
> operation in particular that is slow?
>
> Also, CC’ing swift-users since I think it belongs there.
>
> Saagar Jha
>
> On Apr 18, 2017, at 22:57, Hbucius Smith via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> Hello Swift community,
>
>
> When I used multidimensional array in swift, I found it is very low
> efficiency.
>
>
> I used in the following way :
>
>
> * var array = Array.init(repeating: Array.init(repeating: 0, count: 5),
> count: 5)*
>
> * array[0][0] = 0*
>
>
> I have read some posts in stack overflow. It suggests using one
> dimension to fake multidimensional array. I think it is too ugly. DO we
> have better choice for this ?
>
>
>
>
>
>
> *best wishes for you *
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170421/fd8430de/attachment.html>
More information about the swift-users
mailing list