String editing in C++

Started by
10 comments, last by Curtis123 21 years, 2 months ago
What I want to be able to do is to change each character separately.(BTW I am using C++). So, for another example, If the user enters a string like "Hello, how are you?", I want to be able to go into it and change it by using character substitution, like "Guiou, eur ury rng?" (P.S., that doesn't really mean anything it's just an example). So do you (or anyone?) know how to do this? I've already tried using character arrays like: if(mystring[0] = 'A') { mystring[0] = 'B' } Plus, doing that would take forever, because I'd have to check each character 26 times. So, if anyone knows anything, Please tell me, even a tidbit of info can help! - Ow. Stop shouting. -fel [edited by - felisandria on February 6, 2003 7:46:12 PM]
Advertisement
std::string test = "Hello, this is a test";std::replace_if(test.begin(),test.end(),std::bind2nd(std::equal_to<char>(),'i'),'a');  


That will produce the string: "Hello, thas as a test"

[edited by - daerid on February 6, 2003 7:22:02 PM]
daerid@gmail.com
lets say that the source string only contains As, Bs, and Cs and you want to turn them into Gs, Ws, and Zs.

so BAC will become WGZ

make an array of 3 characters and but G,W,Z into it. Then make a loop that goes through every character of the string. Use the character as an index into the array. So if you have "replacement" as the name of your array and you encounter a letter A you want the 0th cell of the array. So we need to turn A into 0. How do we do that? Subtract ''A'', you can do math with letters. Likewise ''B'' - ''A'' equals 1, so you''ll get access to the cell that contains the W. ''C'' - ''A'' equals 2, so that will give you the Z.
You could make a map from one character set to another.

PS Your code is buggy

if(mystring[0] = ''A'')
{

This will assign ''A'' to mystring[0]. You really mean to use == for comparison.
daerid: Or, simpler:

  std::string test = "Hello, this is a test";std::replace ( test.begin(), test.end(), ''i'', ''a'' );  


-Neophyte
int p1, p2, i;char code[256];string s;s = GetStringFrom(place);for(i = 0; i < 256; i++){     code[i] = i;}for(i = 0; i < 100; i++){     p1 = (rand() * 26)/RAND_MAX;     p2 = (rand() * 26)/RAND_MAX;     code[p1+'a'] ^= code[p2+'a'];     code[p2+'a'] ^= code[p1+'a'];     code[p1+'a'] ^= code[p2+'a'];}for(i = 'A'; i <= 'Z'; i++){     code[i] = code[('a'-'A')+i];}for(i = 0; i < s.length(); i++){     s[i] = code[s[i]];} 


Might need some slight changes to compile/work, but in theory it should do the job =-)

[edited by - Extrarius on February 11, 2003 2:06:28 AM]
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Why bother with all the extraneous XOR''s?
daerid@gmail.com
quote:Original post by daerid
Why bother with all the extraneous XOR''s?


There aren''t any. The first one puts the result at p1, the second at p2, and the third at p3. Its just a different way to swap the character at p1 and p2. You could write that loop as:
for(i = 0; i < 100; i++){     char temp;     p1 = (rand() * 26)/RAND_MAX;     p2 = (rand() * 26)/RAND_MAX;     temp = code[p2+''a''];     code[p2+''a''] = code[p1+''a''];     code[p1+''a''] = temp;} 

instead if you really wanted to - it does the same thing.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk

  mystring[i]=lookup[mystring[i]];  
Keys to success: Ability, ambition and opportunity.
Everyone''s solution thus far except for petewood''s will be quadratic in terms of the number of pairs in the mapping and the length of the string. Fleshing out petewood''s idea you can do the following.


  using std::map;using std::string;map<char, char> f;string s;...string::iterator i;for (i = s.begin(); i != s.end(); ++i) {    *i = f[*i];}  


Since a lookup in a map is O(log2(n)), the overall algorithm is O(log2(n) x m) where n is the number of pairs inserted into the map f and m is the length of the string s. This makes one key assumption though, that f is defined for all characters in s. This means you have to initialize f to be an identity mapping and then substitute your own pairs as needed. This method is fine if you translate nearly your entire alphabet and expect to almost always need to translate a character. It makes the added size of the map and the time to apply an identity transofmration negligable. Or...


  string::iterator i;map<char, char>::iterator c;for (i = s.begin(); i != s.end(); ++i) {    c = f.find(*i);    if (c != 0) {        *i = c->second;    }}  


The above only translates a character if it is found in the map. The running time is O(log2(k) x m). You don''t have to initialize your map and thus there is less cost in terms of space. But I dunno... I probably made a mistake or two somewhere.

This topic is closed to new replies.

Advertisement