swap words in a string/ simplify my code please

Q: in a given string, swap the second word with the one before the last. if there are less than 4 words then just delete the second one
ex: "my name is laura fidarova" = "my laura is name fidarova"

i have the code, but my teacher said it's way too complicated. is there a way to write it without using <iterator>, <list> and <regex>?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  #include <regex>
#include <iterator>
#include <iostream>
#include <string>
#include <list>
using namespace std;
int main()
{
    string s = "My name is Laura Fidarova";
    //string s = "My name is Laura";
    //string s = "I am Laura";
    // string s = "Laura Fidarova";
    // string s = "Laura";

    
    regex words_regex("[^\\s]+");
    list<string> words;
    for (sregex_iterator i = sregex_iterator(s.begin(), s.end(), words_regex); i != sregex_iterator(); ++i)
    {
        words.emplace_back(i->str());
    }

    
    auto words_begin = words.begin(), words_end = words.end();
    if (words.size() < 4 && words.size() > 1)
    {
        words.erase(++words_begin); 
    }
    
    else if (words.size() > 3)
        {
            --words_end;
            iter_swap(++words_begin, --words_end); 
        }

    s.clear();
    for (auto& word : words)
    {
        s += (word + " ");
    }
    
    cout << "Transformed text: " << s << endl;
Last edited on
read the words into a vector of string, letting cin split it on the whitespace for you.
swap the strings at the 2 locations with std:: swap.
write out the vector, injecting a space for each element.

you can do it character by character with no tools at all, if you must. Tools good. No tools bad. Regex too much sledgehammer for fly, though. Tool-less, creating a new string and jumping around in the original seem simple enough, just append the new characters to the new string in the right order.
Last edited on

Maybe something like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <sstream>
#include<vector>
#include<string>

std::string get(std::string s )
{
std::istringstream sentence(s);
std::string v="",answer="";;
std::vector<std::string> vs;
int n;
while(sentence>>v)
{
	n+=1;
	vs.resize(n);
	vs[n-1]=v+" ";
}
if (vs.size()<2) return "";
if (vs.size()<4) vs[1]="";
else
{swap (vs[1],vs[vs.size()-2]);}; //swap second with second last
for(n=0;n<vs.size();n++) answer=answer+vs[n];// build the answer
return answer;	 
}


int main()
{
std::string z=get("My name is Laura Fidarova");
std::cout<<z<<std::endl;

//end
std::cout <<"Press return to end . . ."<<std::endl; 
std::cin.get();	 

}
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
   string s = "My name is Julius Caesar";
   
   vector<string> V;
   stringstream ss( s );
   for ( string word; ss >> word; ) V.push_back( word );
   if ( V.size() >= 4 ) swap( V[V.size()-2], V[1] );
   else if ( V.size() > 1 ) V.erase( V.begin()+1 );
   for ( string e : V ) cout << e << " ";
   cout << '\n';
}


If you want to preserve spaces, punctuation etc. then you will have to work somewhat harder (and define precisely what constitutes a "word").
Last edited on
@oggin. n is defined but not initialised before it is used - hence could initially contain any value.

To re-construct without having a trailing space, using part of C++20 consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <utility>

std::string convert(const std::string& s)
{
	std::vector<std::string> vs;
	std::string answer;
	std::istringstream sent(s);

	for (std::string wrd; sent >> wrd; vs.push_back(wrd));

	if (vs.size() >= 2)
		if (vs.size() < 4)
			vs.erase(vs.begin() + 1);
		else
			std::swap(vs[1], vs[vs.size() - 2]);

	for (size_t n {}; const auto& v : vs)
		answer += (n++ > 0 ? " " : "") + v;

	return answer;
}

int main()
{
	std::cout << convert("My name is Laura Fidarova") << '\n';
	std::cout << convert("My name is Laura") << '\n';
	std::cout << convert("I am Laura") << '\n';
	std::cout << convert("Laura Fidarova") << '\n';
	std::cout << convert("Laura") << '\n';
}


or for non-C++20, put the n definition outside of the range-for. Note tat it doesn't preserve multi-whitespaces.


My Laura is name Fidarova
My is name Laura
I Laura
Laura
Laura

Topic archived. No new replies allowed.