 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
lotusny78@yahoo.com Guest
|
Posted: Fri Apr 15, 2005 7:27 am Post subject: STL: Replacing consecutive matching elements in a string |
|
|
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
|
Posted: Sat Apr 16, 2005 12:05 am Post subject: Re: STL: Replacing consecutive matching elements in a string |
|
|
[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
|
Posted: Sat Apr 16, 2005 12:06 am Post subject: Re: Replacing consecutive matching elements in a string |
|
|
| 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
|
Posted: Sat Apr 16, 2005 5:40 pm Post subject: Re: Replacing consecutive matching elements in a string |
|
|
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
|
Posted: Sat Apr 16, 2005 5:43 pm Post subject: Re: STL: Replacing consecutive matching elements in a string |
|
|
[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
|
Posted: Sun Apr 17, 2005 2:25 pm Post subject: Re: STL: Replacing consecutive matching elements in a string |
|
|
[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
|
Posted: Sun Apr 17, 2005 3:38 pm Post subject: Re: STL: Replacing consecutive matching elements in a string |
|
|
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
|
Posted: Sun Apr 17, 2005 6:04 pm Post subject: Re: STL: Replacing consecutive matching elements in a string |
|
|
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
|
Posted: Sun Apr 17, 2005 9:21 pm Post subject: Re: STL: Replacing consecutive matching elements in a string |
|
|
<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
|
Posted: Sun Apr 17, 2005 9:21 pm Post subject: Re: STL: Replacing consecutive matching elements in a string |
|
|
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
|
Posted: Tue Apr 19, 2005 11:00 pm Post subject: Re: STL: Replacing consecutive matching elements in a string |
|
|
| 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
|
Posted: Wed Apr 20, 2005 12:34 pm Post subject: Re: STL: Replacing consecutive matching elements in a string |
|
|
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
|
Posted: Wed Apr 20, 2005 3:52 pm Post subject: Re: STL: Replacing consecutive matching elements in a string |
|
|
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
|
Posted: Thu Apr 21, 2005 2:36 am Post subject: Re: STL: Replacing consecutive matching elements in a string |
|
|
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 |
|
 |
|
|
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
|
|