Recursive Functions

Need a recursive function to print the alphabet in the reverse order (z-a) ?

1
2
3
4
5
6
7
8
9
10
void print(char p)
{
if (p=='z')
   return ;
print(p-1);

cout<<p;

return ;
} 


This prints in the normal order , but with
unwanted symbols .
I recommend you play around with the basic elements of your function (the if block, the recursive call, and the print statement) until you understand what's going on here and why it doesn't work. I could tell you exactly what to do, but I think it's best if you figure out how recursion works on your own.
O:o
If you haven't gotten it yet, answer this: what is z-1 as an integer? how about as a character? How about a-1 as integer/character? Walk through the function in your head (or in your debugger). Or, instead of outputting the character using cout, try: cout << (int)p << endl;
It is not a simple task as it is described here by others and I wonder why such difficult task is assigned to beginners.

First of all if you need to output the alphabet in reverse order then the function shall not have a parameter because the alphabet is a defined entity. The parameter is needed only when you want to output some arbitrary sequence of symbols that is set by a user but the alphabet is already defined entity that does not depend on a start element of a sequence given by a user.

I will show a recursive function that outputs letters from 'Z' to 'A'. You can change it such a way that it will output letters from 'z' to 'a'.

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
#include <iostream>

void print_alphabet()
{
	static char c = '@';

	if ( c == '@' ) c = 'Z';

	if ( c == 'A' )
	{
		std::cout << c << std::endl;
		c--;
	}
	else
	{
		std::cout << c << ' ';
		c--;
		print_alphabet();
	}
}


int main()
{

	print_alphabet();

	return 0;
}
Your solution really over-complicates the problem, given the presumed level of OPs education. What happens if the professor calls the function twice as part of his/her test? From multiple threads? The 'shall not have a parameter' is not an appropriate assumption in general, especially for an intro class. The above will only confuse someone struggling with their first foray into recursion, who may not even know what a static local variable is.


Last edited on
It is not a simple task as it is described here by others
It's a basic exercise on recursion. I can't imagine what you see in it that makes you think it's not.

I think the best part is that there was a solution far simpler (and better) than that ugly thing you put up there:
1
2
3
void print_alphabet(){
    print_alphabet('z');
}

@helios
I can't imagine what you see in it that makes you think it's not.



The assignment says to write a function not to write functions.
> It is not a simple task as it is described here

A recursive function to print the decimal digits in reverse order (9-0) is trivial;
we know that char('9'-1) == '8', char('8'-1) == '7' and so on.

Either:
1
2
3
4
5
void print_digits1( char digit = '9' )
{
    std::cout << digit ;
    if( digit > '0' ) print_digits1( digit-1 ) ;
}

Or:
1
2
3
4
5
void print_digits2( char digit = '0' )
{
    if( digit < '9' ) print_digits2( digit+1 ) ;
    std::cout << digit ;
} 



A recursive function to print the alphabetic characters in reverse order (z-a) is not as trivial;
since we can't assume that char('z'-1) == 'y' etc. would always be true.

1
2
3
4
5
void print_alpha( const char* a_to_z = "abcdefghijklmnopqrstuvwxyz", std::size_t pos = 25 )
{
   std::cout << a_to_z[pos]  ;
   if( pos > 0 ) print_alpha( a_to_z, pos-1 ) ;
}

Last edited on
@JLBorges


As I pointed out your approach is incorrect. The function shall not have any parameter because such entity as alphabet is already defined. That is there is such entity (defined before the task) and you need to output it. When you specify parameters as you did

( const char* a_to_z = "abcdefghijklmnopqrstuvwxyz", std::size_t pos = 25 )

You are in fact defining the alphabet anew and moreover defining it incorrectly because the English alphabet has fixed number of symbols that is equal to 26. Alphabet is not a sequence with variable length of symbols. The number 26 is a property of the alphabet.

You should consider the task the following way: there is an object already defined that has its own properties and you should output it in the reverse order. In your example you are trying to redefine the object and moreover its properties are undefined because user can specify 5 enstead of 25 or "!@#$%" instead of the alphabet.
So your code performs another task than it is required.
Last edited on
> such entity as alphabet is already defined.

Not by C++.

The basic execution character set and the basic execution wide-character set shall each contain all the members of the basic source character set, plus control characters representing alert, backspace, and carriage return, plus a null character (respectively, null wide character), whose representation has all zero bits. For each basic execution character set, the values of the members shall be non-negative and distinct from one another. In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous. The execution character set and the execution wide-character set are implementation-defined supersets of the basic execution character set and the basic execution wide-character set, respectively. The values of the members of the execution character sets and the sets of additional members are locale-specific.


Which is why your offering of:
1
2
3
4
5
6
if ( c == 'A' )
{
    std::cout << c << std::endl;
    c--;
}
// etc  
is not merely incorrect; it is laughable.

In contrast, the idea by helios has the great merit of simplicity, (and as he points out, does not suffer from ugliness), and to boot, would probably meet the requirements of MAQAH adequately.
Last edited on
@JLBorges
> such entity as alphabet is already defined.
Not by C++.


Why not in C++?! Is it difficult to define a container Alphabet which will have fixed number of elements?

So imagine that you have such a container. Its properties are already defined. And you need to write a recursive function with the following declaration

void print_alpha( const Alphabet &a );

This definition of the task is fully corresponds to the original task.

And what are you finding laughable in my function? I can rewrite the code snip which you consider as laughable the following way

1
2
3
4
5
6
7
Alphabet a;
//...
if ( c == a.first_letter() )
{
    std::cout << c << std::endl;
    c--;
}


Now is it more laughable?:)

EDIT: When you are using such word as "alphabet" it means that this enity is already defined and everybody knows what you are saying about. You shall not give your own definition of the entity. Otherwise nobody will understand what you are speaking about. So the function shall deal with common accepted already defined entity that called the alphabet.
Last edited on
> Now is it more laughable?:)

It is just as laughable, and just as incorrect as your original offering. Though on the ugliness front you have are making admirable progress. It has indubitably become even more ugly.



It seems that you do not understand what I am speaking about. Your remarks about the execution character set and the wide character set are unserious because the class Alphabet can be defiined with 1) the class traits; 2) with a locale. So it is a detail of the definition and should not be taken into acount when the function is being written because you will deal with a common interface as I showed. I can it rewrite in a more strictly manner

1
2
3
4
5
6
7
8
9
10
Alphabet a;
//...

Alphabet::value_type c;
//...
if ( c == a.first_letter() )
{
    std::cout << c << std::endl;
    c--;
}



Moreover the expression c--; may be substituted for a method a.prev(); or a-- and so on. What is the problem? But in any case you should not write the function the way you did. What about for example Russian alphabet?
Last edited on
That it would be more clear what I want to say is that I would like to point out that your realization is not error-prone. For example nothing prevents to call the function as

print_alpha( "abcdefghijklmnopqrstuvwxyz", 60 );

or

print_alpha( "abcdefghijklmnopqrstuvwxyz", 26 );

or

print_alpha( "abc^%$hijklmnopqrstuvwxyz", 25 );

and so on. So it follows that the properties of the alphabet shall be hiden from a user. In this case we are returning to the realization consisting of two functions. The first one will not have parameters and the second one will correspond to your function definition.

void print_alpha( const char* a_to_z = "abcdefghijklmnopqrstuvwxyz", std::size_t pos = 25 )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void print_alpha()
{
   static const char a[] = "abcdefghijklmnopqrstuvwxyz";
   print_alpha( a, siizeof( a ) - 1 );
}

void print_alpha( const char *a, size_t n )
{
   std::cout << a[--n];
   if ( n != 0 )
   {
      std:;cout << ' ';
      print_alpha( a, n );
   }
}


But in this case the assignment should be formulated as write functions (not a function) that recursively output the alphabet in the reverse order.



Last edited on
It's a basic assignment on recursion, guys. I doubt whoever wrote it had in mind that the student would even consider non-contiguous alphabetic characters or any other such minuscule details.

But hey, great job on flooding the thread with pointless arguments. I'm sure the OP wasn't confused by any of it at all.

Geez...
Last edited on
@MAQAH

Here is a very simple way to print the alphabet in reverse order using recursion.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

using namespace std;

void print(char);

int main()
{
    char x = '\x7A'; // lower-case z
    print(x);
   
   cout << endl << endl;
   return 0;
}

void print(char p)
{
   cout<<p;
   if (p=='a')
   return ;

   print(p-1);
} 
Last edited on
Or even simpler...

1
2
3
4
5
void print(char p='a')
{
   if (p < 'z') print(p+1);
   cout<<p;
}
closed account (o1vk4iN6)
Or even with templates...

1
2
3
4
5
6
template< char A = 'a', char B = 'z' >
void print_range_rev()
{
      std::cout << B;
      if( A != B ) print_range_rev< A, B - 1 >();
}


Topic archived. No new replies allowed.