Накопление суммы в одной строке в C#

#c# #algorithm

#c# #алгоритм

Вопрос:

Возможно ли сделать это в одной строке с целью получения накопленной суммы, равной n?

 int n = 0;
for (int i = 1; i <= 10; i  )
{
    n  = i;
}
  

Ответ №1:

Для этого есть метод расширения LINQ:

 static int SlowSum1ToN(int N)
{
    return Enumerable.Range(1, N).Sum();
}
  

Однако вы также можете вычислить это конкретное значение (сумму арифметической последовательности) вообще без итерации:

 static int FastSum1ToN(int N)
{
    return (N * (1   N)) / 2;
}
  

Комментарии:

1. …но теперь -1 за вашу неработающую реализацию этого.

2. Ха-ха, упс. Почему-то у меня было ощущение, что я совершу подобную ошибку. Я думаю, что вместо модульных тестов для TDD мне следует просто опубликовать код на SO; таким образом, вы сможете быстрее получать обратную связь 😉

3. return (N * (1 N)) >> 1; примерно еще на 35% быстрее на моем core2duo. 1 за математику.

4. @Bengie: попробуйте сохранить /2 , но использовать uint вместо int . Это тоже улучшает производительность?

5. @Steve: Да, кажется, uint использует их примерно с одинаковой скоростью. Я предполагаю, что сдвиг не сработал бы с отрицательным знаком int, но в этом случае у нас нет отрицательных чисел. Компилятор не может этого вычислить. По крайней мере, это мое предположение. Хотя это хороший момент.

Ответ №2:

Да, это возможно, вы можете сделать это с помощью Enumerable.Используйте диапазон для генерации последовательности целых чисел, а затем вызовите метод расширения LINQ Sum следующим образом:

 int result = Enumerable.Range(1, 10).Sum();
  

Ответ №3:

ДА

Вы можете заменить

 int S = 0

for (int i = 0; i <= N; i  )
{
    S  = i;
}
  

с

int S = (N*(N 1))/2

Комментарии:

1. Ваша математическая формула N*(N 1)/2 абсолютно корректна, но в результате получится более одной строки кода.

2. @Waqas: Что вы имеете в виду? Разве это не одна строка? Вы говорите о сборке?

Ответ №4:

В качестве дополнительного ответа существует также Aggregate функция, которая является более общей, чем Sum :

 var sum = Enumerable.Range(1, 10).Aggregate(0, (a, b) => a  = b);
  

Таким образом, вы также можете делать такие вещи, как

 // multiply 1 * 2 * 3 * 4 ...
var product = Enumerable.Range(1, 10).Aggregate(1, (a, b) => a *= b);
  

Комментарии:

1. Я думаю, вы имеете в виду (a, b) => a b . a = b не является неправильным, поскольку он вычисляется как a b , но нет смысла присваивать результат a .

Ответ №5:

В чем прелесть однострочников? Вот он:

int n = 0; for (int i = 1; i <= 10; i ) {n = i;}

Есть ли лучший способ вычислить это? Конечно. Смотрите другие ответы, в которых используется формула.

Комментарии:

1. вы не круты, если все ваше приложение не состоит всего из одной строки кода.

2. @Matt: действительно, это главное достижение в Java и C # по сравнению с C и C — при удалении препроцессора больше нет необходимости в разрывах строк.