2015-07-29 2 views
1

В настоящее время меня интересует LINQ. Я пытаюсь получить простые числа. Я на самом деле очень хорошо, но мой код не показывает простые числа, которые ниже Sqrt (n).C# Prime Numbers with LINQ

static void Main(string[] args) 
    { 

     Func<int, int, IEnumerable<int>> EnumerableRange = 
      (startPoint, endPoint) => 
       Enumerable.Range(Math.Min(startPoint, endPoint), Math.Abs(startPoint - endPoint) + 1); 

     Func<int, int, bool> isFullyDivided = 
      (value, divisor) => 
       (value % divisor).Equals(0); 

     int sp = 2, 
      ep = 100; 

     var query = 
      EnumerableRange(sp, ep) 
      .Where(value => 
       EnumerableRange(2, (int)Math.Ceiling(Math.Sqrt(ep))) 
       .Any(divisor => 
        isFullyDivided(value, divisor)) 
        ); 

     var primeNumbers = 
      EnumerableRange(sp, ep) 
      .Except(query); 

     foreach (var item in primeNumbers) 
     { 
      Console 
       .WriteLine(item); 
     } 

     Console 
      .Read(); 

    } 

В настоящее время этот код неправильно выходит из простых чисел, которые меньше sqrt(n). Предполагается, что код получает простые числа от 2 до 100. Вместо этого он печатает только простые числа 11 и выше. Пропуски 2, 3, 5, 7 отсутствуют.

+0

Можете ли вы уточнить, как ваш код не работает? – ryanyuyu

+0

В следующем коде представлены простые числа 11 и выше. Ниже 11, которые отсутствуют 2, 3, 5, 7. – Artxzta

ответ

1

Вы скованность делителей неверно - вы смотрите на делители между 2 и Sqrt(ep) (10), когда вам нужно только проверить делители между 2 и Sqrt(value):

var query = 
     EnumerableRange(sp, ep) 
     .Where(value =>          V---------- 
      EnumerableRange(2, (int)Math.Ceiling(Math.Sqrt(value))) 
      .Any(divisor => 
       isFullyDivided(value, divisor)) 
       ); 

Вот почему вашим простые числа начинаются с 11, потому что ваши делители идут до 10, которые будут включать в себя само значение. Ответ @ ryanyuyu также решает ту же проблему, но по-другому. Ваш код по-прежнему будет проверять ненужные делители.

+0

Ответ @ ryanyuyu правильный. Мне не хватает этого состояния. ! Value.Equals (divisor) – Artxzta

+1

Вы не _need_ это условие, если вы измените свой выбор дивизора. –

+0

Затем он начинается с 5. Как 5, 7, 11 ... – Artxzta

2

У вас есть логическая проблема. Все может равномерно разделяться, поэтому вы должны проверить, что value != divisor. В противном случае вы неправильно исключаете числа, которые делятся (например, 5 % 5 == 0).

var query = 
    EnumerableRange(sp, ep) 
    .Where(value => 
     EnumerableRange(2, (int)Math.Ceiling(Math.Sqrt(ep))) 
     .Any(divisor => 
      value != divisor && //This is the logic you are missing 
      isFullyDivided(value, divisor)) 
      ); 
+0

Спасибо. Большое спасибо. Я думаю, что такие часы, как «что мне не хватает, проклятье». Действительно оценен. – Artxzta

0

Лучшее решение:

  var query = 
      EnumerableRange(sp, ep) 
      .Where(value => 
       EnumerableRange(2, (int)Math.Ceiling(Math.Sqrt(value))) 
       .Any(divisor => 
        !value.Equals(divisor) && 
        isFullyDivided(value, divisor)) 
        ); 

Math.Floor неправильно. Правильным является Math.Ceiling.