creating complement of DNA sequence and reversing it C++ - c++

So I am trying to create the complement of the sequence
TGAGACTTCAGGCTCCTGGGCAACGTGCTGGTCTGTGTGC
however my output didn't work as expected.
The complements for each letter in the sequence are
A -> T
G -> C
C -> G
T -> A
I've been programming in Java for over a year now so I've gotten really rusty with pointers in C++, I'm guessing the problem lies in the reverse methods and the way to pointers are shifted around through each pass of the function call
#include<stdio.h>
#include<iostream>
using namespace std;
void reverse(char s[]);
int main() {
char s[40] = {'T','G','A','G','A','C','T','T','C','A','G','G','C','T','C','C','T','G','G','G','C','A','A','C','G','T','G','C','T','G','G','T','C','T','G','T','G','T','G'};
cout << "DNA sequence: "<< endl << s << endl;
reverse(s);
cout << "Reverse Compliment: "<< endl << s << endl;
system("pause");
}
void reverse(char s[])
{
char c;
char *p, *q;
p = s;
if (!p)
return;
q = p + 1;
if (*q == '\0')
return;
c = *p;
reverse(q);
switch(c) {
case 'A':
*p = 'T';
break;
case 'G':
*p = 'C';
break;
case 'C':
*p = 'G';
break;
case 'T':
*p = 'A';
break;
}
while (*q != '\0') {
*p = *q;
p++;
q++;
}
*p = c;
return;
}

Standard modern C++ makes this low-level, pointer-oriented programming, unnecessary (in fact, you're effectively writing C).
Once you have a function, say complement, which transforms a nucleotide to its complement, you just need to apply some standard library function like transform.
Here is a rewrite of your program in C++11:
#include <string>
#include <iostream>
#include <algorithm>
#include <cassert>
using namespace std;
char complement(char n)
{
switch(n)
{
case 'A':
return 'T';
case 'T':
return 'A';
case 'G':
return 'C';
case 'C':
return 'G';
}
assert(false);
return ' ';
}
int main()
{
string nucs = "ACAATTGGA";
transform(
begin(nucs),
end(nucs),
begin(nucs),
complement);
cout << nucs << endl;
}

std::string style, looks easy and clean: I presume it may be useful to OP or others.
creating complement of DNA sequence and reversing it C++
In other words, it is reverse complement of a DNA sequence, which can be easily achieved by reversing the DNA sequence and then getting its complement. Or getting the complement and then reversing. An example is shown below.
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
std::string DNAseq = "TGAGACTTCAGGCTCCTGGGCAACGTGCTGGTCTGTGTGC";
reverse(DNAseq.begin(), DNAseq.end());
for (std::size_t i = 0; i < DNAseq.length(); ++i){
switch (DNAseq[i]){
case 'A':
DNAseq[i] = 'T';
break;
case 'C':
DNAseq[i] = 'G';
break;
case 'G':
DNAseq[i] = 'C';
break;
case 'T':
DNAseq[i] = 'A';
break;
}
}
std::cout << "reverse complement : " << DNAseq << std::endl;
return 0;
}

Change the reverse method like this
void reverse(char s[])
{
while (*s) {
switch(*s) {
case 'A':
*s = 'T';
break;
case 'G':
*s = 'C';
break;
case 'C':
*s = 'G';
break;
case 'T':
*s = 'A';
break;
}
++s;
}
return;
}
...and you will get correct result.
If you don't like pointers, please, don't use them! In modern C++ pointers aren't often necessary. The following code is C++11 (do you have C++11 compiler?) written as I would do it.
#include <string>
#include <iostream>
#include <algorithm>
std::string reverse(std::string seq)
{
auto lambda = [](const char c) {
switch (c) {
case 'A':
return 'T';
case 'G':
return 'C';
case 'C':
return 'G';
case 'T':
return 'A';
default:
throw std::domain_error("Invalid nucleotide.");
}
};
std::transform(seq.cbegin(), seq.cend(), seq.begin(), lambda);
return seq;
}
int main()
{
std::string seq("TGAGACTTCAGGCTCCTGGGCAACGTGCTGGTCTGTGTG");
std::cout << "DNA sequence: " << std::endl << seq << std::endl;
seq = reverse(seq);
std::cout << "Reverse Compliment: " << std::endl << seq << std::endl;
system("pause");
return EXIT_SUCCESS;
}
Some notes:
Use default in switch statement.
In C++ it's better to return a value from a function than to manipulate a variable via pointer.
Prefer std::string to plain char.

Related

C++ program to convert string to numeric digits

I'm trying to create a function that converts input words to numeric digits like a mobile numpad. It is for an assignment. I cannot use cstring or character arrays.
Can someone please identify and correct the error in my code? It currently gives the error: ISO C++ forbids comparison between pointer and integer [-fpermissive].
I am not using any pointer variables. I do have used the strlen() function to determine the exact place of a character in a string. Any help is greatly appreciated.
#include<iostream>
#include<conio.h>
#include<string.h>
#include<stdio.h>
using namespace std;
void Letter_correspondence();
int main()
{
Letter_correspondence();
return 0;
}
void Letter_correspondence()
{
cout<<"Enter the letters of the word you want to convert to numbers: ";
char a[]="Hello";
char b[]="world";
int len=strlen(a);
int lenb=strlen(b);
int n;
int l=a[n];
for (n=0;n<=7;n++)
{
while (n<=len)
{
if (l=="a"||l=="b"||l=="c")
{
if (n==2)
{
cout<<"-";
}
cout<<"2";
}
else if (l=="d"||l=="e"||l=="f")
{
if (n==2)
{
cout<<"-";
}
cout<<"3";
}
else if (l=="g"||l=="h"||l=="i")
{
if (n==2)
{
cout<<"-";
}
cout<<"4";
}
else if (l=="j"||l=="k"||l=="l")
{
if (n==2)
{
cout<<"-";
}
cout<<"5";
}
else if (l=="m"||l=="n"||l=="o")
{
if (n==2)
{
cout<<"-";
}
cout<<"6";
}
else if (l=="p"||l=="q"||l=="r"||l=="s")
{
if (n==2)
{
cout<<"-";
}
cout<<"7";
}
else if (l=="t"||l=="u"||l=="v")
{
if (n==2)
{
cout<<"-";
}
cout<<"8";
}
else if (l=="w"||l=="x"||l=="y"||l=="z")
{
if (n==2)
{
cout<<"-";
}
cout<<"9";
}
}
}
}
If I understood this right, you're trying to map characters to different ones and print them. You said you cannot use cstring or character arrays, but you do that here:
char a[]="Hello";
char b[]="world";
Instead, I would just use std::string:
std::string a = "Hello";
You can then iterate through it using a range-based for loop. The best way to print your string would probably be using a switchstatement:
for (char &c : a)
{
switch (tolower(c)) {
case 'a':
case 'b':
case 'c':
std::cout << 2;
break;
case 'd':
case 'e':
case 'f':
std::cout << 3;
break;
case 'g':
case 'h':
case 'i':
std::cout << 4;
break;
case 'j':
case 'k':
case 'l':
std::cout << 5;
break;
case 'm':
case 'n':
case 'o':
std::cout << 6;
break;
case 'p':
case 'q':
case 'r':
case 's':
std::cout << 7;
break;
case 't':
case 'u':
case 'v':
std::cout << 8;
break;
case 'w':
case 'x':
case 'y':
case 'z':
std::cout << 9;
break;
default:
std::cout << c;
}
}
If you're using an old version of C++ that doesn't support range based for loops, change this
for (char &c : a)
{
switch (tolower(c)) {
To this
for (size_t i = 0; i < a.size(); i++)
{
switch (tolower(a[i])) {
And std::cout << c; to std::cout << a[i];.

C++ set a char value to a string?

This outputs upper case 'S' or 'P' regardless of the users choice to type lower case or not.
The output works when I cout with the other statements in my code
HOWEVER... I want to display STANDARD or PREMIUM in my final cout statement.
How can I change the value of the char to output either STANDARD or PREMIUM???
#include <string>
#include <iostream>
char meal;
cout << endl << "Meal type: standard or premium (S/P)? ";
cin >> meal;
meal = toupper(meal);
if (meal == 'S'){
meal = 'S';
}
else{
meal = 'P';
}
I've tried meal = 'Standard' and meal = 'Premium'
It doesn't work.
#include<iostream>
#include<string>
using namespace std;
int main(int argc, char* argv)
{
char meal = '\0';
cout << "Meal type: standard or premium (s/p)?" << endl;;
string mealLevel = "";
cin >> meal;
meal = toupper(meal);
if (meal == 'S'){
mealLevel = "Standard";
}
else{
mealLevel = "Premium";
}
cout << mealLevel << endl;
return 0;
}
declare extra variable string mealTitle;, then do if (meal == 'P') mealTitle = "Premium"
#include <string>
#include <cstdio>
#include <iostream>
using namespace std;
int main(void) {
string s = "Premium";
cout << s;
}
You cannot change the variable meal to be a string, because its type is a char. Just use another object with a different name:
std::string meal_type;
switch (meal) {
case 'P':
meal_type = "Premium";
break;
case 'S':
default:
meal_type = "Standard";
break;
}
#include <string>
#include <iostream>
std::string ask() {
while (true) {
char c;
std::cout << "\nMeal type: standard or premium (S/P)? ";
std::cout.flush();
if (!std::cin.get(c)) {
return ""; // error value
}
switch (c) {
case 'S':
case 's':
return "standard";
case 'P':
case 'p':
return "premium";
}
}
}
int main() {
std::string result = ask();
if (!result.empty()) {
std::cout << "\nYou asked for " << result << '\n';
} else {
std::cout << "\nYou didn't answer.\n";
}
return 0;
}

PigLatin C++ function

This code is giving me a lot of strange errors. For whatever reason, the "newstring" function is not running. I think it may have something to do with the fact that it is part of a cout statement, because if I remember correctly, it does not give the same error if I call the function independently of the cout statement. The program requires a string function, but the new function is not running for some reason. Could anyone take a look at the code?
#include <iostream>
#include <string>
using namespace std;
void newstring(string);
bool isVowel(char ch);
string rotate(string pStr);
string pigLatinString(string pStr);
int main()
{
string str;
cout << "Enter a sentence to be translated to Pig Latin: ";
getline(cin, str);
cout << endl;
cout << "The pig Latin form of " << str << " is: " << newstring(str);
system("PAUSE");
return 0;
}
bool isVowel(char ch)
{
switch(ch)
{
case 'A':
case 'E':
case 'I':
case 'O':
case 'U':
case 'Y':
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
case 'y':
return true;
default:
return false;
}
}
string rotate(string pStr)
{
string::size_type len = pStr.length();
string rStr;
rStr = pStr.substr(1, len - 1) + pStr[0];
return rStr;
}
string pigLatinString(string pStr)
{
string :: size_type len;
bool foundVowel;
if (isVowel(pStr[0]))
pStr = pStr + "-way";
else
{
pStr = pStr + '-';
pStr = rotate(pStr);
len = pStr.length();
foundVowel = false;
for ( int counter = 1; counter < len - 1; counter++)
{
if (isVowel(pStr[0]))
{
foundVowel = true;
break;
}
else
pStr = rotate(pStr);
if (!foundVowel)
pStr = pStr.substr(1, len) + "-way";
else
pStr = pStr + "ay";
}
return pStr;
}
}
string newstring(string sentence)
{
string newsentence, currentword;
for (int i = 0; i < sentence.length(); i++)
{
if (sentence[i]==' ')
{
pigLatinString(currentword)+" ";
currentword.clear();
}
else
{
currentword+=sentence[i];
}
}
return newsentence;
}
Your newstring prototype is wrong.
void newstring(string);
Should be
string newstring(string);
Function newstring is declared as having type void
void newstring(string);
You may not create objects of type void and send them in an output stream
cout << "The pig Latin form of " << str << " is: " << newstring(str);
Also the function has no definition because you defined another function with the same name but returning std::string
string newstring(string sentence)
^^^^^^^^^^^^^^^^^^
pigLatinString(currentword)+" ";
pigLatinString returns a string, but you don't do anything with that result.
newstring returns newsentence, but is is empty.
Maybe you should fill newsentence with what is returned from pigLatinString?
Oh, and now I notice you have two newstrings... a void and a string...

class initialization in C++

I tried to initialize an array of a class then use a loop to change the data members in each of the objects. I'm not sure how to get the values to stick, because after I changed the values, I tried to print a random object out and it's just the default values and not the changed values. Any help would be appreciated, Thanks!
#include <iostream>
#include <string>
#include <time.h>
using namespace std;
class card {
private:
int rank;
int suit;
////////////////////////////////////////////////////////////
public:
/////////////////////////////////////////////////////////////
// default constructor with initialization list
card(int userRank = (2,3,4,5,6) , int userSuit=15)
:rank(userRank), suit(userSuit){}
///////////////////////////////////////////////////////////
// function to validate user's rank choice.
int cardcheckRank(int pRank){
while(pRank<2 || pRank>14)
{
cout << "Choose a playing card rank between 2-14, where 11=Jack, "
"12=Queen, 13=King, 14=Ace"<<endl;
cin >> pRank;
}
return pRank;
}
/////////////////////////////////////////////////////////////
// function to validate user's suit choice.
int cardcheckSuit(int pSuit){
while(pSuit<15 || pSuit>18)
{
cout << "Choose a playing card suit "
"between 15-18, where 15=Diamond, 16=Club, 17=Heart, 18=Spades.";
cin >> pSuit;
}
return pSuit;
}
//////////////////////////////////////////////////////////////////
// functioin to get a card value from user.
void storeCard(int pRank, int pSuit){
card(cardcheckRank(pRank),cardcheckSuit(pSuit) );
}
/////////////////////////////////////////////////////////////////
// translates
string faceRank(int translateRank){
switch (translateRank) {
case 2:
return "Two";
case 3:
return "Three";
case 4:
return "Four";
case 5:
return "Five";
case 6:
return "Six";
case 7:
return "Seven";
case 8:
return "Eight";
case 9:
return "Nine";
case 10:
return "Ten";
case 11:
return "Jack";
case 12:
return "Queen";
case 13:
return "King";
case 14:
return "Ace";
default: return "Invalid";
}
}
///////////////////////////////////////////////////////////
// translate integer suit value into a word.
string faceSuit(int translateSuit){
switch (translateSuit){
case 15:
return "Diamonds";
break;
case 16:
return "Clubs";
break;
case 17:
return "Hearts";
break;
case 18:
return "Spades";
break;
default: return "Invalid";
}
}
///////////////////////////////////////////////////////
// Function to print the current card.
void printCard(){
cout << "The rank of the card is ";
cout << faceRank(rank);
cout << " and the suit is " << faceSuit(suit) << "." << endl;
}
}; // End of card class.
//////////////////////////////////////////////////////
// main function.
int main()
{
srand (time(NULL)); // initialize random seed.
card deck[52];
char choice = 'n';
int h = 0; // card number.
for(int i = 15; i < 19; i++)
{
int y = i;
for(int j =2; j < 15; j++)
{
int z = j;
(deck [h]).storeCard(z,y);
cout << "Card rank " << (deck [h]).faceRank(z);
cout << ", suit " << (deck [h]).faceSuit(y) <<endl;
++h;
}
}
do{
cout <<"Would user like to play?(y/n)"<<endl;
cin >> choice;
int ranNum = (rand()% 51 + 0);
if(choice == 'y')
{
cout << "User: ";
deck[7].printCard();
}
}
while(choice == 'y');
return 0;
}
Values are not sticking because your storeCard function doesn't really store the card, it creates a new card object and throws it away. If you really want to express this by invoking the card constructor, then assign the constructed object to the current one:
void storeCard(int pRank, int pSuit){
*this = card(cardcheckRank(pRank),cardcheckSuit(pSuit) );
}
A more idiomatic approach would be for storeCard to directly modify the object's attributes, much like the constructor does:
void storeCard(int pRank, int pSuit){
rank = cardcheckRank(pRank);
suit = cardcheckSuit(pSuit);
}

converting Roman numerals into decimal

Hey guys I think I'm really close with but I'm not too sure how to continue. All of the questions related to my problem don't really answer anything. The error that I'm getting right now is an
(33): error C2064: term does not evaluate to a function taking 1 arguments
(41): error C2064: term does not evaluate to a function taking 1 arguments
Header file:
using namespace std;
class romanType
{
public:
void printRoman(char romanNum);
int printDecimal(int& total);
int convertRoman(int& total);
void setRoman(char& roman);
romanType();
romanType(char);
private:
char romanNum[6];
int decimal;
int total;
};
Implementation:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include "romanType.h"
using namespace std;
romanType::romanType(char)
{
};
void romanType::printRoman(char romanNum)
{
cout << "Here is your number in Roman Numeral form: " << romanNum << endl;
};
int romanType::printDecimal(int& total)
{
cout << "Here is your number in Decimal form: " << total << endl;
return total;
};
void romanType::setRoman(char& romanNum)
{
};
int romanType::convertRoman(int& total)
{
int len = 0;
len = strlen(romanNum);
int count[1];
for(int i = 0; i < len; i++)
{
switch(romanNum[i])
{
case 'M':
count[i] = 1000;
break;
case 'm':
count[i] = 1000;
break;
case 'D':
count[i] = 500;
break;
case 'd':
count[i] = 500;
break;
case 'C':
count[i] = 100;
break;
case 'c':
count[i] = 100;
break;
case 'L':
count[i] = 50;
break;
case 'l':
count[i] = 50;
break;
case 'X':
count[i] = 10;
break;
case 'x':
count[i] = 10;
break;
case 'V':
count[i] = 5;
break;
case 'v':
count[i] = 5;
break;
case 'I':
count[i] = 1;
break;
case 'i':
count[i] = 1;
break;
default:
cout << "Error.." << endl;
}
total = total + count[0];
}
return total;
};
My main:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include "romanType.h"
using namespace std;
int main()
{
romanType r;
char romanNum;
char choice;
int decimal;
int total;
cout << "Hello! Please enter your Roman Numeral: " << endl;
cin >> romanNum;
cout << endl;
r.setRoman(romanNum);
r.convertRoman(total);
cout << "Do you want the Roman Numeral or the Decimal?" << endl;
cout << "Press [D] for Decimal!" << endl << "Press [R] for Roman Numeral!" << endl;
cin >> choice;
if (choice == 'D' || choice == 'd')
r.printDecimal(total);
else if (choice == 'R' || choice == 'r')
r.printRoman(romanNum);
else
cout << "That wasn't the right button!" << endl;
system ("pause");
return 0;
}
I'm pretty sure I'm on the right track. It would be nice to see any tips or advice relating to my errors.
Thanks in advance
From just a quick look at the code, I might suggest looking through the debug window at the values of your variables at each step. What I am seeing is two variables, one char type named romanNum, and an entirely different one that is a char array named romanNum. It gets a little confusing but could work if you are only asking the user for a single char in roman numerals which then you wouldn't need an array at all. Otherwise, you could get a string then convert that into an array.
Start there and see if that helps.