Sorting Genome Strings in C++ - c++

I'm creating a program that is meant to sort genome strings, and I've run into an issue with the output.
Code:
#include <iostream>
#include <string>
#include <cctype>
#include <cmath>
#include <algorithm>
using namespace std;
int main()
{
string genome;
cout << "Enter a genome string: ";
cin >> genome;
int geneCounter = 0;
while(!genome.empty()) //enters loop if strings not empty
{
if(genome.find("ATG") == string::npos)
{
if(geneCounter == 0)
{
cout << "No gene is found";
genome.clear();
}
return 0;
}
else
{
int startGene = genome.find("ATG");
int endGene = min(min(genome.find("TAG"), genome.find("TAA")), genome.find("TGA"));
string currentGene = genome.substr(startGene + 3, endGene - (startGene +3));
if((currentGene.length() % 3) == 0)
{
geneCounter += 3;
cout << currentGene <<endl;
}
endGene += 3;
genome.erase(0, endGene);
cout << genome;
}
}
return 0;
}
The code itself runs fine, it displays "No gene is found" correctly and doesn't stick me in a loop of not closing.
However, the string I'm being asked to test it with (TTATGTTTTAAGGATGGGGCGTTAGTT), does not output the correct results.
Whenever I input the string I get the following:
TTT
GGATGGGGCGTTAGTTGGGCGT
TT
When I should be getting:
TTT
GGGGCGT
I feel like I'm missing something very simple, any help would be appreciated.

Related

Binary number function

#include <iostream>
using namespace std;
void binary(unsigned a) {
int i;
cout << "0" << endl;
do {
for (i = 1; i < a; i=i/2) {
if ((a & i) != 0) {
cout << "1" << endl;
}
else {
cout << "0" << endl;
}
}
}
while (1 <= a && a <= 10);
}
int main(void) {
binary(4);
cout << endl;
}
I wrote a code about binary numbers. İt should give bits respect to entering number like for
4 (0100) for 2 (10). However my code goes infinity could you explain. I wrote in visual
studio and I cannot use <bits/stdc++.h> because there is no such a library in visual studio
Initially i is 1 but i = i / 2 sets i to 0, where it remains. The inner loop, therfore, loops for ever.
To output an unsigned number a in binary, use
#include <bitset>
#include <climits>
std::cout << std::bitset<sizeof(a) * CHAR_BIT>(a) << '\n';
(There is, at the time of writing no std::bin i/o manipulator cf. std::hex.)
Without using a built-in function, you can write your own function and perform your operation as follows.
Solution-1
#include <iostream>
void binary(unsigned int number)
{
if (number / 2 != 0) {
binary(number / 2);
}
std::cout << number % 2;
}
int main() {
binary(10);
}
Solution-2
#include <iostream>
#include<string>
void binary(unsigned int number)
{
std::string str = "";
while (number != 0) {
str = (number % 2 == 0 ? "0" : "1") + str;
number /= 2;
}
std::cout << str;
}
int main()
{
binary(4);
}
Note : Don't use using namespace std; . Why is "using namespace std;" considered bad practice?

Find second to last word in a string C++

Hi I need to find second to last word in a string. Right now below program is printing the last one.
#include <iostream>
#include <string>
using namespace std;
int main() {
string text{"some line with text"};
// find last space, counting from backwards
int i = text.length() - 2; // last character
while (i != 0 && !isspace(text[i]))
{
--i;
}
string lastword = text.substr(i+1); // +1 to skip leading space
cout << lastword << endl;
return 0;
}
Output: (Printing last word)
text
You can split the string into words and hold the previous word before saving the current word.
#include <iostream>
#include <string>
#include <sstream>
int main() {
std::string text{"some line with text"};
std::stringstream ss(text);
std::string previousword, lastword, newword;
while (ss >> newword) {
previousword = lastword;
lastword = newword;
}
std::cout << previousword << std::endl;
return 0;
}
Also note that using using namespace std; is discouraged.
You don't need any loops. Just add error checking:
int main() {
std::string text{ "some line with text" };
std::size_t pos2 = text.rfind(' ');
std::size_t pos1 = text.rfind(' ', pos2-1);
std::cout << text.substr(pos1+1, pos2-pos1-1) << std::endl;
return 0;
}
Just keep counting spaces until you arrive to the word you want or use a stringstream as MikeCAT proposed.
Here there is a function that finds any last word number without having to copy the entire string in a stringstream:
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
string getNLastWord(string text, int n)
{
bool insideAWord = false;
int wordNum = 0;
int wordEnd = -1;
for(int i = text.size() - 1; i > 0; i--)
{
if(text[i] != ' ' && !insideAWord)
{
wordNum++;
insideAWord = true;
}
else if(text[i] == ' ')
{
insideAWord = false;
}
if(wordNum == n)
{
wordEnd = i;
break;
}
}
if(wordEnd == -1)
{
cout << "There are no " << n << " words from right." << endl;
}
else
{
int wordStart;
for(wordStart = wordEnd; wordStart > 0; wordStart--)
{
if(text[wordStart] == ' ')
{
wordStart++;
break;
}
}
return text.substr(wordStart,wordEnd+1-wordStart);
}
return "";
}
int main() {
string text = "some text";
cout << getNLastWord(text,2);
return 0;
}

Trying to use getline (string) in C++ to parse a kml file

I'm using getline() to parse coordinate lines from a kml file into a vector.
The relevant part of the kml file looks like this (replaced numbers with x)...
<coordinates>
-xxxxxxxxx,xxxxxxxxx,0
-xxxxxxxxx,xxxxxxxxx,0
-xxxxxxxxx,xxxxxxxxx,0
-xxxxxxxxx,xxxxxxxxx,0
-xxxxxxxxx,xxxxxxxxx,0
-xxxxxxxxx,xxxxxxxxx,0
-xxxxxxxxx,xxxxxxxxx,0
-xxxxxxxxx,xxxxxxxxx,0
-xxxxxxxxx,xxxxxxxxx,0
-xxxxxxxxx,xxxxxxxxx,0
-xxxxxxxxx,xxxxxxxxx,0
-xxxxxxxxx,xxxxxxxxx,0
</coordinates>
When using getline() to print the kml file line by line it does it just fine so I figured something like this would work to parse coordinates into a vector...
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
vector <string> coordinates;
int main() {
fstream inputFile("Fish.kml", fstream::in);
string str;
bool running = true;
int counter = 0;
while (running) {
getline(inputFile, str, '\0');
if (str == " <coordinates>") {
counter++;
}
if (counter > 0 && str != " </coordinates>") {
coordinates.push_back(str);
}
if (counter > 0 && str == " </coordinates>") {
counter = -1;
running = false;
}
}
inputFile.close();
for (int i = 0; i < coordinates.size(); i++) {
cout << coordinates[i] << "\n";
}
return 0;
}
My thinking was to use if statements to check whether the getline() function is about to read the coordinates by checking if the line, "coordinates", has been read or not. If it has it will increase the counter to above zero that way in the next loop the rest of the program knows to start logging coordinates. Same thinking applies to stopping the code by checking to see if the line "/coordinates" has been read. It's all I could think of with my current knowledge, but obviously I must be missing something important because...
When I compile and run I don't get any errors but the program doesn't do anything. This is what it looks like, It does nothing, my computer fans kick on and I have to cancel the process...
irectory>test.exe
^C
Any ideas what is going on here?
Thank you!
Update:
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
vector <string> coordinates;
int main() {
fstream inputFile("Fish.kml", fstream::in);
string str;
bool running = true;
int counter = 0;
while (getline(inputFile, str, '\0')) {
if (str == " <coordinates>") {
counter++;
}
if (counter > 0 && str != " </coordinates>") {
coordinates.push_back(str);
}
if (counter > 0 && str == " </coordinates>") {
counter = -1;
inputFile.close();
}
}
for (int i = 0; i < coordinates.size(); i++) {
cout << coordinates[i] << "\n";
}
return 0;
}
I updated the code above as suggested and it does not get stuck while executing anymore. But it does not print the vector back. I'm not sure if it is failing to record the lines of coordinates or if I didn't print it properly.
replace while(running) with while(getline(inputFile, str) and remove running variable as it is no longer needed.
And also
if (str == "<coordinates>") {
counter++;
}
if (counter > 0 && str != "</coordinates>") {
coordinates.push_back(str);
}
if (counter > 0 && str == "</coordinates>") {
counter = -1;
}
Hopefully the following code would help you a little bit. I worte it myself. It only reads the first coordinates part.
//
// Created by albert on 4/1/22.
//
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
vector<float> split(string s, string del) {
int start = 0;
int end = s.find(del, start);
vector<float> ret;
while (end != string::npos) {
string substr = s.substr(start, end - start);
if (!substr.empty())
ret.push_back(stof(substr));
start = end + del.size();
end = s.find(del, start);
}
string substr = s.substr(start, end - start);
if (!substr.empty())
ret.push_back(stof(substr));
return ret;
}
int main() {
fstream istream;
istream.open("map.kml", fstream::in);
vector<vector<float>> coordinates;
bool flag = false;
if (istream.is_open()) {
cout << "file is open" << endl;
string str;
while (getline(istream, str, '\n')) {
if (str == " <coordinates>")
flag = true;
else if (str == " </coordinates>") {
flag = false;
break;
} else if (flag)
coordinates.push_back(split(str, string(1, ',')));
}
}
istream.close();
for (int i = 0; i < coordinates.size(); i++) {
cout << coordinates[i][0] << " " << coordinates[i][1] << " " << coordinates[i][2] << "\n";
}
cout << coordinates.size() << endl;
return 0;
}

C++ - Checking if a word is palindrome in struct data type

I want to know how to check if a word is palindrome in struct data type or object whatever you want to call it. I want to read a data from file then I need to check if that type of word that I have read is a palindrome or not. Also i need to reverse order of the words but I did that so do not need any help about that.
Here is the code:
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;
struct lettersStr
{
string name;
string object;
};
int main(int argc, char** argv)
{
ifstream letter;
letter.open("letter.txt");
lettersStr things[200];
int numberOfThings= 0;
while(letter >> letter[numberOfThings].name >> letter[numberOfThings].object)
{
numberOfThings++;
}
for (int i = 0; i < numberOfThings; i++)
{
cout << letter[i].name << " " << letter[i].object<< endl;
}
string names;
for (int i = 0; i < numberOfThings; i++)
{
names= things[i].name;
}
for (int i = numberOfThings- 1; i >= 0; i--)
{
cout << things[i].name << endl;
}
bool x = true;
int j = names.length() - 1;
for (int i = 0; i < j; i++,j--)
{
if (things[i].name.at(i) != things[i].name.at(j))
x = false;
if (x)
{
cout << "String is a palindrome ";
}
else
cout << "String is not a palindrome";
}
And here is the cout:
Kayak Audi
Ahmed Golf7
Ahmed
Kayak
String is not a palindrome
String is not a palindrome
I think major problem is this:
for (int i = 0; i < j; i++,j--)
{
if (things[i].name.at(i) != things[i].name.at(j))
x = false;
As you can see it wont cout right way of checking if a word is palindrome or not.
P.S: If this is a stupid question I am sorry, I am a beginner in C++ programming.
Cheers
As already pointed out in the comments, for (int i = 0; i < j; i++,j--) loops though things and the letters of their names simultaneously. You also have to account for cases where you compare a lower and an upper case letter such as the 'K' and 'k' at the beginning and end of 'Kayak'. You can use std::tolower for this.
Here is an example (live demo):
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
bool is_palindrome(std::string name)
{
if (name.empty())
return false;
// As has been pointed out, you can also use std::equal.
// However, this is closer to your original approach.
for (unsigned int i = 0, j = name.length()-1; i < j; i++,j--)
{
if (std::tolower(name.at(i)) != std::tolower(name.at(j)))
return false;
}
return true;
}
struct lettersStr
{
string name;
string object;
};
int main(int argc, char** argv)
{
std::vector<lettersStr> vec = {lettersStr{"Kayak","Boat"},lettersStr{"Audi","Car"}};
for (const auto &obj : vec)
if (is_palindrome(obj.name))
std::cout << obj.name << " is a palindrome" << std::endl;
else
std::cout << obj.name << " isn't a palindrome" << std::endl;
}
It gives the output:
Kayak is a palindrome
Audi isn't a palindrome

Unable to assign a range sub-string to an array of strings. c++

So I'm unable to create a substring cut using ranges. I am making an airport program where you feed the program a txt.file and it has to divide the lines I get from it into different strings. For instance, I have the following text data:
CL903 LONDON 41000 14.35 08906 //number of flight, destination, price, etc.
UQ5723 SYDNEY 53090 23.20 12986
IC5984 TORONTO 18030 04.45 03260
AM608 TOKYO 41070 18.45 11315
so the first string will be on the lines of this (variables are in Spanish):
numVuelo[n] = M[n].substr(0,5)
this line will work perfectly, but when I move to the next one (from 7 to 14), it tells me that it's out of range, even though It's between the 0 and 31st values of the length of the string.
M[n] gets all of the strings on the text, I'm using Codeblocks and a class style with header and all. I'll copy the code below...
This is my header Vuelo.h:
#ifndef VUELO_H
#define VUELO_H
#include <iostream>
#include <fstream>
#include <string>
#define NUM_FLIGHTS 10
using namespace std;
class Vuelo
{
public:
Vuelo(int N);
virtual ~Vuelo();
void setM();
void setNumVuelo(string _numVuelo, int n);
void setDestino(string _destino, int n);
void setPrecio(string _precio, int n);
private:
string M[NUM_FLIGHTS];
string numVuelo[NUM_FLIGHTS];
string destino[NUM_FLIGHTS+1]; //somehow "destino" doesn't work without the +1 but everything else does
float precio[NUM_FLIGHTS];
Then, on another code called Vuelo.cpp I have the following
#include "Vuelo.h"
Vuelo::Vuelo(int N)
{
M[N] = { };
numVuelo[N] = { };
destino[N] = { };
precio[N] = { };
}
Vuelo::~Vuelo()
{
//nope
}
void Vuelo::setM()
{
int c = 1;
string s;
ifstream F ("flights.txt");
if(F.is_open())
{
while (!F.eof())
{
getline(F,s);
M[c] = s;
cout << M[c] << endl;
c++;
}
//sets all values
for(c = 0; c < NUM_FLIGHTS; c++)
{
setNumVuelo(M[c],c);
setDestino(M[c],c);
setPrecio(M[c],c);
}
F.close();
}
else
{
cout << "ERROR document wasn't found" << endl;
}
}
void Vuelo::setNumVuelo(string _numVuelo, int n)
{
numVuelo[n]= _numVuelo.substr(0,5); //this works
cout << numVuelo[n] <<endl;
}
void Vuelo::setDestino(string _destino, int n)
{
destino[n] = _destino.substr(7, 13); //PROBLEM HERE
cout << destino[n] << " " << destino[n].length() << endl;
}
void Vuelo::setPrecio(string _precio, int n)
{
string p = _precio.substr(15,19); //PROBLEM HERE
precio[n] = atof(p.c_str());
cout << precio[n] <<endl;
}
And finally my main looks like this:
#include "Vuelo.h"
#include <iostream>
#include <fstream>
#include <string>
#define NUM_FLIGHTS 10
using namespace std;
int main()
{
cout << "Bienvenido, reserva tu vuelo!" << endl;
cout << "-----------------------------------" << endl;
Vuelo* flight = new Vuelo(NUM_FLIGHTS);
flight->setM();
return 0;
}
Thanks :)