C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

STL: Replacing consecutive matching elements in a string

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
lotusny78@yahoo.com
Guest





PostPosted: Fri Apr 15, 2005 7:27 am    Post subject: STL: Replacing consecutive matching elements in a string Reply with quote



Hi everyone,

I'm trying to use the STL to replace every time there are consecutive
tabs with ' ' in a string. I came up with something that works, but it
seems like there should be an easier way to do it. I'm looking for
another strategy, not really bug-fixes as this is semi-spaghetti code.
Also, I don't want to exploit the possibility of string iterators being
pointers. Thanx.
- Sean

class ConsecutiveTabs {
public:
bool operator() (char c1, char c2)
{
if('t' == c1 && 't' == c2)
return true;
else
return false;
}
};

string line;
....
string::iterator beginIt;
while(line.end() !=
(beginIt=
adjacent_find(line.begin(), line.end(), ConsecutiveTabs))) {
if(*beginIt == 't') {
string::iterator endIt = beginIt;
advance(endIt, 2);
line.replace(beginIt, endIt, 1, ' ');
}
}


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
simont
Guest





PostPosted: Sat Apr 16, 2005 12:05 am    Post subject: Re: STL: Replacing consecutive matching elements in a string Reply with quote



[email]lotusny78 (AT) yahoo (DOT) com[/email] wrote:
Quote:
Hi everyone,

I'm trying to use the STL to replace every time there are
consecutive tabs with ' ' in a string. I came up with something
that works, but it seems like there should be an easier way to do
it. I'm looking for another strategy, not really bug-fixes as this
is semi-spaghetti code. Also, I don't want to exploit the
possibility of string iterators being pointers. Thanx.
- Sean

Perhaps something like
boost::algorithm::replace_all( str, "tt", " " );

I haven't tried this btw, I just thought there'd probably be something
in there.

See:
http://www.boost.org/doc/html/replace_all.html


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Isaac Rodriguez
Guest





PostPosted: Sat Apr 16, 2005 12:06 am    Post subject: Re: Replacing consecutive matching elements in a string Reply with quote



Quote:
I'm trying to use the STL to replace every time there are consecutive
tabs with ' ' in a string. I came up with something that works, but it
seems like there should be an easier way to do it. I'm looking for
another strategy, not really bug-fixes as this is semi-spaghetti code.
Also, I don't want to exploit the possibility of string iterators being
pointers. Thanx.

Well, I am not sure if this is simpler or not, but you can take a look at
it.

#include <iostream>
#include <string>
#include <algorithm>


int main ()
{
using std::string;
using std::cout;
using std::endl;

string s = "HellottWorldtthisttisttfun";
cout << s << endl;

string::iterator search = s.begin();
while ( search != s.end() ) {

search = std::find(search, s.end(), 't');
if (search != s.end()) {

string::iterator next = search + 1;
if (*next == *search && 't' == *search) {

s.replace(search, next + 1, 1, ' ');
}
else {

++search;
}
}
}

cout << s << endl;

return 0;
}

- Isaac.



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Carl Barron
Guest





PostPosted: Sat Apr 16, 2005 5:40 pm    Post subject: Re: Replacing consecutive matching elements in a string Reply with quote

Isaac Rodriguez <discussion.support (AT) autodesk (DOT) com> wrote:

Quote:
I'm trying to use the STL to replace every time there are consecutive
tabs with ' ' in a string. I came up with something that works, but it
seems like there should be an easier way to do it. I'm looking for
another strategy, not really bug-fixes as this is semi-spaghetti code.
Also, I don't want to exploit the possibility of string iterators being
pointers. Thanx.

Well, I am not sure if this is simpler or not, but you can take a look at
it.
...

as long as you are looking at std::strings, why not

void replace_all(std::string &str,std::string const &fnd,std::string
const & rep)
{
std::string::size_type pos=0;
std::string::size_type len=fnd.length();
std::string::size_type rep_len = rep.length();

while((pos = str.find(fnd,pos)) !=std::string::npos)
{
str.replace(pos,len,rep);
pos+=rep_len;
}
}

The code is for exposition only, not tested.



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Seungbeom Kim
Guest





PostPosted: Sat Apr 16, 2005 5:43 pm    Post subject: Re: STL: Replacing consecutive matching elements in a string Reply with quote

[email]lotusny78 (AT) yahoo (DOT) com[/email] wrote:
Quote:
Hi everyone,

I'm trying to use the STL to replace every time there are consecutive
tabs with ' ' in a string. I came up with something that works, but it
seems like there should be an easier way to do it. I'm looking for
another strategy, not really bug-fixes as this is semi-spaghetti code.
Also, I don't want to exploit the possibility of string iterators being
pointers. Thanx.
- Sean

#include <string>
#include <algorithm>

using std::string;

void replace_all(string& s, const string& a, const string& b)
{
for (string::size_type i = s.find(a);
i != string::npos;
i = s.find(a, i + b.size()))
s.replace(i, a.size(), b);
}

replace_all(str, "tt", " ");

--
Seungbeom Kim

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Paavo Helde
Guest





PostPosted: Sun Apr 17, 2005 2:25 pm    Post subject: Re: STL: Replacing consecutive matching elements in a string Reply with quote

[email]lotusny78 (AT) yahoo (DOT) com[/email] wrote in news:1113537204.841335.52700
@l41g2000cwc.googlegroups.com:

Quote:
Hi everyone,

I'm trying to use the STL to replace every time there are consecutive
tabs with ' ' in a string. I came up with something that works, but it

Something like this? This replaces any sequence of 2 or more tabs by a
single space (note: untested).

string::size_type k=0;
while((k=line.find("tt", k))!=line.npos) {
string::size_type l = line.find_first_not_of("t", k);
line[k++] = ' ';
line.erase(k, l-k);
}

Paavo

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Thierry Miceli
Guest





PostPosted: Sun Apr 17, 2005 3:38 pm    Post subject: Re: STL: Replacing consecutive matching elements in a string Reply with quote

You may use the std::unique function template that takes a binary
predicate as follows:

class AdjacentBlanks
{
public:
bool operator()(char el1, char el2)
{
return ( el1 == ' ' && el2 == ' ' );
}
};

.......

// Replace all tabs by space characters
std::replace(line.begin(), line.end(), 't', ' ');

// Replace sequences of spaces by a single space character
std::unique(line.begin(), line.end(), AdjacentBlanks());


Thierry Miceli
www.ideat-solutions.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Potter
Guest





PostPosted: Sun Apr 17, 2005 6:04 pm    Post subject: Re: STL: Replacing consecutive matching elements in a string Reply with quote

On 15 Apr 2005 03:27:40 -0400, [email]lotusny78 (AT) yahoo (DOT) com[/email] wrote:

Quote:
I'm trying to use the STL to replace every time there are consecutive
tabs with ' ' in a string. I came up with something that works, but it
seems like there should be an easier way to do it.

I assume that using the STL and easier means hiding the logic in one
liners.

Quote:
Also, I don't want to exploit the possibility of string iterators being
pointers.

String iterators are random access iterators whether they are pointers
or not. You can do anything with a random access iterator that you can
do with a pointer.

Quote:
if('t' == c1 && 't' == c2)
return true;
else
return false;

Sorry, I can't resist. Use one line.

return 't' == c1 && 't' == c2;

Let's assume no embedded nul characters, then the following should do
the job.

char f1 (char c1, char c2) {
return c2 == '' && c1 == 't' ? ' ' : c1;
}
char f2 (char c1, char c2) {
return c2 == 't' && c1 == 't' ? '' : c2;
}
void doubleTabToSpace (std::string& s) {
std::transform(s.begin(), s.end() - 1, s.begin() + 1,
s.begin() + 1, f2);
std::transform(s.begin(), s.end() - 1, s.begin() + 1,
s.begin(), f1);
s.erase(std::remove(s.begin(), s.end(), ''), s.end());
}

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Carl Barron
Guest





PostPosted: Sun Apr 17, 2005 9:21 pm    Post subject: Re: STL: Replacing consecutive matching elements in a string Reply with quote

<lotusny78 (AT) yahoo (DOT) com> wrote:

Quote:
Hi everyone,

I'm trying to use the STL to replace every time there are consecutive
tabs with ' ' in a string. I came up with something that works, but it
seems like there should be an easier way to do it. I'm looking for
another strategy, not really bug-fixes as this is semi-spaghetti code.
Also, I don't want to exploit the possibility of string iterators being
pointers. Thanx.
- Sean
struct two_tabs

{
bool operator () (char x,char y) const {return x=='t' && y=='t';}
}

void remove_mutliple_tabs(std::string &line)
{
std::string::iterator it = std::unique(line.begin(),line.end(),
two_tabs());
line.erase(it,line.end());
}


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
John Potter
Guest





PostPosted: Sun Apr 17, 2005 9:21 pm    Post subject: Re: STL: Replacing consecutive matching elements in a string Reply with quote

On 17 Apr 2005 11:38:57 -0400, [email]tmiceli (AT) sympatico (DOT) ca[/email] (Thierry Miceli)
wrote:

Quote:
You may use the std::unique function template that takes a binary
predicate as follows:

// Replace all tabs by space characters
std::replace(line.begin(), line.end(), 't', ' ');

// Replace sequences of spaces by a single space character
std::unique(line.begin(), line.end(), AdjacentBlanks());

Ignoring the fact that this also changes existing space sequences
and replaces four tabs with a single space, unique only changes the
contents of the string, not the size.

line.erase(std::unique(line.begin(), line.end(), AdjacentBlanks()),
line.end());

It is worth noting that this is linear while most other solutions are
quadratic.

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Allan W
Guest





PostPosted: Tue Apr 19, 2005 11:00 pm    Post subject: Re: STL: Replacing consecutive matching elements in a string Reply with quote

Quote:
lotusny78 (AT) yahoo (DOT) com wrote:
I'm trying to use the STL to replace every time there are
consecutive tabs with ' ' in a string.

simont wrote:
Quote:
Perhaps something like
boost::algorithm::replace_all( str, "tt", " " );

But if there are five tabs in a row, this would only replace four of
them -- and it would replace them with two spaces instead of just one.

Maybe this (assumes no more than 80 tabs in a row in original string):
// 80 tabs
const char tabs[]="tttttttttttttttttttt"
"tttttttttttttttttttt"
"tttttttttttttttttttt"
"tttttttttttttttttttt";
for (int i=0; i boost::algorithm::replace_all(str, tabs+i, " ");

Or maybe this (assumes no more than about 16000 tabs in a row):
const char tabs[]="tttttttttttt"; // 12 tabs
int i;
// Strings of 18 or more tabs have 16 tabs removed...
for (i=0; i<999; ++i)
boost::algorithm::replace_all(str, tabs, tabs+10);
for (i=0; i<=10; ++i)
boost::algorithm::replace_all(str, tabs+i, " ");


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Wed Apr 20, 2005 12:34 pm    Post subject: Re: STL: Replacing consecutive matching elements in a string Reply with quote

Allan W wrote:
Quote:
lotusny78 (AT) yahoo (DOT) com wrote:

I'm trying to use the STL to replace every time there are
consecutive tabs with ' ' in a string.
simont wrote:
Perhaps something like
boost::algorithm::replace_all( str, "tt", " " );

But if there are five tabs in a row, this would only replace
four of them -- and it would replace them with two spaces
instead of just one.

Maybe this (assumes no more than 80 tabs in a row in original
string):
// 80 tabs
const char tabs[]="tttttttttttttttttttt"
"tttttttttttttttttttt"
"tttttttttttttttttttt"
"tttttttttttttttttttt";
for (int i=0; i boost::algorithm::replace_all(str, tabs+i, " ");

Or maybe this (assumes no more than about 16000 tabs in a row):
const char tabs[]="tttttttttttt"; // 12 tabs
int i;
// Strings of 18 or more tabs have 16 tabs removed...
for (i=0; i<999; ++i)
boost::algorithm::replace_all(str, tabs, tabs+10);
for (i=0; i<=10; ++i)
boost::algorithm::replace_all(str, tabs+i, " ");

Wouldn't boost::regex and boost::replace be a better solution,
with a regex pattern of "\t+" and a replace pattern of " "?

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
John Potter
Guest





PostPosted: Wed Apr 20, 2005 3:52 pm    Post subject: Re: STL: Replacing consecutive matching elements in a string Reply with quote

On 19 Apr 2005 19:00:31 -0400, "Allan W" <allan_w (AT) my-dejanews (DOT) com>
wrote:

Quote:
lotusny78 (AT) yahoo (DOT) com wrote:
I'm trying to use the STL to replace every time there are
consecutive tabs with ' ' in a string.

simont wrote:
Perhaps something like
boost::algorithm::replace_all( str, "tt", " " );

But if there are five tabs in a row, this would only replace four of
them -- and it would replace them with two spaces instead of just one.

Exactly what the original code did. Why are you changing the problem?

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
E. Mark Ping
Guest





PostPosted: Thu Apr 21, 2005 2:36 am    Post subject: Re: STL: Replacing consecutive matching elements in a string Reply with quote

In article <1113984974.749659.76450 (AT) l41g2000cwc (DOT) googlegroups.com>,
<kanze (AT) gabi-soft (DOT) fr> wrote:
Quote:
Allan W wrote:
[email]lotusny78 (AT) yahoo (DOT) com[/email] wrote:

I'm trying to use the STL to replace every time there are
consecutive tabs with ' ' in a string.

Wouldn't boost::regex and boost::replace be a better solution,
with a regex pattern of "\t+" and a replace pattern of " "?

Or better yet, a regex pattern of "\t\t+".
--
Mark Ping
[email]emarkp (AT) soda (DOT) CSUA.Berkeley.EDU[/email]

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.