С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.62
Ruslan1991
0 / 0 / 0
Регистрация: 10.06.2010
Сообщений: 5
#1

С Использованием рекурсии! - C++

25.03.2011, 11:13. Просмотров 1738. Ответов 15
Метки нет (Все метки)

Привет!
Есть задачка (она уже сделанная, ее у меня приняли):

Во входном файле задана последовательность положительных вещественных чисел, за которой следует отрицательное число. Описать рекурсивную функцию без параметров, которая находит сумму положительных чисел.

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
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstdio>
#include <conio>
 
 
#define INPUT_FILENAME "in.txt"
 
using namespace std;
 
double get_sum(ifstream& file)
{
    double current;
    file >> current;
    return((current >= 0) ? current + get_sum(file) : 0);
}
 
 
int main()
{ifstream fin(INPUT_FILENAME);
if(!fin.is_open())
    {
        cerr << "Failed to open file!" << endl;
            getch();
        return(EXIT_FAILURE);
    }
    cout << "Sum is" << get_sum(fin) << endl;
 
    fin.close();
        getch();
    return(EXIT_SUCCESS);
}
Необходимо решить вторую задачку (над которой я замучился):

Дана последовательность ненулевых чисел, за которой следует ноль. Напечатать сначала все отрицательные числа, а затем - все положительные.

Помогите пожалуйста!


Подозреваю необходимо использовать 2 функции...
отрицательная и положительная

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
using namespace std;
 
double get_otr(ifstream& file)
{
    double current;
    file >> current;
    return((current <= 0) ? current + get_otr(file) : 0);
}
double get_pol(ifstream& file)
{
    double current;
    file >> current;
    return((current >= 0) ? current + get_pol(file) : 0);
}
что-то подобное, если я не ошибаюсь
как оформить main???(((

Добавлено через 6 минут
Блин(( Совсем не то...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.03.2011, 11:13
Здравствуйте! Я подобрал для вас темы с ответами на вопрос С Использованием рекурсии! (C++):

Сортировка с использованием рекурсии - C++
Здравствуйте. Задание : Написать рекурсивную функцию сортировки массива. Помогите пожалуйста найти алгоритмическую ошибку, так как...

решение задач с использованием рекурсии - C++
Ув Форумчане подскажите пожалуйста либо ресурс где это можно прочитать мне нужно эту тему расписать помогите пожалуйста :)

Выполнить задачу с использованием рекурсии - C++
Есть одномерный массив длиной N, заполненный числами от -10 до 10. Найти максимальную сумму, если можно брать следующий элемент, или через...

Решить задачу с использованием рекурсии - C++
Функция f(n) определена для целых положительных чисел следующим образом: f(n)=1, если n=1 или f(n)=сумма f(nDIVi) по i от 2 до...

Алгоритм Евклида с использованием рекурсии - C++
Моя реализация алгоритма Евклида с использованием рекурсивной функции. //Program finds greatest common divisor of two natural numbers....

Задание... о золотой горе с использованием рекурсии - C++
Пути в числовом треугольнике начинаются от верхнего числа. От любого числа можно перейти к одному из двух соседних чисел в следующей...

15
taras atavin
3570 / 1754 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
25.03.2011, 11:22 #2
Без параметра не может быть рекурсии.

Добавлено через 5 минут
Что вообще такое рекурсия? Рекурсия - это вызов подпрограммой себя же с другими значениями параметров, пока не поступит вызов с такими их значениями, при которых подпрограмма завершится не рекурсивно, то есть не вызывая себя. Если в цепочке рекурсивных вызовов нет такого, который вызовет экземпляр подпрограммы, завершаемый не рекурсивно, то такая цепочка рекурсивных вызовов бесконечна, а кроме как по параметру нельзя определить, когда надо прервать цепочку рекурсивных вызовов. Поэтому
C++
1
2
3
4
5
enytype f()
{
 ...
 return f();
}
- не рекурсия, а наглядное пособие, как делать не надо.
0
Nameless One
Эксперт С++
5777 / 3427 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
25.03.2011, 11:32 #3
Как вариант, можно использовать глобальную переменную и модифицировать уже ее. Условие остановки - некоторое значение глобальной переменной. Но так делать не есть хорошо.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
25.03.2011, 11:35 #4
ДРУГИЕ параметры вовсе не обязательны. Собственно, достаточно сделать проверку file.good() для корректного завершения рекурсии.

Цитата Сообщение от taras atavin Посмотреть сообщение
а кроме как по параметру нельзя определить
Глобальная переменная? .) Вовсе не обязательно что-либо передавать в рекурсивную функцию в качестве параметра. Даже никто не говорит, что рекурсия должна быть конечной. Это просто прямой или косвенный самовызов. Всё.

Добавлено через 1 минуту
Цитата Сообщение от Ruslan1991 Посмотреть сообщение
Напечатать сначала все отрицательные числа, а затем - все положительные.
Печатай за два прохода и не парься.)
Только в начало файла вернуться не забудь.
0
Nameless One
Эксперт С++
5777 / 3427 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
25.03.2011, 11:35 #5
Извиняюсь, невнимательно почитал задание.
Здесь действительно можно обойтись без параметров функции, а в качестве глобального параметра используется поток cin. Условие остановки - если введенный элемент равен нулю.
0
taras atavin
3570 / 1754 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
25.03.2011, 11:36 #6
Цитата Сообщение от Nameless One Посмотреть сообщение
Как вариант, можно использовать глобальную переменную и модифицировать уже ее. Условие остановки - некоторое значение глобальной переменной. Но так делать не есть хорошо.
Бред. Глобальная - она и в Африке глобальная и когда экзепляр вернёт управление предыдущему, для него она будет уже испорчена, так как в нём должна содержать то значение, которое имела при его вызове, а не следующего экземпляра в цепочке рекурсивных вызовов. Ладно ещё сделдать свой стек, а в нём эмулировать локальный параметр, так хоть получится, но зачем?
0
Nameless One
Эксперт С++
5777 / 3427 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
25.03.2011, 11:37 #7
Цитата Сообщение от Deviaphan Посмотреть сообщение
Печатай за два прохода и не парься.)
Зачем?
Примерно так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void rec()
{
  int num;
  std::cin >> num;
  if(num == 0)
    return;
  if(num < 0)
  {
    std::cout << num << std::endl;
    rec();
  }
  else
  {
    rec();
    std::cout << num << std::endl;
  }
}
2
taras atavin
3570 / 1754 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
25.03.2011, 11:38 #8
Цитата Сообщение от Nameless One Посмотреть сообщение
Извиняюсь, невнимательно почитал задание.
Здесь действительно можно обойтись без параметров функции, а в качестве глобального параметра используется поток cin. Условие остановки - если введенный элемент равен нулю.
В рекурсии?
0
Nameless One
Эксперт С++
5777 / 3427 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
25.03.2011, 11:39 #9
Цитата Сообщение от taras atavin Посмотреть сообщение
Бред. Глобальная - она и в Африке глобальная и когда экзепляр вернёт управление предыдущему, для него она будет уже испорчена, так как в нём должна содержать то значение, которое имела при его вызове, а не следующего экземпляра в цепочке рекурсивных вызовов. Ладно ещё сделдать свой стек, а в нём эмулировать локальный параметр, так хоть получится, но зачем?
Да ладно?
C
1
2
3
4
5
6
7
8
int global = 5;
int rec()
{
   if(global == 0)
      return 42;
   --global;
   return rec();
}
1
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
25.03.2011, 11:43 #10
Цитата Сообщение от Nameless One Посмотреть сообщение
Зачем?
Затем, что нуп и апазорился.)
Хорошее решение. Мне надо было думать до того, как говорю.
0
Nameless One
Эксперт С++
5777 / 3427 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
25.03.2011, 11:50 #11
Deviaphan, все когда-то были нубами, в этом нет ничего страшного. Программистами не рождаются .
Данный вариант плох тем, что есть угроза переполнения стека. Но, судя по условию, именно этот вариант и требуется.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
25.03.2011, 11:56 #12
Цитата Сообщение от Nameless One Посмотреть сообщение
Deviaphan, все когда-то были нубами, в этом нет ничего страшного
Я думал, что уж сто лет, как нет.) Ан нет, апазорился.)
0
Ruslan1991
0 / 0 / 0
Регистрация: 10.06.2010
Сообщений: 5
25.03.2011, 12:42  [ТС] #13
Спасибо Всем За Помощь!
0
easybudda
Модератор
Эксперт CЭксперт С++
9699 / 5649 / 964
Регистрация: 25.07.2009
Сообщений: 10,871
25.03.2011, 14:02 #14
Цитата Сообщение от Nameless One Посмотреть сообщение
Примерно так:
может чего не понял, но у меня вот в таком
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
#include <iostream>
using namespace std;
 
void rec()
{
  int num;
  std::cin >> num;
  if(num == 0)
    return;
  if(num < 0)
  {
    std::cout << num << std::endl;
    rec();
  }
  else
  {
    rec();
    std::cout << num << std::endl;
  }
}
 
int main(){
    rec();
    return 0;
}
виде вот как отработало:
Код
$ ./namelessone_rec
2
3
-4
-4
5
-6
-6
0
5
3
2
На самом деле прежде, чем это увидел, свою версию написал, почти такую же, но тоже для дурдома арифметика - положительные числа задом на перёд печатает
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
 
void prn(int * arr){
    if ( *arr > 0 ){
        prn(arr + 1);
        printf("%d ", *arr);
    }
    else if ( *arr < 0 ){
        printf("%d ", *arr);
        prn(arr + 1);
    }
}
 
int main(void){
    int arr[] = { 1, -4, 2, -3, 8, 5, -1, 0 };
    
    prn(arr);
    
    return 0;
}
0
Nameless One
Эксперт С++
5777 / 3427 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
25.03.2011, 14:39 #15
Цитата Сообщение от easybudda Посмотреть сообщение
может чего не понял, но у меня вот в таком
в принципе, ты понял все правильно Программа ведь делает как раз то, что нужно - печатает сначала отрицательные числа, потом положительные. Кто же виноват, что ввод и вывод смешиваются?
Нам же не сказано, в каком виде задана последовательность чисел. Это может быть и массив, как в твоем примере, а может быть и файл с данными.
Можно сделать и так:
Bash
1
2
3
4
5
6
7
8
nameless@nameless-desktop:~/cpp-sample$ echo "-1 8 5 -3 5 -4 0" | ./cpp-sample 
-1
-3
-4
5
5
8
nameless@nameless-desktop:~/cpp-sample$

Или так:
Bash
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
nameless@nameless-desktop:~/cpp-sample$ cat main.cc
#include <iostream>
 
void rec()
{
    int num;
    std::cin >> num;
 
    if(num == 0)
    return;
    if(num < 0)
    {
    std::cerr << num << std::endl;
    rec();
    } else {
    rec();
    std::cerr << num << std::endl;
    }
}
 
int main()
{
    rec();
    return 0;
}
nameless@nameless-desktop:~/cpp-sample$ ./cpp-sample 2>out.txt && echo Result && cat out.txt
-4
-2
8
-2
1
-3
0
Result
-4
-2
-2
-3
1
8
nameless@nameless-desktop:~/cpp-sample$


Вот еще вариант со списком аргументов переменной длины:
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
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
 
void rec(int, ...);
void va_rec(int, va_list);
 
int main(void)
{
    rec(8, -3, 14, -1, 23, -5, 6, 0);
    exit(0);
}
 
void rec(int first, ...)
{
    if(first)
    {
    va_list ap;
    va_start(ap, first);
    va_rec(first, ap);
    va_end(ap);
    }
}
 
void va_rec(int last, va_list ap)
{
    if(!last)
    return;
 
    int arg = va_arg(ap, int);
 
    if(last < 0)
    {
    printf("%d\n", last);
    va_rec(arg, ap);
    } else {
    va_rec(arg, ap);
    printf("%d\n", last);
    }
}
1
25.03.2011, 14:39
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.03.2011, 14:39
Привет! Вот еще темы с ответами:

Решение уравнения методом бисекции с использованием рекурсии - C++
Добрый день! Задачу задали в универе... Написать-то написал, сам метод халявный, но с рекурсией что-то запарился. 1....

Вычислении функции разложением ее в ряд с использованием рекурсии - C++
Составить программу вычисления заданной математической функции путем разложения ее в ряд. Программа должна применять рекурсивную функцию...

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

Программа должна вычислять значение функции exp(x) действительного аргумента x с точностью ε с использованием рекурсии. - C++
Построить рекурсивный алгоритм, записать алгоритм в виде блок-схемы и на алгоритмическом языке. Программа должна вычислять значение...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.