HELPPPP RECURSIVE CODE

Need Help with this code, trying to make it recursive but it keeps giving me errors.
this is the assignment:
This is a void function.
* The base case will be that the iterator 'itr' is pointing to the end of codes, the set of strings.
* If itr is not at codes' end yet, then call listAllRNAStrandsFor() with a substring of the protein
* that excludes the first character (protein.substr(1)) but uses the overloaded function
* void listAllRNAStrandsFor(const string protein,
* map<char, set<string>> &encodings,
* const string RNA = "");
* where the second parameter is encodings, but the third parameter uses string concatenation: RNA + *itr
* then make the recursive call listAllRNAStrandsFor(protein, encodings, RNA, codes, ++it);
* with the incremented iterator.
}

/* Now the overloaded function will be defined like this:
* void listAllRNAStrandsFor(const string protein,
* map<char, set<string>> &encodings,
* const string RNA)
* {
* //if protein is the empty string (base case) then
* //print RNA and
* //return
* //otherwise listAllRNAStrandsFor(protein, encodings, RNA, encodings[protein[0]], encodings[protein[0]].cbegin());
*/



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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
 int main(){
map<char, set<string>> encs;
    string protein;
	const string RNA;
	const set<string>& codes = {};
	set<string>::const_iterator itr;
	int counter = 0;

	// Amino Acid (char) ... is encoded by RNA sequences (set<string>)
	encs['I'] = set<string>{ "AUU", "AUC", "AUA" };                       // Isoleucine
	encs['L'] = set<string>{ "CUU", "CUC", "CUA", "CUG", "UUA", "UUG" };  // Leucine
	encs['V'] = set<string>{ "GUU", "GUC", "GUA", "GUG" };                // Valine
	encs['F'] = set<string>{ "UUU", "UUC" };                              // Phenylalanine
	encs['M'] = set<string>{ "AUG" };                                     // Methionine
	encs['C'] = set<string>{ "UGU", "UGC" };                              // Cysteine
	encs['A'] = set<string>{ "GCU", "GCC", "GCA", "GCG" };                // Alanine
	encs['G'] = set<string>{ "GGU", "GGC", "GGA", "GGG" };                // Glycine
	encs['P'] = set<string>{ "CCU", "CCC", "CCA", "CCG" };                // Proline
	encs['U'] = set<string>{ "ACU", "ACC", "ACA", "ACG" };                // Threonine
	encs['S'] = set<string>{ "UCU", "UCC", "UCA", "UCG", "AGU", "AGC" };  // Serine
	encs['Y'] = set<string>{ "UAU", "UAC" };                              // Tyrosine
	encs['W'] = set<string>{ "UGG" };                                     // Tryptophan
	encs['Q'] = set<string>{ "CAA", "CAG" };                              // Glutamine
	encs['N'] = set<string>{ "AAU", "AAC" };                              // Asparagine
	encs['H'] = set<string>{ "CAU", "CAC" };                              // Histidine
	encs['E'] = set<string>{ "GAA", "GAG" };                              // Glutamic acid
	encs['D'] = set<string>{ "GAU", "GAC" };                              // Aspartic acid
	encs['K'] = set<string>{ "AAA", "AAG" };                              // Lysine
	encs['R'] = set<string>{ "CGU", "CGC", "CGA", "CGG", "AGA", "AGG" };  // Arginine
	encs['-'] = set<string>{ "UAA", "UAG", "UGA" };                       // Stop codons
	
	cout << setw(15) << " " << "The amino acids are LVFMCAGPUSYWQNHEDKER-.\n";
	cout << setw(15) << " " << "Enter a protein terminating with the \"-\" stop codon: ";
	while (cin >> protein) {
		listAllRNAStrandsFor(protein, encs, RNA,codes,itr);
	    cout << setw(15) << " " << "The amino acids are LVFMCAGPUSYWQNHEDKER-.\n";
		cout << setw(15) << " "	<< "Enter a protein terminating with the \"-\" stop codon: ";
	}
}



void  listAllRNAStrandsFor(const string protein, map<char, set<string>>& encodings,
	const string RNA, const set<string>& codes, set<string>::const_iterator itr)
{
	 
	
	
	if (itr != codes.end())// a problem
	  listAllRNAStrandsFor(protein.substr(1), encodings, RNA + *itr, codes, itr);
		listAllRNAStrandsFor(protein, encodings, RNA, codes, ++itr);
}

void listAllRNAStrandsFor(const string protein, map<char, set<string>> &encodings,
	const string RNA)
{ 
	if (protein.empty())
	{
		cout << RNA;
	}

	else
	listAllRNAStrandsFor(protein, encodings, RNA, encodings[protein[0]], encodings[protein[0]].cbegin());
}
Last edited on
Hi,

I guessing the base case for the first overload is line 49?

Also, on line 51, you have indentation, but only line 50 is associated with the if on line 49, so line 51 is always executed. Although the problem text seems to suggest that you need an else statement for line 51, which could make sense given your indentation.

To make sure this isn't a problem, the golden rule is always use braces - even if there is only 1 statement.
If it is like this
1
2
3
4
5
6
7
8
if (itr != codes.end())// a problem
	{
		listAllRNAStrandsFor(protein.substr(1), encodings, RNA + *itr, codes, itr);
	}
	
	
	else { listAllRNAStrandsFor(protein, encodings, RNA, codes, ++itr); }

It executes but as soon as the user input is inputted,i get an error that points to the base case and it shuts down
the error given is :Unhandled exception at 0x5C8AED76 (ucrtbased.dll) in Michelle Dozal Project 3.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.
Hi,

Have you tried looking at the code in a debugger? Hopefully there is a GUI version in your IDE :+)

If it says invalid parameter, then there is something wrong with the way the function is called. On line 44 RNA is a const string, but on line 50 you are appending *itr
Also, from where is the second overload called?
On the visual studios debugger the problem is the base case
and I fixed line 44 thank you.
No worries :+)

Just thinking that pseudo code comments taken from the assignment might have helped prevent these logical errors. It's easy to call the wrong function when one has overloaded recursive functions. Even if you remove the comments afterwards.

Another thing, just so you know for the future:

With STL containers that have iterators defined and one wants to traverse the whole container, one can use a range based for loop, and no iterators.

1
2
3
4
5
6
7
8
#include <set>
#include <iostream>
 
int main() {
  std::set<int> set = { 6, 1, 3, 4, 2, 5 };
  for (const auto& i : set)
    std::cout << i << "\n";
}


Even better, with a forward reference:

1
2
3
4
5
6
7
8
#include <set>
#include <iostream>
 
int main() {
  std::set<int> set = { 6, 1, 3, 4, 2, 5 };
  for ( auto&& i : set)
    std::cout << i << "\n";
}


The forward reference works with lvalues, rvalues, const and non-const, so it is the preferred method for generic programming.

Note one can't have:

for ( const auto&& i : set)

rather the container is sent to a function as const, if that is what one wants to do :+)

Good Luck !!

Edit:

Another thing, pass strings and other containers by reference, or std::move them.

Avoid having using namespace std;, instead put std:: before each std thing, this is what experienced C++ programmers do, one gets used to it. There is plenty written about this on the web.
Last edited on
I changed it to

1
2
3
4
5
6
7
8
9
if (itr != codes.end())
	{

		listAllRNAStrandsFor(protein.substr(1), encodings, RNA + *itr);
	}
		
	
	
	else { listAllRNAStrandsFor(protein, encodings, RNA, codes, ++itr); } 


but now it gives me the error

Error C2660: 'listAllRNAStrandsFor': function does not take 3 arguments
I am not sure why that is, can you post the code here, so that we can compile it ourselves?
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
#include <cmath>
#include <windows.h>
#include <fstream>
#include <map>
#include <set>

using namespace std;
 
int main()
{map<char, set<string>> encs;
    string protein;
	string RNA;
	const set<string>& codes = {};
	set<string>::const_iterator itr;
	int counter = 0;

	// Amino Acid (char) ... is encoded by RNA sequences (set<string>)
	encs['I'] = set<string>{ "AUU", "AUC", "AUA" };                       // Isoleucine
	encs['L'] = set<string>{ "CUU", "CUC", "CUA", "CUG", "UUA", "UUG" };  // Leucine
	encs['V'] = set<string>{ "GUU", "GUC", "GUA", "GUG" };                // Valine
	encs['F'] = set<string>{ "UUU", "UUC" };                              // Phenylalanine
	encs['M'] = set<string>{ "AUG" };                                     // Methionine
	encs['C'] = set<string>{ "UGU", "UGC" };                              // Cysteine
	encs['A'] = set<string>{ "GCU", "GCC", "GCA", "GCG" };                // Alanine
	encs['G'] = set<string>{ "GGU", "GGC", "GGA", "GGG" };                // Glycine
	encs['P'] = set<string>{ "CCU", "CCC", "CCA", "CCG" };                // Proline
	encs['U'] = set<string>{ "ACU", "ACC", "ACA", "ACG" };                // Threonine
	encs['S'] = set<string>{ "UCU", "UCC", "UCA", "UCG", "AGU", "AGC" };  // Serine
	encs['Y'] = set<string>{ "UAU", "UAC" };                              // Tyrosine
	encs['W'] = set<string>{ "UGG" };                                     // Tryptophan
	encs['Q'] = set<string>{ "CAA", "CAG" };                              // Glutamine
	encs['N'] = set<string>{ "AAU", "AAC" };                              // Asparagine
	encs['H'] = set<string>{ "CAU", "CAC" };                              // Histidine
	encs['E'] = set<string>{ "GAA", "GAG" };                              // Glutamic acid
	encs['D'] = set<string>{ "GAU", "GAC" };                              // Aspartic acid
	encs['K'] = set<string>{ "AAA", "AAG" };                              // Lysine
	encs['R'] = set<string>{ "CGU", "CGC", "CGA", "CGG", "AGA", "AGG" };  // Arginine
	encs['-'] = set<string>{ "UAA", "UAG", "UGA" };                       // Stop codons
	
	cout << setw(15) << " " << "The amino acids are LVFMCAGPUSYWQNHEDKER-.\n";
	cout << setw(15) << " " << "Enter a protein terminating with the \"-\" stop codon: ";
	while (cin >> protein) {
		listAllRNAStrandsFor(protein, encs, RNA,codes,itr);
	    cout << setw(15) << " " << "The amino acids are LVFMCAGPUSYWQNHEDKER-.\n";
		cout << setw(15) << " "	<< "Enter a protein terminating with the \"-\" stop codon: ";
	}
}

void  listAllRNAStrandsFor(const string protein, map<char, set<string>>& encodings,
	 string RNA, const set<string>& codes, set<string>::const_iterator itr)
{
	 
	
	
	if (itr != codes.end())
	{
		listAllRNAStrandsFor(protein.substr(1), encodings, RNA + *itr);
	}
		
	else { listAllRNAStrandsFor(protein, encodings, RNA, codes, ++itr); } 
}

void listAllRNAStrandsFor(const string protein, map<char, set<string>> &encodings,
	string RNA)
{ 
	if (protein.empty())
	{
		cout << RNA;
	}

	else
	listAllRNAStrandsFor(protein, encodings, RNA, encodings[protein[0]], encodings[protein[0]].cbegin());
}
Hi

I put the following function declarations after line 11 and it compiles:

1
2
3
4
5
void  listAllRNAStrandsFor(const string protein, map<char, set<string>>& encodings,
	 string RNA, const set<string>& codes, set<string>::const_iterator itr);
	 
void listAllRNAStrandsFor(const string protein, map<char, set<string>> &encodings,
	string RNA);
Last edited on
There is no output of the data, protein is const, how is it ever going to be empty? Apart from the const, what causes protein to be consumed by the program? That is how will it be empty, what is it that removes chars from the string?
RNA is uninitialized, rather it is empty "".

As is codes. Edit which is const.

More work at your end it seems :+)
Last edited on
Topic archived. No new replies allowed.