Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #15158 > unrolled thread

comparing two std::string variables

Started byGus Gassmann <horand.gassmann@googlemail.com>
First post2012-03-28 15:25 -0700
Last post2012-03-29 00:46 -0700
Articles 6 — 5 participants

Back to article view | Back to comp.lang.c++


Contents

  comparing two std::string variables Gus Gassmann <horand.gassmann@googlemail.com> - 2012-03-28 15:25 -0700
    Re: comparing two std::string variables Tomasz D <tdolbniak@gmail.com> - 2012-03-28 23:25 -0700
    Re: comparing two std::string variables Gus Gassmann <horand.gassmann@googlemail.com> - 2012-03-29 03:18 -0700
      Re: comparing two std::string variables "AnonMail2005@gmail.com" <anonmail2005@gmail.com> - 2012-03-29 10:33 -0700
      Re: comparing two std::string variables Timothy Madden <terminatorul@gmail.com> - 2012-04-09 13:02 -0700
    Re: comparing two std::string variables nick_keighley_nospam@hotmail.com - 2012-03-29 00:46 -0700

#15158 — comparing two std::string variables

FromGus Gassmann <horand.gassmann@googlemail.com>
Date2012-03-28 15:25 -0700
Subjectcomparing two std::string variables
Message-ID<df58aa78-c003-4a2a-8fb8-8d602ee51b3e@a5g2000vbl.googlegroups.com>
I am trying to compare two std::string objects str1 and str2. Both
strings are rather long (~70000 characters). The first one is read
from a file, the second one is generated by a program. I am trying to
establish that the two strings are equal. However, it turns out that
the string read in from the file has additional white space in several
places. (The white space does not concern me; I will declare the
strings equal if the other characters match.)  In order to compare
them it seems that I must compress them both. What is the best way to
do that? Do I have to copy each std::string to a char*, or is there a
better way?

Thanks

gus

[toc] | [next] | [standalone]


#15160

FromTomasz D <tdolbniak@gmail.com>
Date2012-03-28 23:25 -0700
Message-ID<22526991.1156.1333002301389.JavaMail.geo-discussion-forums@vbxy18>
In reply to#15158
If you already have the code that reads the contents of a file into a string you could consider comparing hashes of strings instead of strings themselves.

But if I were to solve such problem I think I would try doing it "sequentially": 

1. read in a couple of bytes
2. compare to the corresponding part of the generated string
3. stop the whole process if the compared parts are not equal
4. back to 1

This could save you some time and resources needed for reading in the whole file if the difference is found before the EOF.

[toc] | [prev] | [next] | [standalone]


#15161

FromGus Gassmann <horand.gassmann@googlemail.com>
Date2012-03-29 03:18 -0700
Message-ID<68b6ce30-a7a5-42aa-8254-bfbaef3dfcb2@n5g2000vbf.googlegroups.com>
In reply to#15158
On Mar 29, 4:46 am, nick_keighley_nos...@hotmail.com wrote:
> On Wednesday, March 28, 2012 11:25:36 PM UTC+1, Gus Gassmann wrote:
> > I am trying to compare two std::string objects str1 and str2. Both
> > strings are rather long (~70000 characters). The first one is read
> > from a file, the second one is generated by a program. I am trying to
> > establish that the two strings are equal. However, it turns out that
> > the string read in from the file has additional white space in several
> > places. (The white space does not concern me; I will declare the
> > strings equal if the other characters match.)  In order to compare
> > them it seems that I must compress them both.
>
> not really. can't you just skip the spaces?
>
> > What is the best way to
> > do that? Do I have to copy each std::string to a char*, or is there a
> > better way?
>
> you know you can index std::string?

Ah. No.

In the end I did solve the problem by skipping the spaces, as follows:

std::string resultFileContent; //this is the string read in from the
file
//the string generated by the program is eclass.errmsg
int i,j;
bool ok;

i = 0;
j = 0;
ok = true;

for (;;)
{
    if (i >= resultFileContent.size() || j >= eclass.errormsg.size() )
break;
    for (;;)
    {
        if (resultFileContent[i] != '\n' && resultFileContent[i] !=
'\r' &&
            resultFileContent[i] != '\t' && resultFileContent[i] != '
' ) break;
        if (i >= resultFileContent.size() ) break;
        i++;
    }
    for (;;)
    {
        if (eclass.errormsg[j] != '\n' && eclass.errormsg[j] != '\r'
&&
            eclass.errormsg[j] != '\t' && eclass.errormsg[j] != ' ' )
break;
        if (j >= eclass.errormsg.size() ) break;
        j++;
    }

    ok &= (resultFileContent[i] == eclass.errormsg[j]);
    if (!ok) break;
    i++;
    j++;
}

if (ok)
{
// the two strings are equal (up to whitespace)
}
else
{
// the two strings are not equal
}

This seemed to work. (At least it declared my test case "ok".) Since
the strings are so long, I am concerned a little bit about efficiency.
Can the above be improved?

[toc] | [prev] | [next] | [standalone]


#15165

From"AnonMail2005@gmail.com" <anonmail2005@gmail.com>
Date2012-03-29 10:33 -0700
Message-ID<a6ac58a4-0659-401d-8371-d2f97db01254@eb6g2000vbb.googlegroups.com>
In reply to#15161
On Mar 29, 6:18 am, Gus Gassmann <horand.gassm...@googlemail.com>
wrote:
> On Mar 29, 4:46 am, nick_keighley_nos...@hotmail.com wrote:
>
>
>
>
>
> > On Wednesday, March 28, 2012 11:25:36 PM UTC+1, Gus Gassmann wrote:
> > > I am trying to compare two std::string objects str1 and str2. Both
> > > strings are rather long (~70000 characters). The first one is read
> > > from a file, the second one is generated by a program. I am trying to
> > > establish that the two strings are equal. However, it turns out that
> > > the string read in from the file has additional white space in several
> > > places. (The white space does not concern me; I will declare the
> > > strings equal if the other characters match.)  In order to compare
> > > them it seems that I must compress them both.
>
> > not really. can't you just skip the spaces?
>
> > > What is the best way to
> > > do that? Do I have to copy each std::string to a char*, or is there a
> > > better way?
>
> > you know you can index std::string?
>
> Ah. No.
>
> In the end I did solve the problem by skipping the spaces, as follows:
>
> std::string resultFileContent; //this is the string read in from the
> file
> //the string generated by the program is eclass.errmsg
> int i,j;
> bool ok;
>
> i = 0;
> j = 0;
> ok = true;
>
> for (;;)
> {
>     if (i >= resultFileContent.size() || j >= eclass.errormsg.size() )
> break;
>     for (;;)
>     {
>         if (resultFileContent[i] != '\n' && resultFileContent[i] !=
> '\r' &&
>             resultFileContent[i] != '\t' && resultFileContent[i] != '
> ' ) break;
>         if (i >= resultFileContent.size() ) break;
>         i++;
>     }
>     for (;;)
>     {
>         if (eclass.errormsg[j] != '\n' && eclass.errormsg[j] != '\r'
> &&
>             eclass.errormsg[j] != '\t' && eclass.errormsg[j] != ' ' )
> break;
>         if (j >= eclass.errormsg.size() ) break;
>         j++;
>     }
>
>     ok &= (resultFileContent[i] == eclass.errormsg[j]);
>     if (!ok) break;
>     i++;
>     j++;
>
> }
>
> if (ok)
> {
> // the two strings are equal (up to whitespace)}
>
> else
> {
> // the two strings are not equal
>
> }
>
> This seemed to work. (At least it declared my test case "ok".) Since
> the strings are so long, I am concerned a little bit about efficiency.
> Can the above be improved?- Hide quoted text -
>
> - Show quoted text -

I would try the std::string member function find_next_not_of to find
the next non-whitespace character - it may be faster.

Also, I would avoid calling the size() functions in the loop.  Save
the sizes into variables and just use them since the sizes remain
constant.  Those function calls may or may not be inlined or otherwise
optimized.

HTH

[toc] | [prev] | [next] | [standalone]


#15261

FromTimothy Madden <terminatorul@gmail.com>
Date2012-04-09 13:02 -0700
Message-ID<15ts562puiebg$.b46i80ta6kd7$.dlg@40tude.net>
In reply to#15161
On Thu, 29 Mar 2012 03:18:40 -0700 (PDT), Gus Gassmann wrote:

> On Mar 29, 4:46 am, nick_keighley_nos...@hotmail.com wrote:
>> On Wednesday, March 28, 2012 11:25:36 PM UTC+1, Gus Gassmann wrote:
>>> I am trying to compare two std::string objects str1 and str2. Both
>>> strings are rather long (~70000 characters). The first one is read
>>> from a file, the second one is generated by a program. I am trying to
>>> establish that the two strings are equal. However, it turns out that
>>> the string read in from the file has additional white space in several
>>> places. (The white space does not concern me; I will declare the
>>> strings equal if the other characters match.)  In order to compare
>>> them it seems that I must compress them both.
>>
>> not really. can't you just skip the spaces?
>>
>>> What is the best way to
>>> do that? Do I have to copy each std::string to a char*, or is there a
>>> better way?
>>
>> you know you can index std::string?
> 
> Ah. No.
> 
> In the end I did solve the problem by skipping the spaces, as follows:
> 
> std::string resultFileContent; //this is the string read in from the
> file
> //the string generated by the program is eclass.errmsg
> int i,j;
> bool ok;
> 
> i = 0;
> j = 0;
> ok = true;
> 
> for (;;)
> {
>     if (i >= resultFileContent.size() || j >= eclass.errormsg.size() )
> break;
>     for (;;)
>     {
>         if (resultFileContent[i] != '\n' && resultFileContent[i] !=
> '\r' &&
>             resultFileContent[i] != '\t' && resultFileContent[i] != '
> ' ) break;
>         if (i >= resultFileContent.size() ) break;
>         i++;
>     }
>     for (;;)
>     {
>         if (eclass.errormsg[j] != '\n' && eclass.errormsg[j] != '\r'
> &&
>             eclass.errormsg[j] != '\t' && eclass.errormsg[j] != ' ' )
> break;
>         if (j >= eclass.errormsg.size() ) break;
>         j++;
>     }
> 
>     ok &= (resultFileContent[i] == eclass.errormsg[j]);
>     if (!ok) break;
>     i++;
>     j++;
> }
> 
> if (ok)
> {
> // the two strings are equal (up to whitespace)
> }
> else
> {
> // the two strings are not equal
> }
> 
> This seemed to work. (At least it declared my test case "ok".) Since
> the strings are so long, I am concerned a little bit about efficiency.
> Can the above be improved?

You should use std::string::const_iterator to create an iterator adaptor
that upon increment will incremtent the string::const_iterator until a
non-whitespace character is encountered (or the end of the sequence).

Or you could just increment them like this explicitly in-line in a loop.

Timothy Madden

[toc] | [prev] | [next] | [standalone]


#15162

Fromnick_keighley_nospam@hotmail.com
Date2012-03-29 00:46 -0700
Message-ID<9416468.2253.1333007212926.JavaMail.geo-discussion-forums@ynmb12>
In reply to#15158
On Wednesday, March 28, 2012 11:25:36 PM UTC+1, Gus Gassmann wrote:

> I am trying to compare two std::string objects str1 and str2. Both
> strings are rather long (~70000 characters). The first one is read
> from a file, the second one is generated by a program. I am trying to
> establish that the two strings are equal. However, it turns out that
> the string read in from the file has additional white space in several
> places. (The white space does not concern me; I will declare the
> strings equal if the other characters match.)  In order to compare
> them it seems that I must compress them both.

not really. can't you just skip the spaces?

> What is the best way to
> do that? Do I have to copy each std::string to a char*, or is there a
> better way?

you know you can index std::string?

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c++


csiph-web