Concatenation of strings [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
In vector c++, I have strings, for example :
ACTT CTTG TTGA TG TGA GAG, as you can see, they superpose
ACTT
CTTG
TTGA
TG
GAG
So in the alignment we can see
ACTTGAG
I want to concatenate them as you can see above and put to another vector. I've tried use substring function, but it doesn't work...

Here's a fairly simple algorithm to overlap two strings:
#include <string>
std::string overlap(std::string first, std::string const & second)
{
std::size_t pos = 0;
for (std::size_t i = 1; i < first.size(); ++i)
{
if (first.compare(first.size() - i, i, second, 0, i) == 0)
{
pos = i;
}
}
first.append(second, pos, second.npos);
return first;
}
Usage:
std::string result = overlap("abcde", "defgh");
And to overlap a whole range, use std::accumulate:
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
std::vector<std::string> strings = {"abc", "def", "fegh", "ghq"};
std::cout << std::accumulate(strings.begin(), strings.end(), std::string(), overlap) << std::endl;
}

Assuming you still use the same code as the last question you might want to consider using the first index you have in your element (it[0]). You could add this result to a string and print it.
Use:
std::string space = "";
std::string result = "";
auto end = vec.rend();
for(auto it = vec.rbegin(); it != vec.rend(); ++it ) {
if (it == end - 1) {
result += *it;
}
else {
result += it[0];
}
std::cout << space << *it << std::endl;
space += " ";
}
std::cout << result << std::endl;

Related

I need help swapping this string [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
#include <iostream>
using namespace std;
int main()
{
string sentence;
string output;
string product1;
string product2;
char pr1;
string product;
int i;
getline (cin,sentence);
char pr2;
cin >> pr1;
cin >> pr2;
for (i=0; i < sentence.length();i++){
pr1 = sentence[i]; //asdfg---> g
pr2 = sentence[0]; //--> a
}
output += pr1+sentence+pr2;
cout << output;
return 0;
}
This code is made to swap letters, but for example when I enter asdfg I get gaasdfga. When I enter that, I want to swap g and a. Any idea what I should do? Any idea what's wrong, and how I can improve it?
The below assigns new values to pr1 and pr2. The characters you entered will be lost.
pr1 = sentence[i]; //asdfg---> g
pr2 = sentence[0]; //--> a
To swap the first found of each of the two entered characters, use std::string::find and then std::swap
Example:
#include <utility>
#include <string>
#include <iostream>
int main() {
std::string sentence = "asdfg";
char pr1 = 'g';
char pr2 = 'a';
auto pos1 = sentence.find(pr1);
auto pos2 = sentence.find(pr2);
if(pos1 != sentence.npos && pos2 != sentence.npos) {
std::swap(sentence[pos1], sentence[pos2]);
}
std::cout << sentence << '\n';
}
Output:
gsdfa
An alternative to std::swap(sentence[pos1], sentence[pos2]); would be to do the swap manually:
char temp = sentence[pos1];
sentence[pos1] = sentence[pos2];
sentence[pos2] = temp;
or via a user defined swapper function that you call just like you'd call std::swap:
template<class T>
void swapper(T& lhs, T& rhs) {
// move construct a temporary variable from the argument on the
// left hand side
T temp = std::move(lhs);
// move assign the left hand side from the right hand side
lhs = std::move(rhs);
// move assign the right hand side from the temporary variable
rhs = std::move(temp);
}

Recursion to count words and redundant words in a sentence in c++ [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
Hi i'm trying to count the words in a sentence that is input by the user and this is the code i've written
void Count_Words( )
{
int count=0;
for (i = 0; inserted_text[i] != '\0';i++)
{
if (inserted_text[i] == ' ')
count++;
}
cout << "Word Count: " << count + 1;
}
I need to write this using recursion but i can't figure out how.
Also i need to count the redundant words in the sentence using recursion how do i do that?
I can't use mapping i need to use basic logic to do this. Is there anyway i can do this only with basic logic?
I agree with Hatted Rooster (this is not a good fit for recursion). I guess it serves a teaching purpose. So here is another option.
countWords() returns the number of words for the given substring until its end. To calculate the words for substring 0..n, we can calculate the words for substring 1..n first. And if character 0 is a space, add 1 to that.
int countWords(const char* str)
{
if(*str == '\0')
return 1; // last word
return countWords(str + 1) // how many words are in the remaining substring?
+ (*str == ' ' ? 1 : 0); // count if the beginning of the current substring is a space
}
int main()
{
std::string input = "test test test";
std::cout << countWords(input.c_str()); // 3
}
It doesn't really make sense to use recursion here but anyway, this would be one way to do it:
void Count_Words(int& i, const std::string& inserted_text, int& count)
{
if (inserted_text[i] == '\0')
{
++count; // last word
return;
}
if (inserted_text[i] == ' ')
++count;
Count_Words(++i, inserted_text, count); //recurse
}
int main()
{
std::string input = "test test test";
int i = 0;
int count = 0;
Count_Words(i, input, count);
std::cout << count; // 3
}
The thing to take away from this code is that references are a powerful tool to achieve correct recursion as seen in the function parameters.
As the other answer stated, this is really not a problem that should be resolved using recursion. What if there are thousands of words? That would exhaust the stack memory at some point.
In any event, here is one way to do this recursively:
#include <sstream>
#include <string>
#include <iostream>
void Count_Words(std::istringstream& strm, int& count)
{
std::string word;
if ( strm >> word ) // if there is a word, then increment the count
{
++count;
Count_Words(strm, count); // go to next word recursively
}
}
int Count_Words(std::string inserted_text)
{
// This is the setup for the recursive calls
std::istringstream strm(inserted_text);
int count = 0;
// start the recursion
Count_Words(strm, count);
return count;
}
int main()
{
std::string test = "This has four words";
std::cout << Count_Words(test);
}
Output:
4

How to go through each element in a for a loop C++ using pointers [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Let's say I have a string of names
It holds ["John Doe","Patrick", "Star", "Sandy Cheeks"]
How would I access each letter of the array using a for loop? So let's say I wanted to access the "J" in Jonh Doe all the way to the "s" in Sandy Cheeks?
I can only use the library iostream and string
Since C++11 you can achieve this easily by using a range-based for loop like so:
std::string arr[] = {"John Doe","Patrick", "Star", "Sandy Cheeks"};
for(const std::string& str : arr)
{
for(const char& chr : str)
{
//use chr
}
}
You can use a more explicit method:
static const std::string people[] = {"John Doe", "Patrick", "Star", "Sandy Cheeks"};
size_t name_quantity = sizeof(people) / sizeof(people[0]);
for (size_t name_index = 0; name_index < name_quantity; ++name_index)
{
const std::string& name(people[name_index]);
const size_t name_length = name.length();
for (size_t letter_index = 0; letter_index < name_length; ++letter_index)
{
char letter = name[letter_index];
Process_Letter(letter);
}
}
you dont have a string of names, you have a array of strings, in c++11 you can use a rang based for loop
int main(int argc, char **argv) {
std::cout << "-HW-" << std::endl;
std::string names[] =
{ "John Doe", "Patrick", "Star", "Sandy Cheeks" };
for (const auto& x : names)
{
std::cout << x << std::endl;
}
return 0;
}

How can I erase my string way quicker [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 years ago.
Improve this question
I am supposed to write a program that takes in string like "pre#ogrann##mmink#g" and returns "programming", it is like your backspace button is broken and when you hit it you get '#' instead of erasing the char out, and I have to fix it. I have working code here under but it is way to slow, and I might have to deal with huge string, any suggestion how I could do it better/faster?
#include <string>
#include <iostream>
using namespace std;
int main() {
string str;
while(cin >> str) {
bool done = false;
while(!done) {
if((int)str.find('#')>-1) {
str.erase(str.find('#')-1, 2);
} else {
done = true;
}
}
cout << str << endl;
}
}
Here's how I would do it. I haven't tested it to see if it is actually faster, but as it has a complexity of O(N), I think it should be fast enough:
while (std::cin >> input) {
std::string result;
result.reserve(input.length());
for (auto ch : input) {
if (ch == '#') {
if (result.length() > 0)
result.pop_back();
continue;
}
result += ch;
}
std::cout << result << '\n';
}
#include <iostream>
#include <string>
using namespace std;
string s = "pre#ogrann##mmink#g";
int main() {
string out;
int len = s.length();
for (int i = 0; i < len; i++) {
if(s[i] == '#') {
s.erase(i-1,2);
len = s.length();
i -= 2;
}
}
cout << s;
return 0;
}
This produces a working output.

Generate All Possible Matches of a Regular Expression [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
How can I derive all possible matches of a regular expression
For example:
((a,b,c)o(m,v)p,b)
The strings generated from above expression would be:
aomp
bomp
comp
aovp
bovp
covp
b
Your steps are pretty straight forward though implementing them may take a bit of work:
Create a recursive function which extracts the string between the first set of parenthesis it comes to: https://stackoverflow.com/a/28863720/2642059
In the function split this strings on ',' into a vector<string> and return it: https://stackoverflow.com/a/28880605/2642059
Before returning test if it is necessary to recurse because of a nested parenthesis, one string must be added to the return for each possible combination returned from recursed functions
EDIT:
Say my input string was "(bl(ah,eck,le),yap)"
The first function would extract the string: "bl(ah,eck,le),yap"
Before returning it would search for nested parenthesis, this would cause it to recurse:
The second function would extract the string: "ah,eck,le"
Before returning it would search for nested parenthesis and find none
It would return an vector<string>: ["ah","eck","le"]
The first function would now contain: "bl["ah","eck","le"],yap"
It would not find anymore parenthesis to extract, so it would go to expanding all internal combinations: "["blah","bleck","blle"],yap"
It could now split the string and return: ["blah","bleck","blle","yap"]
The return from your first function is your result.
EDIT:
Glad you solved it I wrote up a two state machine to solve it as well so I figured I could post it here for your comparison:
const char* extractParenthesis(const char* start, const char* finish){
int count = 0;
return find_if(start, finish, [&](char i){
if (i == '('){
count++;
}
else if (i == ')'){
count--;
}
return count <= 0; });
}
vector<string> split(const char* start, const char* finish){
const char delimiters[] = ",(";
const char* it;
vector<string> result;
do{
for (it = find_first_of(start, finish, begin(delimiters), end(delimiters));
it != finish && *it == '(';
it = find_first_of(extractParenthesis(it, finish) + 1, finish, begin(delimiters), end(delimiters)));
auto&& temp = interpolate(start, it);
result.insert(result.end(), temp.begin(), temp.end());
start = ++it;
} while (it <= finish);
return result;
}
vector<string> interpolate(const char* start, const char* finish){
vector<string> result{ 1, string{ start, find(start, finish, '(') } };
for (auto it = start + result[0].size();
it != finish;
it = find(++start, finish, '('),
for_each(result.begin(), result.end(), [&](string& i){ i += string{ start, it }; })){
start = extractParenthesis(it, finish);
auto temp = split(next(it), start);
const auto size = result.size();
result.resize(size * temp.size());
for (int i = result.size() - 1; i >= 0; --i){
result[i] = result[i % size] + temp[i / size];
}
}
return result;
}
Depending upon your compiler you'll need to forward declare these since they call each other. This will also crash fantastically if the input string is malformed. And it can't handle escaped control characters.
Anyway you can call it like this:
const char test[] = "((a,b,c)o(m,v)p,b)";
auto foo = interpolate(begin(test), end(test));
for (auto& i : foo){
cout << i << endl;
}