Complementary DNA(C++) - string

Task:Write a code to the new string of Dna According to its pattern. Just so you know In DNA strings, symbols "A" and "T" are complements of each other, as "C" and "G".
Fore example:DNA_strand ("ATTGC") //returns "TAACG" or DNA_strand ("GTAT") //returns "CATA"
My Code=>
#include <string>
#include <vector>
#include <iostream>
std::string DNAStrand(const std::string& dna)
{
std::string Sym;
std::string c;
std::stringstream s;
s << Sym;
s >> c;
for(int i = 0; i < dna.size() - 1; i++) {
switch (dna[i]) {
case ('A'):
Sym[i] = 'T';
break;
case ('T'):
Sym[i] = 'A';
break;
case ('C'):
Sym[i] = 'G';
break;
case ('G'):
Sym[i] = 'C';
break;
default:
std::cout << "invalid";
} return c.str();
}
int main() {
std::cout << DNAStrand("ATTGC") << "\n"; //retun "TAACG"
std::cout << DNAStrand("GTAT") << "\n"; //retun "CATA"
}
}

You have created a vector<string>, but in the if statements, you are setting the elements of the vector to chars. You want to build a string, not a vector<string>.
You should replace subsequent if statements with else if, or use a switch statement. Otherwise if statements subsequent to a satisfied if statement are executed needlessly.
Replace this vector with an ostringstream. Naming the stream as s, you would append a char named c with s << c. At the end of iterating over dna, return s.str().

Related

Microsoft's code is not working in praxis

This code, under msvc 2022:
const char* chars = "XBECEDX";
for each (char c in chars)
{
if (c == 'X') std::cout << 'A';
else
std::cout << c;
}
Ends with error E0125, E0065, E0029
Maybe output is: ABECEDA
Where is the Failure? Is it bad code or bad compiler or compiler setting or any Failure.
I solve this as vector with lambda function. Here is example:
string s = "XBECEDX";
for_each(s.begin(), s.end(), [](char ch)
{
if (c == 'X') std::cout << 'A';
else std::cout << c;
});
Why not this:
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char* argv[])
{
string chars = "XBECEDX";
// char chars[] = "XBECEDX"; // will also work as an alternate to string
for (char c : chars)
{
if (c == 'X') std::cout << 'A';
else
std::cout << c;
}
return 0;
}

How to print eight words to a line using vector<string>?

I was trying to make a program write 8 words to a line after a user enter their sentence.Its only printing words that have been typed in and i don't have a clue how to make it type 8 words to a line.
#include <iostream>
#include <vector>
#include <string>
#include <cctype>
using namespace std;
vector<string> sentence;
string sente = "";
void print(string, string);
template<typename T>
void print(vector<T>& v, string)
{
cout << "Enter your sentence " << endl;
getline(cin, sente);
sentence.push_back(sente);
for (auto const elem: sentence)
{
cout << elem;
}
}
int main()
{
print(sentence,sente);
}
Using global variables is generally not a good practice.
Also you don't need a extra vector for your use case.
Take a look at the following code, where you can smartly make use of istringstream for your use case:
#include <iostream>
#include <string>
#include <sstream>
void print()
{
std::string sente;
std::cout << "Enter your sentence " << std::endl;
getline(std::cin, sente);
// Used to split string around spaces.
std::istringstream ss(sente);
int wordCountPerLine = 0;
int requiredWordsPerLine = 8;
// Traverse through all words
do {
// Read a word
std::string word;
ss >> word;
// Print the read word
std::cout << word << " ";
wordCountPerLine++;
if(wordCountPerLine % requiredWordsPerLine == 0){
std::cout<<std::endl;
wordCountPerLine = 0;
}
// While there is more to read
} while (ss);
}
int main()
{
print();
}
Feel free to ask any doubts.

How to Iterate over a map <string, vector<string>> m

I need to write a table from a file in a map > m.
I have 3 strings (state, next_states, outputs)
and i want to write them like this (I know it's not correct)
for (i=0; i < 5; i++)
{
//here I have a code, the 3 strings change for every line
for(j=0; j<m.size(); j++)
{
m[i][j] = "state" + "next_states" + "outputs";
}
}
I thought maybe with iterator it would be better but i don't know how to do it.
Here is how you can iterate through your map:
#include <iostream>
#include <map>
#include <vector>
#include <string>
int main()
{
std::map <std::string, std::vector<std::string>> m =
{
{"1", {"a", "b"}},
{"2", {"c", "d", "e"}},
};
for (auto& element : m)
{
std::cout << element.first << " : ";
for (auto& str : element.second)
{
std::cout << str << "; ";
}
std::cout << std::endl;
}
}

synchronize 3 threads to print sequential output

I was asked this question in an interview. I was pretty clueless.
So I decided to learn some multithreading and hopefully find an answer to this question.
I need to use 3 threads to print the output: 01020304050607.....
Thread1: prints 0
Thread2: prints odd numbers
Thread3: prints even numbers
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex m;
std::condition_variable cv1, cv2, cv3;
int count = 0;
void printzero(int end)
{
while (count <= end)
{
std::unique_lock<std::mutex> lock(m);
cv1.wait(lock);
std::cout << 0 << " ";
++count;
if (count % 2 == 1)
{
lock.unlock();
cv2.notify_one();
}
else
{
lock.unlock();
cv3.notify_one();
}
}
}
void printodd(int end)
{
while (count <= end)
{
std::unique_lock<std::mutex> lock(m);
cv2.wait(lock);
if (count % 2 == 1)
{
std::cout << count << " ";
++count;
lock.unlock();
cv1.notify_one();
}
}
}
void printeven(int end)
{
while (count <= end)
{
std::unique_lock<std::mutex> lock(m);
cv3.wait(lock);
if (count % 2 == 0)
{
std::cout << count << " ";
++count;
lock.unlock();
cv1.notify_one();
}
}
}
int main()
{
int end = 10;
std::thread t3(printzero, end);
std::thread t1(printodd, end);
std::thread t2(printeven, end);
cv1.notify_one();
t1.join();
t2.join();
t3.join();
return 0;
}
My solution seems to be in a deadlock situation. I'm not even sure if the logic is correct. Please help
There are several issues with your code. Here is what you need to do in order to make it work:
Revise your while (count <= end) check. Reading count without synchronization is undefined behavior (UB).
Use a proper predicate with std::condition_variable::wait. Problems of your code without predicate:
If notify_one is called before wait then the notification is lost. In the worst case, main's call to notify_one is executed before the threads start running. As a result, all threads may wait indefinitely.
Spurious wakeups may disrupt your program flow. See also cppreference.com on std::condition variable.
Use std::flush (just to be sure).
I played around with your code quite a lot. Below you find a version where I applied my suggested fixes. In addition, I also experimented with some other ideas that came to my mind.
#include <cassert>
#include <condition_variable>
#include <functional>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
// see the `std::mutex` for an example how to avoid global variables
std::condition_variable cv_zero{};
std::condition_variable cv_nonzero{};
bool done = false;
int next_digit = 1;
bool need_zero = true;
void print_zero(std::mutex& mt) {
while(true) {// do not read shared state without holding a lock
std::unique_lock<std::mutex> lk(mt);
auto pred = [&] { return done || need_zero; };
cv_zero.wait(lk, pred);
if(done) break;
std::cout << 0 << "\t"
<< -1 << "\t"// prove that it works
<< std::this_thread::get_id() << "\n"// prove that it works
<< std::flush;
need_zero = false;
lk.unlock();
cv_nonzero.notify_all();// Let the other threads decide which one
// wants to proceed. This is probably less
// efficient, but preferred for
// simplicity.
}
}
void print_nonzero(std::mutex& mt, int end, int n, int N) {
// Example for `n` and `N`: Launch `N == 2` threads with this
// function. Then the thread with `n == 1` prints all odd numbers, and
// the one with `n == 0` prints all even numbers.
assert(N >= 1 && "number of 'nonzero' threads must be positive");
assert(n >= 0 && n < N && "rank of this nonzero thread must be valid");
while(true) {// do not read shared state without holding a lock
std::unique_lock<std::mutex> lk(mt);
auto pred = [&] { return done || (!need_zero && next_digit % N == n); };
cv_nonzero.wait(lk, pred);
if(done) break;
std::cout << next_digit << "\t"
<< n << "\t"// prove that it works
<< std::this_thread::get_id() << "\n"// prove that it works
<< std::flush;
// Consider the edge case of `end == INT_MAX && next_digit == INT_MAX`.
// -> You need to check *before* incrementing in order to avoid UB.
assert(next_digit <= end);
if(next_digit == end) {
done = true;
cv_zero.notify_all();
cv_nonzero.notify_all();
break;
}
++next_digit;
need_zero = true;
lk.unlock();
cv_zero.notify_one();
}
}
int main() {
int end = 10;
int N = 2;// number of threads for `print_nonzero`
std::mutex mt{};// example how to pass by reference (avoiding globals)
std::thread t_zero(print_zero, std::ref(mt));
// Create `N` `print_nonzero` threads with `n` in [0, `N`).
std::vector<std::thread> ts_nonzero{};
for(int n=0; n<N; ++n) {
// Note that it is important to pass `n` by value.
ts_nonzero.emplace_back(print_nonzero, std::ref(mt), end, n, N);
}
t_zero.join();
for(auto&& t : ts_nonzero) {
t.join();
}
}

Looping back again to Start

now I'm Having problem in repeating the loop after it finished doing the first and i want to try it again without exiting the program? I've been using while loop to do it but still no joy. so i decided to do the if statement. But the Array only accept 4 strings then it exit. Any one who can help? TIA.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
template <typename T>
void GetContents(T& Input);
template <typename T>
void DisplayContents(const T& Input);
int main()
{
int PASS = 0;
// To Display the unsorted and sorted Book Titles
std::vector<std::string> books;
GetContents(books);
std::cout << "\nMy original library (number of books: " << books.size() << "):\n\n";
DisplayContents(books);
std::sort(books.begin(), books.end());
std::cout << "\nMy sorted library (number of books: " << books.size() << "):\n\n";
DisplayContents(books);
std::cout << "Press 1 to try again, else to quit: ";
std::cin >> PASS;
std::cout << "\n";
if (PASS == 1)
{
GetContents(books);
}
else
{
return 0;
}
// to input All book titles
template <typename T>
void GetContents(T& Input)
{
const int MAX = 5;
string bookName;
std::cout << "Enter a Book Titles:\n> ";
for (int i = 0; i < MAX; i++)
{
std::getline(std::cin, bookName);
Input.push_back(bookName);
std::cout <<">";
}
}
//Display All input book titles
template <typename T>
void DisplayContents(const T& Input)
{
for (auto iElement : Input)
{
std::cout << iElement << '\n';
}
std::cout << '\n';
system("pause");
}

Resources