#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 — при удалении препроцессора больше нет необходимости в разрывах строк.