Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.02.2013, 11:38   #1
monster-bonster
Пользователь
 
Аватар для monster-bonster
 
Регистрация: 27.06.2012
Сообщений: 38
По умолчанию Рекурсия виновата

Привет уважаемые гуру.
Дана рекурсивно заданная функция

Код:
f(0) = 0;
f(2·x) = f(x);
f(2·x + 1) = f(x) + 1
Я написал рекурсивный вариант
и обнаружил что она работает медленно.
вот моя функция.

Код:
long f(long n)
{
        if (!n)
                return 0;
        else if (!(n%2))
                return f(n/2);
        else if (n%2)
                return f(n/2)+1;
}
помогите написать нерекурсивный вариант.
monster-bonster вне форума Ответить с цитированием
Старый 14.02.2013, 11:40   #2
monster-bonster
Пользователь
 
Аватар для monster-bonster
 
Регистрация: 27.06.2012
Сообщений: 38
По умолчанию

И какое время работы этой функции? (я думаю что log n)
monster-bonster вне форума Ответить с цитированием
Старый 14.02.2013, 11:50   #3
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Цитата:
Я написал рекурсивный вариант
и обнаружил что она работает медленно.
Как обнаружили?
Цитата:
И какое время работы этой функции? (я думаю что log n)
O(logN). Правильно думаете.
Цитата:
помогите написать нерекурсивный вариант.
Первое действие: перевести рекурсивную форму в хвостовую рекурсию.
Код:
long _f(long n, long ret)
{
        if (!n)
                return ret;
        else if (!(n%2))
                return _f(n/2, ret);
        else if (n%2)
                return _f(n/2, ret+1);
}

long f(long n) {return _f(n, 0)};
Чуть упростить...
Код:
long _f(long n, long ret)
{
        if (!n)
                return ret;
        return _f(n/2, (n%2) ? ret+1 : ret);
}

long f(long n) {return _f(n, 0)};
Второе действие: превратить хвостовую рекурсию в цикл.
Код:
long f(long n) {
  long ret = 0;
  while(n){
    if(n%2) ++ret;
    n /= 2;
  }
  return ret;
}
Чуть отполировать и убрать ветвление...
Код:
long f(long n) {
  long ret = 0;
  for(; n!=0; n>>=1) ret+=n&1;
  return ret;
}

Последний раз редактировалось Abstraction; 14.02.2013 в 11:54.
Abstraction вне форума Ответить с цитированием
Старый 14.02.2013, 12:04   #4
monster-bonster
Пользователь
 
Аватар для monster-bonster
 
Регистрация: 27.06.2012
Сообщений: 38
По умолчанию

А нет еще более быстрой функции? Я заметил
что эта функция возвращает количество нечетных
чисел до числа n+1.
monster-bonster вне форума Ответить с цитированием
Старый 14.02.2013, 12:19   #5
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Цитата:
А нет еще более быстрой функции? Я заметил
что эта функция возвращает количество нечетных
чисел до числа n+1.
Чего-о-о? Для n=128 результат будет 1. Что, до 129 всего одно нечётное число? И эта функция, вообще-то, слишком быстрая, чтобы выполняться сколько-нибудь заметное время на хоть сколько-нибудь современном процессоре - так что ещё раз: как Вы меряете скорость?
Впрочем, хотите быстрее - пожалуйста:
Код:
long f(long n) {
  int ret = 0;
  static int add[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
  for(; n!=0; n>>=4) ret+=add[n&0xF];
  return ret;
}
Можно увеличить add до 256 элементов - ускоритесь ещё в два раза, но за счёт памяти.
Abstraction вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Рекурсия unbanned Паскаль, Turbo Pascal, PascalABC.NET 7 19.01.2012 11:25
Рекурсия Надежда1286 Помощь студентам 3 27.11.2011 14:06
Рекурсия mishanya6 Помощь студентам 1 24.11.2011 11:27
Плохое кино? Виновата забастовка гильдии сценаристов США veter_s_morya Свободное общение 13 06.12.2010 12:33
Рекурсия Alexsey1991 Помощь студентам 1 12.05.2010 10:24