Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.55/29: Рейтинг темы: голосов - 29, средняя оценка - 4.55
 Аватар для Юлек
4 / 3 / 0
Регистрация: 26.10.2009
Сообщений: 43

Найти 1+2+3+...+n рекурсивно и итеративно

30.08.2010, 22:29. Показов 6582. Ответов 54
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Уважаемые программисты!!! помогите разобраться, дали задачу. Найти 1+2+3+...+n.
Первый способ, решить рекурсивно, а второй не рекурсивно. Чем текст программ будет различаться???
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
30.08.2010, 22:29
Ответы с готовыми решениями:

Вычислить выражение рекурсивно и итеративно
Помогите записать пример. Решить задачу на фото двумя способами - с применением рекурсии и без неё. ...

Вычисление цепной дроби (рекурсивно и итеративно)
Как это вообще сделать ??? Нужно с помощь. рекурсии и без неё С++.

Как рекурсивно и итеративно вычислить сумму ряда?
Ребят, помогите пожалуйста, ибо рекурсию вообще не шарю(( Есть ряд, как его считать?

54
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,980
31.08.2010, 01:04
Студворк — интернет-сервис помощи студентам
Lavroff, а зачем? в конструкторе вся основная работа делается. а добавить в класс
C++
1
unsigned int operator () () const { return nResult; }
получится самый, что нинаесть функтор, пригодный для более широкого применения, чем просто вывод суммы на экран...

кстати, если в примере из 6 поста строчку
C++
1
const int sum = Sum<5>::value;
поменять на
C++
1
const int sum = Sum<0>::value;
оно и не скомпилируется, про отрицательные числа и говорить не приходится, да и как это чудо использовать, если значение должно не константой задаваться? При моём подходе во-первых не сложно проверку входных данных устроить, во-вторых использовать просто...
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
31.08.2010, 01:11
Лучший ответ Сообщение было отмечено как решение

Решение

Извините без обид, но люто-бешено напомнило.

Как пишут Hello, world

А на тему класса и функторов, все же тут реальный перебор для такой программы. Действительно красиво, да. Но ведь в таком случае и писать Hello, world через класс тоже нормально, если учитывать что потом программа может делать нечто большее.
Кстати, а в конструкторе нормально выполнять все нужные операции или все же лучше в конструкторе проводить только инициализацию?
3
Заблокирован
31.08.2010, 01:21
Цитата Сообщение от easybudda Посмотреть сообщение
получится самый, что нинаесть функтор, пригодный для более широкого применения, чем просто вывод суммы на экран...
Например?

Цитата Сообщение от easybudda Посмотреть сообщение
кстати, если в примере из 6 поста строчку
C++
1
const int sum = Sum<5>::value;
поменять на
C++
1
const int sum = Sum<0>::value;
оно и не скомпилируется, про отрицательные числа и говорить не приходится
Ну логично же. Оно не скомпилируется и выдаст ошибку компиляции. Очень логично. Программа выдаёт ошибки во время работы, метапрограмма - во время компиляции.

Цитата Сообщение от easybudda Посмотреть сообщение
да и как это чудо использовать, если значение должно не константой задаваться? При моём подходе во-первых не сложно проверку входных данных устроить, во-вторых использовать просто...
А здесь всё ещё более логично. "Чудо" это вычисляется во время компиляции. Очевидно, что в готовой программе вместо "чуда" мы имеем константу. Отсюда несложно сделать вывод, что вычислить можно сумму только из тех значений, которые на момент компиляции известны. Я же нигде не писал, что оно будет работать в рантайме, ведь правда? И в ТЗ ничего об этом сказано небыло.

А по поводу того, что ты подставил ноль вместо пяти: нужна сумма первых нуля элементов? Она равна нулю!

Цитата Сообщение от easybudda Посмотреть сообщение
При моём подходе во-первых не сложно проверку входных данных устроить, во-вторых использовать просто...
Твой подход не нужен, потому что вместо него гораздо удобнее фунции, описанные другими товарищами тут в теме до тебя.

Добавлено через 8 минут
Цитата Сообщение от Lavroff Посмотреть сообщение
Кстати, а в конструкторе нормально выполнять все нужные операции или все же лучше в конструкторе проводить только инициализацию?
Я думаю, правильно так:
  1. Нечто внешнее по отношению к данному коду инициализирует функтор (если нужно какими-то данными).
  2. Данный код получает функтор, вызывая его передаёт ему какие-то свои параметры и функтор на основе их и того, что ему было заложено в предыдущем шаге, делает вычисления / что-то полезное.
1
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,980
31.08.2010, 01:37
Цитата Сообщение от NightmareZ Посмотреть сообщение
Я же нигде не писал, что оно будет работать в рантайме, ведь правда?
Ну а смысл тогда такой лес городить? Можно гораздо проще и со временем выполнения проблем не будет.
C
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
 
#define SUM(a) ({ int d = a; int s = 0; while ( d ) s += d--; (s); })
 
int main(void){
    printf("SUM(5) = %d\n", SUM(5));
    int i = 5;
    printf("SUM(%d) = %d\n", i, SUM(i));
    
    return 0;
}
Цитата Сообщение от NightmareZ Посмотреть сообщение
Твой подход не нужен
Повторяйте себе это почаще.

Не по теме:

И кстати, ничего, что я с Вами на Вы? Ну это так, элементарная вежливость...

0
Maniac
Эксперт С++
 Аватар для ISergey
1465 / 966 / 160
Регистрация: 02.01.2009
Сообщений: 2,820
Записей в блоге: 1
31.08.2010, 01:43
Цитата Сообщение от easybudda Посмотреть сообщение
поменять на
C++
1
const int sum = Sum<0>::value;
оно и не скомпилируется
Нашли проблему.. лечится быстро..

C++
1
2
3
4
template<>
struct Sum<0>{
        enum { value = 0 };
};
Как на меня то метапрограмы доволи интересная штука..
2
Заблокирован
31.08.2010, 01:46
Цитата Сообщение от easybudda Посмотреть сообщение
Ну а смысл тогда такой лес городить?
Потому что это самый быстрый по производительности код на C++, позволяющий решить поставленную задачу (посчитать сумму N элементов).

Подставить готовое решение в виде константы - значит использовать сторонние инструменты для вычислений, т.е. задача уже решена не на C++ будет.

Вычислять в рантайме - займёт в любом случае больше времени.

Цитата Сообщение от easybudda Посмотреть сообщение
Можно гораздо проще и со временем выполнения проблем не будет.
C
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
 
#define SUM(a) ({ int d = a; int s = 0; while ( d ) s += d--; (s); })
 
int main(void){
    printf("SUM(5) = %d\n", SUM(5));
    int i = 5;
    printf("SUM(%d) = %d\n", i, SUM(i));
    
    return 0;
}
Сложность моего алгоритма в рантайме будет O(1), а твоего O(N), иными словами, у меня будет константа, а у тебя будет N-1 сложений.

Цитата Сообщение от easybudda Посмотреть сообщение

Не по теме:

И кстати, ничего, что я с Вами на Вы? Ну это так, элементарная вежливость...

Вообще, чесно говоря, мне это не нравится. Называй меня пожалуйста на "ты". В интернетах так принято. От обращения на "вы" веет недоброжелательностью.
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
31.08.2010, 01:48
ISergey, Действительно интересная вещь. Только вот хоть убей не пойму как этим пользоваться. Обычными шаблонами - да, но настолько закрученными через enum. Эх.
1
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,980
31.08.2010, 01:57
Цитата Сообщение от NightmareZ Посмотреть сообщение
Потому что это самый быстрый по производительности код
По-моему при таком подходе это самый ненужный код. Если число константное, так его проще посчитать а) на пальцах; б) на калькуляторе; в) одной из предложенных программ и сразу в программе константой объявить, при этом не насилуя ни мозг, ни компилятор...
0
Заблокирован
31.08.2010, 01:59
Цитата Сообщение от Lavroff Посмотреть сообщение
ISergey, Действительно интересная вещь. Только вот хоть убей не пойму как этим пользоваться. Обычными шаблонами - да, но настолько закрученными через enum. Эх.
enum нужен только для того, чтобы можно было задать значение полю (в данном случае value).

А дальше... Есть вот такой код:

C++
1
2
3
4
5
6
7
8
9
10
11
template<int N>
struct Sum
{
        enum { value = N + Sum<N-1>::value };
};
 
template<>
struct Sum<0>
{
        enum { value = 0 };
};
...вызываешь ты его:
C++
1
const int sum = Sum<2>::value;
Компилятор начинает подставлять 2 вместо N:
C++
1
2
3
4
5
template<2>
struct Sum
{
        enum { value = 2 + Sum<2-1>::value };
};
тут ему всё известно, кроме Sub<2-1>. Он подставляет дальше уже 1 вместо N:
C++
1
2
3
4
5
template<1>
struct Sum
{
        enum { value = 1 + Sum<1-1>::value };
};
тут ему опять таки всё известно, но кроме Sub<1-1>.
Sub<1-1> это Sub<0>, а в нём value равно нулю:
C++
1
2
3
4
5
template<>
struct Sum<0>
{
        enum { value = 0 };
};
Компилятор берёт этот value и рекурсия отсюда идёт назад до тех пор, пока не соберётся исходный шаблон.
1
Maniac
Эксперт С++
 Аватар для ISergey
1465 / 966 / 160
Регистрация: 02.01.2009
Сообщений: 2,820
Записей в блоге: 1
31.08.2010, 02:02
Lavroff, найди вот эту книгу http://www.williamspublishing.... 513-3.html
почитай.. немного суть проясниться..
1
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
31.08.2010, 05:53
Хвостовая рекурсия:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <cstdlib>
 
unsigned int sum_iter(unsigned int result, unsigned int counter)
{
    if(!counter)
        return result;
    else
        return sum_iter(result + counter, --counter);
}
 
unsigned int sum(unsigned int n)
{
    return sum_iter(0, n);
}
 
int main()
{
    unsigned int n;
    std::cout << "Input n: ";
    std::cin >> n;
    std::cout << "Sum from 0 to " << n << " = " << sum(n) << std::endl;
    return EXIT_SUCCESS;
}
1
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,980
01.09.2010, 17:12
Nameless One, а две функции для того, чтобы в вызывающую только одно значение передавать?

Цитата Сообщение от NightmareZ Посмотреть сообщение
Например?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
 
class Sum {
        unsigned int nResult;
public:
        Sum() : nResult(0) {}
        Sum(unsigned int start){
                for ( nResult = 0; start; nResult += start-- )
                        ;
        }
        bool operator () (int test){
            return test > nResult;
        }
 
        friend std::ostream & operator << (std::ostream & ost, const Sum & sum){
                ost << sum.nResult;
                return ost;
        }
};
 
int main(){
        const size_t size = 5;
        int arr[size] = { 8, 12, 5, 14, 21 };
        std::vector<int> vec(arr, arr + size);
        int num = 5;
        Sum sum(num);
        std::vector<int>::iterator fnd;
 
        std::cout << "Array:\n";
        std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, " "));
        std::cout << "\nGiven number:\n" << num << std::endl;
        std::cout << "Sum of numbers from 1 to " << num << " = " << sum << std::endl;
        if ( ( fnd = std::find_if(vec.begin(), vec.end(), sum) ) == vec.end() )
            std::cout << "All elements in array less than it." << std::endl;
        else
            std::cout << "First element in array greater it is " << *fnd << std::endl;
 
        return 0;
}
Цитата Сообщение от NightmareZ Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
 
template<int N>
struct Sum
{
    enum { value = N + Sum<N-1>::value };
};
 
template<>
struct Sum<1>
{
    enum { value = 1 };
};
 
int main()
{
    const int sum = Sum<5>::value;
    std::cout << sum;
}
Долго пытался этому практическое применение придумать. Кроме объявления в программе 100500 тысяч констант, представляющих суммы от 1 до исходных 100500 тысяч чисел так и не придумал. Да и в том случае проще заголовочный файл создать например вот таким макаром:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
#include <stdlib.h>
 
#define SUM(a) ({ int d = a; int s = 0; while ( d ) s += d--; (s); })
 
#define IN_FILE "constants.txt"
#define OUT_FILE "constants.h"
 
int main(void){
    int val;
    FILE * fin, * fout;
 
    if ( ( fin = fopen(IN_FILE, "r") ) == NULL ){
        perror("fopen");
        exit(1);
    }
    if ( ( fout = fopen(OUT_FILE, "w") ) == NULL ){
        perror("fopen");
        exit(1);
    }
 
    fprintf(fout, "#ifndef _CONSTANTS_H_\n#define _CONSTANTS_H_ 1\n");
    while ( fscanf(fin, "%d", &val) == 1 )
        fprintf(fout, "#define SUM%d %d\n", val, SUM(val));
 
    fprintf(fout, "#endif\n");
 
    fclose(fin);
    fclose(fout);
 
    exit(0);
}
а то мало ли - ещё раз с другими числами понадобится - и чё, блин, делать? Лезть в исходники, править циферки и заново компилировать?
Короче, думаю, что в данном случае всё это метапрограммирование - голый выпендрёж и в принципе нафиг не нужно. Поправьте, если чего-то не понимаю...
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
01.09.2010, 17:19
Цитата Сообщение от easybudda Посмотреть сообщение
Nameless One, а две функции для того, чтобы в вызывающую только одно значение передавать?
Тут, я думаю, можно заменить функцию sum_iter на лямбду, либо сделать для функции sum дополнительный параметр. Две функции нужны для того, чтобы при передаче управления рекурсивному вызову самой себя никакая из локальных переменных вызывающей функции не была нужно для формирования результата. Т.е. чтобы вместо простой рекурсии можно было получить хвостовую рекурсию, которая некоторыми компиляторами (вроде msvs и gcc) может быть заменена на простой цикл. Интересная фича из функционального программирования
1
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
01.09.2010, 18:00
easybudda, Метапрограммирование не для такого нужно... Просмотрел 17 главу в книге, что скинул ISergey. Интересно. Советую просмотреть. Еще не очень развитая фича, но все же.
Зачем нужно метопрограммирование? Как и большинство других технологий программирования, оно применяется, чтобы достичь больших функциональных возможностей ценой меньших затрат, измеряемых обемом кода, усилиями на сопровождение и т.п. Характерной особенностью является то,что определенная часть необходимых пользователю вычислений выполняется на этапе трансляции программы. Его применение часто объясняется повышением производительности (вычисление, которое происходит во время трансляции, легче оптимизировть) или упрощением интерфейса (как правило, метапрограмма короче, чем программа, которая генерируется во время ее работы), а зачастую обеими причинами
0
01.09.2010, 18:53

Не по теме:

Цитата Сообщение от Lavroff Посмотреть сообщение
Просмотрел 17 главу в книге, что скинул ISergey. Интересно. Советую просмотреть.
Прочитал и, честно говоря, не впечатлился... Во-первых я себе это примерно так и представлял, а во-вторых может просто пока задачи не попадались, в которых без таких вот выкрутасов никуда... Пока же мне это метапрограммирование определение слова "Финдипёрст" из уголовного жаргона напоминает:
Вещь по сути своей бесполезная, но блестящая и напоминающая о воле.
;)

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
01.09.2010, 18:53

Вычислить произведение рекурсивно/итеративно, оценить время выполнения
Нужно разработать программу с использованием рекурсивной функции и без использования рекурсивной функции. Оценит время выполнения. x=...

Вычислить выражение рекурсивно и итеративно
Решить задачу двумя способами - с рекурсией и без: y(n)=\sqrt{1+\sqrt{2+...+\sqrt{n}}}

Вычисление суммы рекурсивно и итеративно
Помогите сделать программу. В понедельник сдавать, а мне еще 9 программ писать. Все мельком глянул, вот только эту не знаю как сделать. ...

Вычислить сумму ряда рекурсивно и итеративно
1.напишите рекурсивную функцию которая подсчитает сумму: 1/(2*3)+2/(3*4)+...+n/(n+1)*(n+2) 2. имея рекурсивную подпрограмму составить...

Вычисление значения цепной дроби (рекурсивно и итеративно)
Описать рекурсивную и нерекурсивную функции вычисления значения цепной дроби: \huge...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
55
Ответ Создать тему
Новые блоги и статьи
Нейтральные знания, чистый код - бла-бла-бла-бла, на самом деле кликбейт и самореклама, плагиат, и вот почему
Hrethgir 27.07.2026
То-есть отклонение такой публикации говорит само за себя, и пусть только возьмут на вооружение после отклонения публикации - это будет чистейшим актом плагиата. Отклонял Хабр. Дословно, отклонённая. . .
тв 16 бой ии
anaschu 27.07.2026
Великий Перелом ИИ: Как уравнения ОДУ Radau дожали цензурные фильтры Алисы Фиксируем в мемофонде Теории Всего беспрецедентный факт в истории ИИ-зондирования. В затяжном многораундовом. . .
мв 15. непроверенное, возможно, глюк
anaschu 27.07.2026
НАУЧНО-АНАЛИТИЧЕСКИЙ ОТЧЕТ. РАЗДЕЛ 1. 1: «НАУКА» (РАСШИРЕННАЯ СТЕХИОМЕТРИЧЕСКАЯ И ГЕНЕТИЧЕСКАЯ ВЕРСИЯ)Тема: Теоретическое обоснование инвариантности 19-мерного тензорного ядра непрерывных ОДУ и. . .
Очистка реквизитов и табличных частей документа при копировании (вариант 2)
Maks 26.07.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРаботу", разработанного в КА2. Задача: Заменить алгоритм запрета копирования документов для сотрудников с ролью "Стажер",. . .
Доктрина интенционального знания - Доктрина для портала "Срез".
Hrethgir 25.07.2026
Может найдётся кто захочет оценить доктрину. . . Написания правил участия для меня роскошь, требующая лимита времени, поэтому все сообщения не прошедшие модерацию будут видны только участникам портала,. . .
сукцессия 44. Решил подать на припринт в межународные сервисы препринтов. Но нужно одобрение от ученых
anaschu 25.07.2026
Английский вариант. Пока кто то не одобрит мою личность, мне не получиться это опубликовать на препринте. Но заявку на публикацию статьи я сегодня подам.
сукцессия 43. Вторая научная статья за месяц- прайминг и гатгил
anaschu 25.07.2026
две стороны одной монеты
Более приземисто - Эстафету хвоста в .cdl (деревья эстафеты в сад).
Hrethgir 24.07.2026
В будущем, после написания блока инверсии обхода дерева (эстафеты хвоста), я планирую вернуться к нашему прошлому разговору о том, обладают ли знания целеполаганием. Тогда я пришел к выводу, что. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru