Определяне на цифри в естествено число - рекурсия и итерация

Под естествено число ще разбираме цяло положително число (1,2,3,...,n). Цифрите в 10-ична бройна система са 0,1,2,3,4,5,6,7,8,9 и също са числа. Алгоритъм за определяне броя и вида цифри в естествено число: въвежда се естествено число; това число се дели целочислено на основата на бройната система - в случая 10; последната (най-дясната) цифра може да бъде определена чрез операцията %, следващата стъпка е целочислено делене на 10 - премахваме последната цифра. Алгоритъмът продължава докато редуцираното число е по-голямо от 0. Всяка програма съдържаща цикличен алгоритъм може да се реализира, както с итерация, така и с рекурсия.

Тук целта е да се представят успоредно двата варианта - с рекурсия и итерация.
Задачата е следната:
От клавиатурата се въвежда естествено число N от интервала [1..10001].
Програмата трябва да изведе сумата на всички единици, участващи в изписването на числата от интервала [1..N] при представянето им в 2-ична бройна система.
Пример: 4 Изход: 5
1 – 1
2 - 10
3 – 11
4 – 100
Общият брой на 1-ците е 5.
Кратко описание на алгоритъма брой и вид цифри в двоично число.
Въвежда се естествено число.
Създадени са 2 вложени цикъла. Външният обхожда всички числа от интервала. Вътрешният брой всички единици на поредното число, чрез проверка на най-дясната цифра. След като е проверена тази цифра се изтрива.
В езика C/C++ има възможност да се работи директно с разрядите на въведеното число:
а) i & 1;//операция AND
дали въведеното число е четно или нечетно, дали последна цифра на това число в 2-ично представяне е 0 или 1
б) i=i>>1;//всички разряди се премества с 1 позиция надясно, т.е. маха се най-десния разряд, най-дясната цифра на въведеното число.
Същият резултат може да се постигне и чрез целочислено делене на 2 и проверка на целочисления остатък. Този подход е приложен във функцията redica2.
Реализацията на алгоритъма е в 3 варианта: чрез вложен цикъл (redica2), чрез 2 отделни цикъла (redica и chislo) и чрез съставна рекурсия (redica1 и chislo1).
За по-голяма яснота при съпоставяне рекурсия итерация освен една функция с вложен цикъл са реализирани две отделни функции.

Следващата примерна програма реализира решена задача за извеждане на всички цифри в естествено число чрез итерация.
#include <iostream>
using namespace std;

long chislo(long i)//wytreshen cikyl
 {long j;
  // iteratiwen wariant za prowerka broj cifri 1 w dwoichnoto predstawqne
  j=0;//inicializirane na suma ot 1 w dwoichnoto predstawqne
    while (i>0)
   {j +=i & 1;//operaciq AND dali chisloto e chetno ili ne, dali poslednata cifra e 0 ili 1
     i=i>>1;//izmestwane s 1 razrqd nadqsno  
    }//while 
   return j;
} // iteraciq broj cifri 1 w chisla 

long redica(long m)//wynshen cikyl
{ long j,k,n; 
   // wariant iteraciq za obhovdane na wsichki chisla ot interwala
   j=0;//inicializirane na obshata suma
  for (k=1; k<=m;k++)
    {n=chislo(k);//broj 1-ci w porednoto estestweno chislo
     j+=n;    // broj edinici w porednoto chislo
     //sledwashiq red e samo za iliustraciq - movete da go ostawite kato komentar
     //cout<<"Chisloto "<<k<<" w 2-ichna brojna sistema ima "<<n<<" broq 1-ci\n";
   }//for  
    return j; 
 }// iteraciq cifri w chislo 

long chislo1(long i)//wlovena rekursiq 
   { long m;
   // wariant rekursiq za prowerka broj 1-ci w dwoichnoto predstawqne
    m= i & 1;//dali poslednata mu cifra e 1
     if (i>0) {i=i>>1; return chislo(i)+m;}
    else return 0;    
}// rekursiq cifri 1 pri dwoichno predstawqne na chislo

 long redica1(long m)
   {//  wariant rekursiq za obhovdane na wsichki chisla ot interwala
      if (m>0) {return redica1(m-1)+chislo(m);}
      else return 0;
    }// rekursiq obhovdane na chisla 

   long redica2 (long m) //funkciq s wloven cikyl
    // wariant iteraciq s wloven cikyl za prowerka broj 1 w dwoichnoto predstawqne
   {long i,j,N,sum=0;
     for (i=1;i<=m;i++)//obhovdane na wsichki chisla ot interwala
   { N=i;//porednoto chislo ot interwala
    while (N>0)//broj 1-ci w chsiloto, predstaweno w 2-ichna brojna sistema
        { sum+=N%2;//dali chisloto e chetno - celochislen ostatyk
          N/=2; //namalqwame 2-pyti chisloto - celochisleno delene
     }//while
    }//for
   return sum;
}// iteraciq broj cifri 1 w chisla  

int main ()
{ long m,n; 
   char ose;
   cout<<"Imate wywedeno estestweno chislo M ot interwala [5..50005].\n";
   cout<<"Da se systawi programa,  chrez koqto se izchislqwa obshiq broj\n";
   cout<<"na 1-cite pri predstawqne na wsichki estestweni chisla ot 1\n";
   cout<<"do wywedenoto wkluichitelno w 2-ichna brojna sistema.\n";
   cout<<"Primer: 10 Izhod 17\n";
    do {
       cout<<"Wywedete chislo [5..1005]: ";cin>>m;
       n=redica(m);
       cout<<"Pri iteratiwniq wariant obsh broj 1-ci w redicata: "<<n<<endl; 
       n=redica1(m);//wsichki chisla ot interwala 1..m wkluichitelno
       cout<<"Pri wariant s rekursiq obsh broj 1-ci w redicata: "<<n<<endl;    
       n=redica2(m);
       cout<<"Pri wariant s wloven cikyl obsh broj 1-ci w redicata: "<<n<<endl; 
       cout<<"She wywevdate li drugi chisla <y/n>: ";cin>>ose;
    } while (ose=='y');
    system("pause");
    return 0;
}//kraj na programa cifri w chisla rekursiq

Описаните програми илюстрират идеята, че рекурсия и итерация са алтернативни подходи при решаване на широк кръг задачи. Изборът рекурсия или итерация трябва да бъде обвързан с конкретния проблем, а не да бъде самоцел.
Когато казваме, че една програма е рекурсивна се разбира, че тя съдържа в себе си поне една рекурсивна функция. Можете да разгледате множество програми съдържащи рекурсивна функция и в следните страници:
алгоритъм на Евклид за намиране най-голям общ делител
естествено число - римски цифри, палиндром
триъгълник от знаци
търсене на минимална стойност в редица
бързо сортиране - метод на Хоор
програма за извеждане на Питагорова тройка числа
програма за изчисляване на верижна дроб
диаметър на множество

Обяснени и решени задачи с подобни алгоритми, функции и служебни думи са разгледани в страницата с електронни уроци по информатика - програмиране.
Илюстриране работата на характерни алгоритми можете да намерите в предоставените електронни помагала съдържащи решени задачи, примери.

 
Размер на шрифта
Increase Font Size Option 3 Reset Font Size Option 3 Decrease Font Size Option 3
Bulgarian Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish
Търсене в сайта: