Wrong answer in c++ - c++

You are given a DNA sequence, and few enzymes. Suppose, a DNA sequence goes like this : ATGCTGCTATGCATGCAGTGACT, and you are given enzymes which can remove AT and GC sequences. Thereby, you need to remove all occurrences of AT from the DNA first and then reform the DNA and apply the next enzyme to remove all occurrences of GC. The output of the problem would be the string you get at last reforming the pieces which are not removed by these enzymes.
Input
The first line of input consists of an integer n that denotes the number of enzymes. The first line has the DNA sequence. The next T lines has the input B1, B2, B3... Bn.
Output
For given input DNA sequence, output a single line containing the final reformed DNA that is formed by repeatedly removing all the occurrences of B1, B2, B3... Bn from A.
In case the DNA is completely consumed print 0 to indicate that there is no DNA left.
Constraints
1 <= n <= 10
Example 1:
Input:
2
ATACGCATGACGATGCATGCAGCAT
ATA
GC
Output:
CATGACGATATAAT
Example 2:
Input:
3
ATGCATGCATCGACTCAGCATCAGCATCGACTA
TG
GC
AT
Output:
ACACCGACTCACACGACTA
My code:
I tried solving it using string in c++, I am getting :
terminate called after throwing an instance of 'std::out_of_range'
what():basic_string::erase()
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <vector>
#include <set>
#include <stdlib.h>
#include <string.h>
#include <queue>
#include <stack>
#include <assert.h>
#include <limits.h>
using namespace std;
int main() {
string str, str1;
int n;
scanf("%d", &n);
cin >> str;
while (n--) {
cin >> str1;
int len = str1.length();int len1=str.length();
for (int i = 0; i < len1; i++) {
int found = str.find(str1);
str.erase(found, found + len);
}
}
cout << str;
return 0;
}

Three main problems:
Number one, out of range exception on string::erase.
Fixed by testing that find actually returned a value:
if (found!=std::string::npos)
Number two, searching correctly.
Fixed by keeping track of found (it's also a size_t not an int) and searching from the next location:
found = str.find(str1,found);
Number three, using string::erase properly.
Fixed by using length of substring to erase, not length + position:
str.erase(found,len);
I still haven't added any input validation to your code. You should really think about doing that yourself.
Final code:
(ideone)
#include <string>
#include <iostream>
int main()
{
std::string str;
std::string str1;
int n;
std::cin>>n;
std::cin>>str;
while(n--)
{
std::cin>>str1;
int len = str1.length();
size_t found = 0;
for(unsigned int i=0;i<str.length();i++)
{
found = str.find(str1,found);
if (found!=std::string::npos)
{
str.erase(found,len);
}
else
{
break;
}
}
}
std::cout<<(str.length()?str:"0");
return 0;
}
idone output for each example input (I've added your example outputs in between the /* */ marks):
Success time: 0 memory: 3476 signal:0
CATGACGATATAAT
/*CATGACGATATAAT*/
Success time: 0 memory: 3476 signal:0
ACACCGACTCACACGACTA
/*ACACCGACTCACACGACTA*/

Related

C++ twoSum. Optimize memory usage

I am solving a twoSum problem.
Steps:
Read an input file with a following template:
7
1 7 3 4 7 9
First line is the target number, second line is a number sequence.
Numbers can be in range 0 < N < 999999999
If the sum of two numbers from the number sequence equals the target number, I write "1" to the output file.
If there are no numbers the sum of which equals the target number then I write "0" to the output file.
I need to optimize memory usage in my code. How can I do that?
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <unordered_map>
#include <string>
#include <algorithm>
using namespace std;
int main() {
ifstream f1;
vector<int> nums;
string line;
string source;
//Open input file and read it to a string
f1.open("input.txt");
while (getline(f1, line, '\n')) {
source+=line + " ";
} f1.close();
//Parse the string into an int vector
stringstream parser(source);
int num;
while (parser >> num) { nums.push_back(num); }
//Clear used strings
line = "";
source = "";
//Get target number
int target = nums.at(0);
//Get number sequence
nums.erase(nums.begin());
bool flag = false;
//Check number sequence for two numbers sum of which equals the target number
unordered_map<int, int> mp;
for(int i=0;i<nums.size();i++){
if(mp.count(nums[i])==1){
flag = true;
break;}
mp[target-nums[i]]=i;
}
//Write the result into the output file
ofstream f2;
f2.open("output.txt");
f2 << flag;
f2.close();
}
There are a couple of things you can do to minimise memory usage here. First up, you don't need to read entire contents of the file into std::string. You can read directly into std::vector, or better still read the file contents into a single int variable and process the numbers as you go. Another thing: you do not need to use a std::unordered_map, because presence of the key is the only thing you are really interested in, so std::unordered_set is sufficient. Below a simple solution making use of that suggestions:
#include <fstream>
#include <unordered_set>
int main() {
std::ifstream input {"input.txt"};
int target;
input >> target;
int current_number;
bool found = false;
std::unordered_set<int> observed_numbers;
while (input >> current_number) {
if (observed_numbers.count(target - current_number) > 0) {
found = true;
break;
}
observed_numbers.insert(current_number);
}
std::ofstream output {"output.txt"};
output << found;
}

C++ Finding Specific characters in a string

Writing a program that asks the user to insert a word. The word gets stored in a string, then the user is asked to insert the position of a character in the word they want displayed. IE. User inputs Peanuts, User then inputs 4, Output is N
You can do it in this way:
#include <iostream>
#include <string.h>
using namespace std;
int main() {
string s = "thisisastring";
int position = 0;
cin>>position;
cout<<s.at(position);
return 0;
}
If you enter 4 it will output 'i' because the starter index of the string is 0.. if you want to output the 4^ character you need to to use cout<<s.at(position-1);
if you enter '0' or a number over than string.lenght() this code generate an error, if to want to prevent this issue you have to run this:
#include <iostream>
#include <string.h>
using namespace std;
int main() {
string s = "thisisastring";
int position = 0;
do{
cin>>position;
}while(position <=0 || position > s.length());
cout<<s.at(position);
return 0;
}

How to compare strings that shows number of differences

I'm new to programming so I'm sorry if my question is hard to understand.
I have a string modelAnswer as such
string modelAnswer = "ABABACDA";
So it's supposed to be the answers to a quiz and I'm trying to make it so that if user's input is
string studentAnswer = "ABADBDBB"; for example the program will show that I have gotten 3 points as the first three letters of the studentAnswer string matches the modelAnswer.
You can use standard algorithm std::inner_product as for example
#include <iostream>
#include <string>
#include <numeric>
#include <functional>
int main()
{
std::string modelAnswer( "ABABACDA" );
std::string studentAnswer( "ABADBDBB" );
auto n = std::inner_product( modelAnswer.begin(), modelAnswer.end(),
studentAnswer.begin(), size_t( 0 ),
std::plus<size_t>(), std::equal_to<char>() );
std::cout << n << std::endl;
return 0;
}
The program output is
3
It is assumed that the strings have the same length. Otherwise you should use the less string as the first pair of arguments.
For example
#include <iostream>
#include <string>
#include <numeric>
#include <algorithm>
#include <functional>
#include <iterator>
int main()
{
std::string modelAnswer( "ABABACDA" );
std::string studentAnswer( "ABADBDBB" );
auto n = std::inner_product( modelAnswer.begin(),
std::next( modelAnswer.begin(), std::min( modelAnswer.size(), studentAnswer.size() ) ),
studentAnswer.begin(), size_t( 0 ),
std::plus<size_t>(), std::equal_to<char>() );
std::cout << n << std::endl;
return 0;
}
If you are using standard strings, with the proper includes (Mainly #include <string>), you can write a simple for loop to iterate over each character, comparing them.
std::string answer = "ABABACDA";
std::string stringToCompare = "ABADBDBB";
int score = 0;
for (unsigned int i = 0; (i < answer.size()) && (i < stringToCompare.size()); ++i)
{
if (answer[i] == stringToCompare[i])
{
++score;
}
}
printf("Compare string gets a score of %d.\n", score);
The above code works for me, printing the following result:
Compare string gets a score of 3.
Using a stringstream, you can push one character at a time into temporary variables and test for equivalence in a loop.
#include <iostream>
#include <string>
#include <sstream>
int main() {
std::istringstream model("ABABACDA");
std::istringstream student("ABADBDBB");
int diff = 0;
char m, s;
while ((model >> m) && (student >> s))
if (m != s) diff++;
std::cout << diff << std::endl; // 5
return 0;
}

Keep output and input from alternating?

I am very new to coding, and have been practicing with some easy problems at codeforces.com. I was working on this problem, but it seemed to be asking for the input (all at once) yielding the output (all at once). I can only figure out how to get one output at a time.
Here are the basic instructions for the problem:
Input
The first line contains an integer n (1 ≤ n ≤ 100). Each of the following n lines contains one word. All the words consist of lowercase Latin letters and possess the lengths of from 1 to 100 characters.
Output
Print n lines. The i-th line should contain the result of replacing of the i-th word from the input data.
Examples
input
4
word
localization
internationalization
pneumonoultramicroscopicsilicovolcanoconiosis
output
word
l10n
i18n
p43s
Here is my code:
#include <iostream>
#include <string>
using namespace std;
void wordToNumbers(string word){
int midLetters = word.length();
char firstLetter = word.front();
char lastLetter = word.back();
cout <<firstLetter <<(midLetters-2) <<lastLetter <<endl;
}
int main(){
string wordInput;
string firstNum;
getline(cin,firstNum);
int i = stoi(firstNum);
for(i>=1; i--;){
getline(cin,wordInput);
if (wordInput.length() > 10){
wordToNumbers(wordInput);
} else {
cout <<wordInput <<endl;
}
}
return 0;
}
it's perfectly fine to read and print output for the lines one by one.
Exactly your solution accepted: http://codeforces.com/contest/71/submission/16659519
I'm also a beginner in c++. My idea would be to save every line first in a buffer and then write everything to std::cout.
I use a std::vector as the buffer, cause IMO it is simple to understand and very useful in many cases. Basically it is a better array. You can read more about std::vector here.
#include <iostream>
#include <string>
//for use of std::vector container
#include <vector>
using namespace std;
void wordToNumbers(string word){
int midLetters = word.length();
char firstLetter = word.front();
char lastLetter = word.back();
cout <<firstLetter <<(midLetters-2) <<lastLetter <<endl;
}
int main(){
string wordInput;
string firstNum;
//container for buffering all our strings
vector<string> bufferStrings;
getline(cin,firstNum);
int i = stoi(firstNum);
//read line by line and save every line in our buffer-container
for(i>=1; i--;){
getline(cin,wordInput);
//append the new string to our buffer
bufferStrings.push_back(wordInput);
}
//now iterate through the buffer and write everything to cout
for(int index = 0; index < bufferStrings.size(); ++index) {
if (bufferStrings[index].length() > 10){
wordToNumbers(bufferStrings[index]);
} else {
cout <<bufferStrings[index] <<endl;
}
}
return 0;
}
Probably this is not the best or most beautiful solution, but it should be easy to understand :)

Why is replacing an element of a vector so slow?

I notice that amending (or replacing) an element in a large vector is consuming a lot of time when the vector is getting bigger, even when the element's place in the vector is known.
Is there an explanaition for this?
I use an unsorted set as an index. The code first tries to find the element in the set with set.find(). If the element not present in the set the code insert it at the end of the set and at the same time pushes it at the end of the vector.
If the element is found on position "x" of the set the data in the vector is replaced by using:
vector.at(x)=vector[x]+element.
When I skip the vector part and only insert the element in the set the code easily processes 95 million elements in less then 2 minutes. But when I add the vector part to it the code keeps on running for hours.
The file I'm importing is a semicolumn separated text, with below structure
2161182;Jutfaseweg;footway;no;7740068,13877901
2953564;Timorkade;cycleway;no;7785429,368846814,582743212,582743202,582743213,582743203,582743214,582743206,582743210,45200603
Each line represents a way. The ID's in the last element are waypoints of that particular way. Each element has a righthand neighbour, unless it is the last element of the way and based on the 4th element ("yes" or "no", meaning oneway or not), also a lefthand neighbour, unless it is the first element of the way.
Below is the code as requested
#include <windows.h>
#include <cstring>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <cstring>
#include <cstdint>
#include <cstdio>
#include <set>
#include <vector>
using namespace std;
set<string>PresentStreet;
set<int>PresentNode;
vector<string>NeighBours;
string line1;
void split(const string& s, char c,
vector<string>& v) {
string::size_type i = 0;
string::size_type j = s.find(c);
while (j != string::npos) {
v.push_back(s.substr(i, j-i));
i = ++j;
j = s.find(c, j);
if (j == string::npos)
v.push_back(s.substr(i, s.length()));
}
}
int main(int argc, char *argv[]) {
ifstream myfile ("filename.txt");
int CounterLine=1;
while ( getline (myfile,line1) ) {
string s1=line1;
vector<string> v1;
split(line1, ';', v1);
PresentStreet.insert(v1[2]);
vector<string> v2;
split(v1[4], ',', v2);
for (int t=0;t<v2.size();t++) {
auto search = PresentNode.find(atoi(v2[t].c_str()));
if(search == PresentNode.end()) {
string Neighbours="";
if(v1[3].find("no")!=std::string::npos&&t>0) {
Neighbours=Neighbours+v2[t-1]+",";
}
if(t<v2.size()-1) {
Neighbours=Neighbours+v2[t+1]+",";
}
stringstream ss;
ss<<CounterLine;
stringstream ss2;
ss2<<v2[t];
PresentNode.insert(atoi(v2[t].c_str()));
NeighBours.push_back(Neighbours);
}else{
int nPosition = distance (PresentNode.begin (), search);
string Neighbours=NeighBours[nPosition];
if(v1[3].find("no")!=std::string::npos&&t>0) {
Neighbours=Neighbours+v2[t-1]+",";
}
if(t<v2.size()-1) {
Neighbours=Neighbours+v2[t+1]+",";
}
NeighBours.at(nPosition)=Neighbours;
}
}CounterLine++;
}
}