473,416 Members | 1,858 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,416 software developers and data experts.

search and replace

C++ers:

Here's an open ended STL question. What's the smarmiest most templated way
to use <string>, <algorithms> etc. to turn this:

" able search baker search charlie "

into this:

" able replace baker replace charlie "

Note that "replace" has one more letter than "search", so you can't do an
inplace substitution.

An alternate prize goes to whoever provides an efficient way (that doesn't
use simple things like character pointers and buffers and C things ;).

(We are aware several C++ Regexps are available; we just need to learn more
raw STL here.)

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Nov 10 '05 #1
22 11064
Tom


"Phlip" <ph******@yahoo.com> wrote in message
news:hn****************@newssvr17.news.prodigy.com ...
C++ers:

Here's an open ended STL question. What's the smarmiest most templated way
to use <string>, <algorithms> etc. to turn this:

" able search baker search charlie "

into this:

" able replace baker replace charlie "

Note that "replace" has one more letter than "search", so you can't do an
inplace substitution.
The maximum number of chars in the resultant string in the
worst-case-scenario is

newLen = (oldLen/sizeOf(SearchString) )*sizeOf(ReplaceString);

so create a memory buffer with the above lenght, and keep inserting strings
from the source to this buffer, word by word, until you hit the searchword.
when you hit the searchword,
instead of inserting the searchword, insert the replace word.

hope you followd that, if you need code.. mail back to the group.


An alternate prize goes to whoever provides an efficient way (that doesn't
use simple things like character pointers and buffers and C things ;).

(We are aware several C++ Regexps are available; we just need to learn
more raw STL here.)

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!

Nov 10 '05 #2

These days every post here smells way too much like homework, but I'll
give you the benefit of the doubt :D.

Phlip wrote:
Here's an open ended STL question. What's the smarmiest most templated way
to use <string>, <algorithms> etc. to turn this:

" able search baker search charlie "

into this:

" able replace baker replace charlie "
I'm not really sure why you would need either <algorithm> or templates
here. Unless you want to be able to replace an int inside a string or
similar. Hmmmm...
Note that "replace" has one more letter than "search", so you can't do an
inplace substitution.


Why not? Watch me :D

#include <string>
#include <iostream>

using namespace std;

int main()
{
const string search = "search";
const string replace = "replace";

string text = " able search baker search charlie ";

string::size_type found_at = text.find( search );
while( string::npos != found_at )
{
text.replace( found_at, search.length(), replace );
found_at = text.find( search, found_at + search.length() );
}

cout << text << endl;
}

Cheers,
Andre

Nov 10 '05 #3
Phlip wrote:
C++ers:

Here's an open ended STL question. What's the smarmiest most templated way
to use <string>, <algorithms> etc. to turn this:

" able search baker search charlie "

into this:

" able replace baker replace charlie "

Note that "replace" has one more letter than "search", so you can't do an
inplace substitution.


Ok, it's not templated; but it is short:

#include <iostream>
#include <string>

void replace_all ( std::string & str,
std::string const & pattern,
std::string const & replacement ) {
std::string::size_type start = str.find( pattern, 0 );
while ( start != str.npos ) {
str.replace( start, pattern.size(), replacement );
start = str.find( pattern, start+replacement.size() );
}
}

int main ( void ) {
std::string banner = " able search baker search charlie ";
std::string pattern = "search";
std::string replacement = "replace";
std::cout << banner << '\n';
replace_all ( banner, pattern, replacement );
std::cout << banner << '\n';
}
Best regards

Kai-Uwe Bux

Nov 10 '05 #4
in*****@gmail.com wrote:

These days every post here smells way too much like homework, but I'll
give you the benefit of the doubt :D.

Phlip wrote:
Here's an open ended STL question. What's the smarmiest most templated
way to use <string>, <algorithms> etc. to turn this:

" able search baker search charlie "

into this:

" able replace baker replace charlie "


I'm not really sure why you would need either <algorithm> or templates
here. Unless you want to be able to replace an int inside a string or
similar. Hmmmm...
Note that "replace" has one more letter than "search", so you can't do an
inplace substitution.


Why not? Watch me :D

#include <string>
#include <iostream>

using namespace std;

int main()
{
const string search = "search";
const string replace = "replace";

string text = " able search baker search charlie ";

string::size_type found_at = text.find( search );
while( string::npos != found_at )
{
text.replace( found_at, search.length(), replace );
found_at = text.find( search, found_at + search.length() );
}

cout << text << endl;
}


Why not? here is why:

#include <string>
#include <iostream>

using namespace std;

int main()
{
const string search = "search";
const string replace = "devious_search_replacement";

string text = " able search baker search charlie ";

string::size_type found_at = text.find( search );
while( string::npos != found_at )
{
text.replace( found_at, search.length(), replace );
cout << text << endl;
found_at = text.find( search, found_at + search.length() );
}

cout << text << endl;
}
Best regards

Kai-Uwe Bux
Nov 10 '05 #5
* in*****@gmail.com:

These days every post here smells way too much like homework, but I'll
give you the benefit of the doubt :D.


Unless this Phlip is someone else than the regular Phlip, we can safely
discount the possibility of a homework question.

What surprises me is that Phlip wants to do this in C++, not in Ruby...

Anyways, for efficiency, I think a two-pass approach is indicated: first
find number of occurrences of the search pattern to be replaced, then
allocate buffer, then copy over with search pattern replaced. For an
original string of length n, that reduces the time from O(n^2) to O(n).
Of course the real decider would be to measure, measure, measure,
because two-pass might much _slower_ for short (typical?) strings.

How to do the searching efficiently depends on what's known about the
data.

For a long string the skipping algorithm used in various grep's could be
employed, and likewise for doing the same replacement on a multitude of
strings, but for a single global replacement on a short string using
skipping might be counter-productive because of the setup time. And to
bring that back on-topic (namely, C++), Phlip might be well advised --
or not -- to check out the facilities of the first standard library
Technical Report, the TR1. As I recall there is some regexp in there.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 10 '05 #6

Kai-Uwe Bux wrote:
in*****@gmail.com wrote:
Note that "replace" has one more letter than "search", so you can't do an
inplace substitution.
Why not? Watch me :D

#include <string>
#include <iostream>

using namespace std;

int main()
{
const string search = "search";
const string replace = "replace";

string text = " able search baker search charlie ";

string::size_type found_at = text.find( search );
while( string::npos != found_at )
{
text.replace( found_at, search.length(), replace );
found_at = text.find( search, found_at + search.length() );
}

cout << text << endl;
}


Why not? here is why:

#include <string>
#include <iostream>

using namespace std;

int main()
{
const string search = "search";
const string replace = "devious_search_replacement";

string text = " able search baker search charlie ";

string::size_type found_at = text.find( search );
while( string::npos != found_at )
{
text.replace( found_at, search.length(), replace );
cout << text << endl;
found_at = text.find( search, found_at + search.length() );


You spotted my mistake here. This should read:
found_at = text.find( search, found_at + replace.length() );
}

cout << text << endl;
}

Cheers,
Andre

Nov 10 '05 #7

"Phlip" <ph******@yahoo.com> wrote in message
news:hn****************@newssvr17.news.prodigy.com ...
C++ers:

Here's an open ended STL question. What's the smarmiest most templated way
to use <string>, <algorithms> etc. to turn this:

" able search baker search charlie "

into this:

" able replace baker replace charlie "

Note that "replace" has one more letter than "search", so you can't do an
inplace substitution.

An alternate prize goes to whoever provides an efficient way (that doesn't
use simple things like character pointers and buffers and C things ;).


heh this is in Haskell:

searchReplace srch rpls xs = unwords $ searchReplace' srch rpls $ words xs
searchReplace' _ _ [] = []
searchReplace' srch rpls (x:xs) | x==srch = rpls:searchReplace' srch rpls
xs
| otherwise = x:searchReplace' srch rpls xs
C++:
string searchReplace(string search,string replace,string xs)
{
istringstream is(xs);string tmp;
ostringstream os;
while(is>>tmp)if(tmp==search)os<<replace;else os<<tmp;
return os.str();
}

I don't know which STL algorithm is equialent of this.

Greetings, Bane.
Nov 10 '05 #8

"Branimir Maksimovic" <bm***@eunet.yu> wrote in message
news:dk**********@news.eunet.yu...

C++:
string searchReplace(string search,string replace,string xs)
{
istringstream is(xs);string tmp;
ostringstream os;
while(is>>tmp)if(tmp==search)os<<replace;else os<<tmp; while(is>>tmp)
{
if(tmp==search)os<<replace;else os<<tmp;
os<<' ';
}
return os.str();
}


Of course this is only if spaces are not important.

Greetings, Bane.
Nov 10 '05 #9
Kai-Uwe Bux wrote:
Ok, it's not templated; but it is short:
I kind'a meant "STL-obsessed". Not just templated.
void replace_all ( std::string & str,
std::string const & pattern,
std::string const & replacement ) {
std::string::size_type start = str.find( pattern, 0 );
while ( start != str.npos ) {
str.replace( start, pattern.size(), replacement );
start = str.find( pattern, start+replacement.size() );
}
}


Great; everyone posted a loop with a find!

My colleague came up with this. Somehow:

stringstream ss;
ostream_iterator<string> outIterator(ss);

transform( m_str.begin(), m_str.end(), outIterator,
swap_character(asciiChar, substituteString) );

m_str = ss.str();

Note that it's a member of some method that transforms a member string
m_str, and that it searches for a single character and replaces it with
a string.

Could one upgrade that to work on a string?

Is its performance profile more or less "guaranteed" than the entries
so far?

The question ain't in Ruby because the answer is too danged simple -
Regular expressions are built-in, overhead and all...

--
Phlip

Nov 10 '05 #10

Phlip wrote:
Kai-Uwe Bux wrote:
Ok, it's not templated; but it is short:


I kind'a meant "STL-obsessed". Not just templated.


Ok, based on your coworkers idea, I came up with this one:

#include <iostream>
#include <iterator>
#include <string>
#include <sstream>
#include <algorithm>

using namespace std;

class SearchAndReplace
{
public:
SearchAndReplace( const string & search, const string & replace )
: search_( search )
, replace_( replace )
, match_len_( 0 )
{
}

string operator() ( const char & c )
{
string s = "";

if ( c == search_[ match_len_ ] )
{
++match_len_;

if ( match_len_ == search_.length() )
{
s = replace_;
match_len_ = 0;
} else {
s = "";
}
} else {
if ( match_len_ > 0 )
s = search_.substr( 0, match_len_ );

s += c;
match_len_ = 0;
}

return s;
}

private:
string search_;
string replace_;
unsigned match_len_;
};

int main()
{
const string in = "Blo bla blo bla blo!";
const string search = "bla";
const string replace = "bliblaeeeep";

stringstream ss;
ostream_iterator< string > out( ss );

transform( in.begin(), in.end(), out,
SearchAndReplace( search, replace ) );

cout << ss.str() << endl;
}
How's that look?

Cheers,
Andre

Nov 11 '05 #11
Thats my code with recursion, not optimize but works fine.

void ReplaceString(string &orginal,string searchstring,string value)
{
int pos;

pos = orginal.find (searchstring, 0);
if (pos < 0 ) return;

string s;
s = orginal;
orginal = s.substr(0,pos);
string rest = s.substr(pos + searchstring.length());
orginal = orginal + value + rest;
ReplaceString(orginal,searchstring,value);
}

Howie
Nov 11 '05 #12
Howie wrote:
Thats my code with recursion, not optimize but works fine.
No, it does not.
void ReplaceString(string &orginal,string searchstring,string value)
{
int pos;

pos = orginal.find (searchstring, 0);
if (pos < 0 ) return;

string s;
s = orginal;
orginal = s.substr(0,pos);
string rest = s.substr(pos + searchstring.length());
orginal = orginal + value + rest;
ReplaceString(orginal,searchstring,value);
}


Try:

int main ( void ) {
const string search = "search";
const string replace = "devious_search_replacement";

string text = " able search baker search charlie ";

ReplaceString( text, search, replace );
}

or:

int main ( void ) {
const string search = "search";
const string replace = "search";

string text = " able search search charlie ";

ReplaceString( text, search, replace );
}

Both run into an infinite loop.

To fix the problem, you might consider to swap the last to instructions:

void ReplaceString(string &orginal,string searchstring,string value)
{
int pos;

pos = orginal.find (searchstring, 0);
if (pos < 0 ) return;

string s;
s = orginal;
orginal = s.substr(0,pos);
string rest = s.substr(pos + searchstring.length());
ReplaceString( rest, searchstring, value );
orginal = orginal + value + rest;
}
Best

Kai-Uwe Bux
Nov 11 '05 #13
On Fri, 11 Nov 2005 01:42:10 -0500, Kai-Uwe Bux <jk********@gmx.net>
wrote:
Howie wrote:
Thats my code with recursion, not optimize but works fine.


No, it does not.
void ReplaceString(string &orginal,string searchstring,string value)
{
int pos;

pos = orginal.find (searchstring, 0);
if (pos < 0 ) return;

string s;
s = orginal;
orginal = s.substr(0,pos);
string rest = s.substr(pos + searchstring.length());
orginal = orginal + value + rest;
ReplaceString(orginal,searchstring,value);
}


Try:

int main ( void ) {
const string search = "search";
const string replace = "devious_search_replacement";

string text = " able search baker search charlie ";

ReplaceString( text, search, replace );
}

or:

int main ( void ) {
const string search = "search";
const string replace = "search";

string text = " able search search charlie ";

ReplaceString( text, search, replace );
}

Both run into an infinite loop.

Thanks Kai-Uwe,

this problem didn´t occur yet. I have fixed it.

Howie
Nov 11 '05 #14
On 2005-11-10, Phlip <ph*******@gmail.com> wrote:
Great; everyone posted a loop with a find!
Well, it's hard to think of anything better.
My colleague came up with this. Somehow:

stringstream ss;
ostream_iterator<string> outIterator(ss);

transform( m_str.begin(), m_str.end(), outIterator,
swap_character(asciiChar, substituteString) );

m_str = ss.str();

Note that it's a member of some method that transforms a member
string m_str, and that it searches for a single character and
replaces it with a string.

Could one upgrade that to work on a string?

Is its performance profile more or less "guaranteed" than the
entries so far?


It looks slower to me, as at least two copies of the input string
have to be made, whereas the string member function version
doesn't necessarily make any copies. Moreover, iostreams are
heavy duty iron for such a simple task.

I'd call the idea clever but impractical. I'm not sure if it's
smarmy. ;-)

--
Neil Cerutti
Nov 11 '05 #15
On 2005-11-11, in*****@gmail.com <in*****@gmail.com> wrote:

Phlip wrote:
Kai-Uwe Bux wrote:
> Ok, it's not templated; but it is short:


I kind'a meant "STL-obsessed". Not just templated.


Ok, based on your coworkers idea, I came up with this one:

#include <iostream>
#include <iterator>
#include <string>
#include <sstream>
#include <algorithm>

using namespace std;

class SearchAndReplace
{
public:
SearchAndReplace( const string & search, const string & replace )
: search_( search )
, replace_( replace )
, match_len_( 0 )
{
}

string operator() ( const char & c )
{
string s = "";

if ( c == search_[ match_len_ ] )
{
++match_len_;

if ( match_len_ == search_.length() )
{
s = replace_;
match_len_ = 0;
} else {
s = "";
}
} else {
if ( match_len_ > 0 )
s = search_.substr( 0, match_len_ );

s += c;
match_len_ = 0;
}

return s;
}

private:
string search_;
string replace_;
unsigned match_len_;
};

int main()
{
const string in = "Blo bla blo bla blo!";
const string search = "bla";
const string replace = "bliblaeeeep";

stringstream ss;
ostream_iterator< string > out( ss );

transform( in.begin(), in.end(), out,
SearchAndReplace( search, replace ) );

cout << ss.str() << endl;
}
How's that look?


Almost.

Consider in = "Blo blbla blo blbla blo!" for the same search and
replace.

--
Neil Cerutti
Nov 11 '05 #16
Phlip wrote:
C++ers:

Here's an open ended STL question. What's the smarmiest most templated way
to use <string>, <algorithms> etc. to turn this:

" able search baker search charlie "

into this:

" able replace baker replace charlie "

Note that "replace" has one more letter than "search", so you can't do an
inplace substitution.

An alternate prize goes to whoever provides an efficient way (that doesn't
use simple things like character pointers and buffers and C things ;).


Ok, here is my entry for the efficiency contest:
void replace_all ( std::string & str,
std::string const & pattern,
std::string const & replacement ) {
std::string::size_type const pattern_length = pattern.size();
std::string::size_type const str_length = str.length();
typedef std::vector< std::string::size_type > location_vect;
location_vect hits;
std::string::size_type start = str.find( pattern, 0 );
while ( start != str.npos ) {
hits.push_back( start );
start = str.find( pattern, start+pattern_length );
}
std::string dummy;
dummy.reserve( str_length
+
hits.size()*( replacement.length() - pattern_length ) );
std::string::size_type from = 0;
std::string::size_type to;
for ( location_vect::size_type chunk_index = 0;
chunk_index < hits.size(); ++ chunk_index ) {
to = hits[ chunk_index ];
dummy.append( str, from, to-from );
dummy.append( replacement );
from = to + pattern_length;
}
to = str_length;
dummy.append( str, from, to-from );
str.swap( dummy );
}
Best

Kai-Uwe Bux

Nov 11 '05 #17

Neil Cerutti wrote:
On 2005-11-11, in*****@gmail.com <in*****@gmail.com> wrote:

Phlip wrote:
Kai-Uwe Bux wrote:

> Ok, it's not templated; but it is short:

I kind'a meant "STL-obsessed". Not just templated.


Ok, based on your coworkers idea, I came up with this one:

#include <iostream>
#include <iterator>
#include <string>
#include <sstream>
#include <algorithm>

using namespace std;

[snipped broken functor]

int main()
{
const string in = "Blo bla blo bla blo!";
const string search = "bla";
const string replace = "bliblaeeeep";

stringstream ss;
ostream_iterator< string > out( ss );

transform( in.begin(), in.end(), out,
SearchAndReplace( search, replace ) );

cout << ss.str() << endl;
}
How's that look?


Almost.

Consider in = "Blo blbla blo blbla blo!" for the same search and
replace.


You're right! Thanks.

Revised functor:

class SearchAndReplace
{
public:
SearchAndReplace( const string & search, const string & replace )
: search_( search )
, replace_( replace )
, match_len_( 0 )
{
}

string operator() ( const char & c )
{
string s = "";

if ( c != search_[ match_len_ ] && match_len_ > 0 )
{
s = search_.substr( 0, match_len_ );
match_len_ = 0;
}

if ( c == search_[ match_len_ ] )
{
++match_len_;

if ( match_len_ == search_.length() )
{
s = replace_;
match_len_ = 0;
}
} else {
s += c;
}

return s;
}

private:
string search_;
string replace_;
unsigned match_len_;
};

Nov 11 '05 #18
Phlip wrote:
Kai-Uwe Bux wrote:
Ok, it's not templated; but it is short:


I kind'a meant "STL-obsessed". Not just templated.
void replace_all ( std::string & str,
std::string const & pattern,
std::string const & replacement ) {
std::string::size_type start = str.find( pattern, 0 );
while ( start != str.npos ) {
str.replace( start, pattern.size(), replacement );
start = str.find( pattern, start+replacement.size() );
}
}


Great; everyone posted a loop with a find!

My colleague came up with this. Somehow:

stringstream ss;
ostream_iterator<string> outIterator(ss);

transform( m_str.begin(), m_str.end(), outIterator,
swap_character(asciiChar, substituteString) );

m_str = ss.str();

Note that it's a member of some method that transforms a member string
m_str, and that it searches for a single character and replaces it with
a string.

Could one upgrade that to work on a string?


transform in this case works with single chars, you have to convert
to a sequence of strings in order to work with this algorithm.
My first example can be converted to work with transform
but that does not satisfies, if spaces are not regarded as delimiters.

I'm learning Haskell and functional programming,
so I found this as a good practicing :).
Here is another version of code in both Haskell and coresponding C++
which works as you expected, I hope.
note there is no single temporary string created in C++ code.:)

// begin C++ ---------------------
#include <iostream>
#include <utility>

using namespace std;

typedef pair<string::iterator,string::iterator> Tuple1;
typedef pair<Tuple1,string::iterator> Tuple2;
typedef pair<bool,Tuple2> Tuple3;

Tuple3
searchr_p(string::iterator srb,string::iterator sre,
string::iterator xsb,string::iterator xse,
string::iterator fndb,string::iterator fnde)
{

if(srb == sre && xsb == xse)
return Tuple3(true,Tuple2(Tuple1(fndb,fnde),xsb));
if(srb == sre)
return Tuple3(true,Tuple2(Tuple1(fndb,fnde),xsb));
if(xsb == xse)
return Tuple3(false,Tuple2(Tuple1(fndb,fnde),xsb));

++fnde;
if(*srb == *xsb)
return searchr_p(++srb,sre,++xsb,xse,fndb,fnde);
else
return Tuple3(false,Tuple2(Tuple1(fndb,fnde),++xsb));
}

string&
searchr(string& sr,
string& rp,
string::iterator xsb,string::iterator xse,
string& out
)
{
if(sr.empty() || rp.empty() || xsb == xse)return out;

Tuple3 fnd = searchr_p(sr.begin(),sr.end(),
xsb,xse,
xsb,xsb);

if(fnd.first)
{
out+= rp;
searchr(sr,rp,fnd.second.second,xse,out);
}
else
{
out.append(fnd.second.first.first,fnd.second.first .second);
searchr(sr,rp,fnd.second.second,xse,out);
}
return out;
}
int main()
{
string sr = "search",rp="replace",str=" able search baker search
charlie ";
string out;
cout<<searchr(sr,rp,str.begin(),str.end(),out)<<'\ n';
}

// end C++

module Main where
import IO
main = do
sr <- getLine
rp <- getLine
str<- getLine
putStrLn $ "Working:" ++ sr ++ " " ++ rp ++ " " ++ str
putStrLn $ searchr sr rp str
putStrLn "Done"
{- search replace " able search baker search charlie " -}

-------------------------------------------------------------------------------

searchr :: String->String->String -> String
searchr [] _ xs = xs
searchr _ [] xs = xs
searchr _ _ [] = []
searchr sr rp xs | fst fnd = rp ++ searchr sr rp (snd $ snd fnd)
| otherwise = (fst $ snd fnd) ++
searchr sr rp (snd $ snd fnd)
where fnd = searchr' sr xs ""

searchr' :: String->String->String -> (Bool,(String,String))
searchr' [] [] fnd = (True,(fnd,[]))
searchr' [] xs fnd = (True,(fnd,xs))
searchr' sr [] fnd = (False,(fnd,[]))
searchr' (sr:srs) (x:xs) fndSoFar | sr == x = searchr' srs xs xxs
| otherwise = (False,(xxs,xs))
where xxs = x:fndSoFar
-------------------------------------------------------------------------------

Greetings, Bane.

Nov 11 '05 #19

"Phlip" <ph******@yahoo.com> wrote in message
news:hn****************@newssvr17.news.prodigy.com ...
C++ers:

Here's an open ended STL question. What's the smarmiest most templated way
to use <string>, <algorithms> etc. to turn this:

" able search baker search charlie "

into this:

" able replace baker replace charlie "

Note that "replace" has one more letter than "search", so you can't do an
inplace substitution.

An alternate prize goes to whoever provides an efficient way (that doesn't
use simple things like character pointers and buffers and C things ;).


Here is mine entry for efficiency contest :)

#include <iostream>
#include <utility>
#include <string>

using namespace std;

typedef pair<string::iterator,string::iterator> Tuple1;
typedef pair<Tuple1,string::iterator> Tuple2;
typedef pair<bool,Tuple2> Tuple3;

Tuple3
searchr_p(string::const_iterator srb,string::const_iterator sre,
string::iterator xsb,string::iterator xse,
string::iterator fndb,string::iterator fnde)
{

string::const_iterator tmps = srb;
while(srb != sre && xsb != xse && *srb==*xsb)
{
++fnde;++srb;++xsb;
}
if(srb == sre)
return Tuple3(true,Tuple2(Tuple1(fndb,fnde),xsb));
if(xsb == xse)
return Tuple3(false,Tuple2(Tuple1(fndb,fnde),xsb));

while(xsb!=xse && *tmps!=*xsb)
{
++fnde;++xsb;
}

return Tuple3(false,Tuple2(Tuple1(fndb,fnde),xsb));
}

string&
searchr(const string& sr,
const string& rp,
string::iterator xsb,string::iterator xse,
string& out
)
{
if(sr.empty() || rp.empty() || xsb == xse)return out.append(xsb,xse);

Tuple3 fnd = searchr_p(sr.begin(),sr.end(),
xsb,xse,
xsb,xsb);
while(fnd.second.first.first != fnd.second.first.second)
{
if(fnd.first)
{
out+= rp;
}
else
{
out.append(fnd.second.first.first,fnd.second.first .second);
}
fnd = searchr_p(sr.begin(),sr.end(),
fnd.second.second,xse,
fnd.second.second,fnd.second.second);
}
return out;
}
int main()
{
string sr = "search",rp="replace",str=" able search sea baker search
charlie ";
string out,tmp=str;
for (int i =0;i<1000000;++i)str+=tmp;
searchr(sr,rp,str.begin(),str.end(),out);
}

Greetings, Bane.
Nov 22 '05 #20
In message <sl**********************@FIAD06.norwich.edu>, Neil Cerutti
<le*******@email.com> writes
On 2005-11-10, Phlip <ph*******@gmail.com> wrote:
Great; everyone posted a loop with a find!


Well, it's hard to think of anything better.
My colleague came up with this. Somehow:

stringstream ss;
ostream_iterator<string> outIterator(ss);

transform( m_str.begin(), m_str.end(), outIterator,
swap_character(asciiChar, substituteString) );

m_str = ss.str();

Note that it's a member of some method that transforms a member
string m_str, and that it searches for a single character and
replaces it with a string.

Could one upgrade that to work on a string?

Is its performance profile more or less "guaranteed" than the
entries so far?


It looks slower to me, as at least two copies of the input string
have to be made, whereas the string member function version
doesn't necessarily make any copies. Moreover, iostreams are
heavy duty iron for such a simple task.

I'd call the idea clever but impractical. I'm not sure if it's
smarmy. ;-)

For smarmy++, there should be no explicit use of for, while, if, etc.,
which should all be hidden within an appropriate STL algorithm. Some of
the other competitors don't seem to have absorbed this principle ;-)

--
Richard Herring
Nov 22 '05 #21
Phlip wrote:
C++ers:

Here's an open ended STL question. What's the smarmiest most templated way
to use <string>, <algorithms> etc. to turn this:

" able search baker search charlie "

into this:

" able replace baker replace charlie "

Note that "replace" has one more letter than "search", so you can't do an
inplace substitution.

An alternate prize goes to whoever provides an efficient way (that doesn't
use simple things like character pointers and buffers and C things ;).

(We are aware several C++ Regexps are available; we just need to learn more
raw STL here.)


Using routines to find the substring ,to reverse the end of the string
and add a string to the end will do the job. The sequence of
intermediate strings would be as follows:

" able search baker search charlie "
" able ielrahc hcraes rekab hcraes"
" able ielrahc hcraes rekab "
" able ielrahc hcraes rekab ecalper"
" able replace baker search charlie "
" able replace baker ielrahc hcraes"
" able replace baker ielrahc "
" able replace baker ielrahc ecalper"
" able replace baker replace charlie "

You should be able to work the rest out for yourself. But as you can see
this method only requires the buffer for the string to be increased by 2
characters and no separate buffers, as well as using simple, easily
understood algorithms.

JFJB
Nov 22 '05 #22
n2xssvv g02gfr12930 wrote:
Phlip wrote:
C++ers:

Here's an open ended STL question. What's the smarmiest most templated
way to use <string>, <algorithms> etc. to turn this:

" able search baker search charlie "

into this:

" able replace baker replace charlie "

Note that "replace" has one more letter than "search", so you can't do
an inplace substitution.

An alternate prize goes to whoever provides an efficient way (that
doesn't use simple things like character pointers and buffers and C
things ;).

(We are aware several C++ Regexps are available; we just need to learn
more raw STL here.)


Using routines to find the substring ,to reverse the end of the string
and add a string to the end will do the job. The sequence of
intermediate strings would be as follows:

" able search baker search charlie "
" able ielrahc hcraes rekab hcraes"
" able ielrahc hcraes rekab "
" able ielrahc hcraes rekab ecalper"
" able replace baker search charlie "
" able replace baker ielrahc hcraes"
" able replace baker ielrahc "
" able replace baker ielrahc ecalper"
" able replace baker replace charlie "

You should be able to work the rest out for yourself. But as you can see
this method only requires the buffer for the string to be increased by 2
characters and no separate buffers, as well as using simple, easily
understood algorithms.

JFJB

Here's the code using STL library functions

void ReplaceTest(void)
{
std::string Tmp(" able search baker search charlie ");

std::cout << Tmp << std::endl;

std::string::size_type p = Tmp.find("search",0);
std::reverse(Tmp.begin() + p,Tmp.end());
Tmp.erase(Tmp.end() - 6,Tmp.end());
Tmp += "ecalper";
std::reverse(Tmp.begin() + p,Tmp.end());

p = Tmp.find("search",0);
std::reverse(Tmp.begin() + p,Tmp.end());
Tmp.erase(Tmp.end() - 6,Tmp.end());
Tmp += "ecalper";
std::reverse(Tmp.begin() + p,Tmp.end());

std::cout << Tmp << std::endl;
}

JFJB
Nov 22 '05 #23

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Les Juby | last post by:
A year or two back I needed a search script to scan thru HTML files on a client site. Usual sorta thing. A quick search turned up a neat script that provided great search results. It was fast,...
10
by: pembed2003 | last post by:
Hi all, I asked this question in the C group but no one seems to be interested in answering it. :-( Basically, I wrote a search and replace function so I can do: char source = "abcd?1234?x";...
5
by: pembed2003 | last post by:
Hi all, I need to write a function to search and replace part of a char* passed in to the function. I came up with the following: char* search_and_replace(char* source,char search,char*...
32
by: tshad | last post by:
Can you do a search for more that one string in another string? Something like: someString.IndexOf("something1","something2","something3",0) or would you have to do something like: if...
2
by: Dennis | last post by:
I am trying to implement a "Find and Replace" dialog that allows using wildcards in the find string, much like the Find and Replace Dialogs in Ms Word, etc. Are there any references or examples on...
2
by: Ola K | last post by:
Hi guys, I wrote a script that works *almost* perfectly, and this lack of perfection simply puzzles me. I simply cannot point the whys, so any help on it will be appreciated. I paste it all here,...
9
by: tomjones75 | last post by:
dear community, i want to search the content of all fields in one table in a access database. it already works for the content of one field in the table. please take a look at the code in...
14
by: Simon Gare | last post by:
Hi, have a search.asp page with results.asp page drawing data from an SQL db, problem is the user has to type the whole field value into the search box to retrieve the value on results.asp, what...
1
Merlin1857
by: Merlin1857 | last post by:
How to search multiple fields using ASP A major issue for me when I first started writing in VB Script was constructing the ability to search a table using multiple field input from a form and...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.