Помощь с выражением LINQ - PullRequest
4 голосов
/ 14 января 2010

Как написать выражение LINQ (предпочтительный синтаксис вызова метода), которое дает список чисел Фибоначчи, лежащих в определенном диапазоне, скажем, от 1 до 1000?

Ответы [ 6 ]

14 голосов
/ 14 января 2010

OK; для более "FP" ответа:

using System;
using System.Collections.Generic;
using System.Linq;
static class Program
{
    static void Main()
    {
        Func<long, long, long, IEnumerable<long>> fib = null;
        fib = (n, m, cap) => n + m > cap ? Enumerable.Empty<long>()
            : Enumerable.Repeat(n + m, 1).Concat(fib(m, n + m, cap));

        var list = fib(0, 1, 1000).ToList();
    }
}

Обратите внимание, что в теории это можно записать как одну лямбду, но это очень трудно .

3 голосов
/ 14 января 2010

Использование ответа блока итератора от здесь :

    foreach (long i in Fibonacci()
           .SkipWhile(i => i < 1)
           .TakeWhile(i => i <= 1000)) {
        Console.WriteLine(i);
    }

или для списка:

var list = Fibonacci().SkipWhile(i => i < 1).TakeWhile(i => i <= 1000)
                 .ToList();

Выход:

1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
2 голосов
/ 28 октября 2010

не очень производительно:

val fibonacci = Enumerable
                  .Range(0, 1000)
                  .Aggregate(new List<int>{1,0}, (b,j)=>{
                                b.Insert(0,b[0]+b[1]);
                                return b; });
2 голосов
/ 14 января 2010

Вот базовое решение для перечислителя. Это ленивая оценка. Поэтому следующее число генерируется, когда MoveNext () завершено.

   foreach (int k in Fibonacci.Create(10))
       Console.WriteLine(k);


    class Fibonacci : IEnumerable<int>
    {
        private FibonacciEnumertor fibEnum;
        public Fibonacci(int max) {
            fibEnum = new FibonacciEnumertor(max);
        }
        public IEnumerator<int> GetEnumerator() {
            return fibEnum;
        }


        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
            return GetEnumerator();
        }
        public static IEnumerable<int> Create(int max) {
            return new Fibonacci(max);
        }

        private class FibonacciEnumertor : IEnumerator<int>
        {
            private int a, b, c, max;
            public FibonacciEnumertor(int max) {
                this.max = max;
                Reset();
            }
            // 1 1 2 3 5 8
            public int Current {
                get {

                    return c;
                }
            }
            public void Dispose() {

            }

            object System.Collections.IEnumerator.Current {
                get { return this.Current; }
            }

            public bool MoveNext() {

                c = a + b;
                if (c == 0)
                    c = 1;
                a = b;
                b = c;
                ;
                return max-- > 0;
            }

            public void Reset() {
                a = 0;
                b = 0;
            }
        }
    }
1 голос
/ 10 июля 2012

поздно, но быстрая версия с ключевым словом yield: -)

IEnumerable<int> Fibonacci(int limit)
{
 int number = 1, old = 0;
 while (number < limit)
 {
  yield return number;
  int tmp = number; number += old; old = tmp;
 }
}

var list = Fibonacci(1000).ToList();
0 голосов
/ 29 ноября 2016

Самый простой способ печати Фибоначчи с использованием linq

        List<int> lst = new List<int> { 0, 1 };

        for (int i = 0; i <= 10; i++)
        {
            int num = lst.Skip(i).Sum();
            lst.Add(num);

            foreach (int number in lst)
                Console.Write(number + " ");
            Console.WriteLine();
        }
...