help rewriting in functional style

后端 未结 5 2130
再見小時候
再見小時候 2021-02-10 10:46

I\'m learning Scala as my first functional-ish language. As one of the problems, I was trying to find a functional way of generating the sequence S up to n places. S is defined

5条回答
  •  失恋的感觉
    2021-02-10 11:20

    Pavel's answer has come closest so far, but it's also inefficient. Two flatMaps and a zipWithIndex are overkill here :)

    My understanding of the required output:

    • The results contain all the positive integers (starting from 1) at least once
    • each number n appears in the output (n/2) + 1 times

    As Pavel has rightly noted, the solution is to start with a Stream then use flatMap:

    Stream from 1
    

    This generates a Stream, a potentially never-ending sequence that only produces values on demand. In this case, it's generating 1, 2, 3, 4... all the way up to Infinity (in theory) or Integer.MAX_VALUE (in practice)

    Streams can be mapped over, as with any other collection. For example: (Stream from 1) map { 2 * _ } generates a Stream of even numbers.

    You can also use flatMap on Streams, allowing you to map each input element to zero or more output elements; this is key to solving your problem:

    val strm = (Stream from 1) flatMap { n => Stream.fill(n/2 + 1)(n) }
    

    So... How does this work? For the element 3, the lambda { n => Stream.fill(n/2 + 1)(n) } will produce the output stream 3,3. For the first 5 integers you'll get:

    1 -> 1
    2 -> 2, 2
    3 -> 3, 3
    4 -> 4, 4, 4
    5 -> 5, 5, 5
    etc.
    

    and because we're using flatMap, these will be concatenated, yielding:

    1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, ...
    

    Streams are memoised, so once a given value has been calculated it'll be saved for future reference. However, all the preceeding values have to be calculated at least once. If you want the full sequence then this won't cause any problems, but it does mean that generating S(10796) from a cold start is going to be slow! (a problem shared with your imperative algorithm). If you need to do this, then none of the solutions so far is likely to be appropriate for you.

提交回复
热议问题