Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Fast way to add null after each char (http://www.velocityreviews.com/forums/t732566-fast-way-to-add-null-after-each-char.html)

Brad 09-05-2010 04:54 PM

Fast way to add null after each char
 
std::string s = "easy";

std::string unicode_string;

std::string::const_iterator it,

for(it = s.begin(); it != s.end(); ++it)
{
unicode_string.push_back(*it);
unicode_string.push_back('\0');
}

The above for loop would make unicode_string look like this:

"e null a null s null y null"

Is there a faster way to do this... in place maybe?

Thanks for any tips,

Brad



Francesco S. Carta 09-05-2010 05:05 PM

Re: Fast way to add null after each char
 
Brad <byte8bits@gmail.com>, on 05/09/2010 09:54:28, wrote:

> std::string s = "easy";
>
> std::string unicode_string;
>
> std::string::const_iterator it,
>
> for(it = s.begin(); it != s.end(); ++it)
> {
> unicode_string.push_back(*it);
> unicode_string.push_back('\0');
> }
>
> The above for loop would make unicode_string look like this:
>
> "e null a null s null y null"


Nay, it will make it look like "e\0a\0s\0y\0"... by the way, why do you
need to do such a thing?

> Is there a faster way to do this... in place maybe?


Faster, I don't know (measure it), in place, yes: use the
std::string::insert() method.

--
FSC - http://userscripts.org/scripts/show/59948
http://fscode.altervista.org - http://sardinias.com

Alf P. Steinbach /Usenet 09-05-2010 05:13 PM

Re: Fast way to add null after each char
 
* Brad, on 05.09.2010 18:54:
> std::string s = "easy";
>
> std::string unicode_string;
>
> std::string::const_iterator it,
>
> for(it = s.begin(); it != s.end(); ++it)
> {
> unicode_string.push_back(*it);
> unicode_string.push_back('\0');
> }
>
> The above for loop would make unicode_string look like this:
>
> "e null a null s null y null"
>
> Is there a faster way to do this... in place maybe?


Depends what you want.

It /seems/ that you're assuming a little-endian architecture, and that the
intent is to treat unicode_string as UTF-16 encoded (via some low level cast),
and that you're assuming that the original character encoding is Latin-1 or a
subset.

That's an awful lot of assumptions.

Look in the standard library for mbcstowcs or something like that, in the C
library, or 'widen'-functions in the C++ library.

Under what seems to be your assumption of Latin-1 encoding of the 'char' string,
and an additional assumption of 16-bit 'wchar_t', you can however do


<code>
#include <iostream>
#include <string>
#include <limits.h>
using namespace std;

#define STATIC_ASSERT( x ) typedef char shouldBeTrue[(x)? 1 : -1]

STATIC_ASSERT( CHAR_BIT == 8 );
STATIC_ASSERT( sizeof( wchar_t ) == 2 );

int main()
{
string const s = "Hello";
wstring const u( s.begin(), s.end() );

wcout << u << L"\n";
}
</code>


But I don't recommend that; use the widening functions, C or C++.


Cheers & hth.,

- Alf

--
blog at <url: http://alfps.wordpress.com>

SG 09-05-2010 05:17 PM

Re: Fast way to add null after each char
 
On 5 Sep., 19:05, "Francesco S. Carta" wrote:
> in place, yes: use the
> std::string::insert() method.


Or better yet, resize() to final size, assign the non-null characters
in a backwards loop and set a couple of chars to zero:

void sillify(string & io)
{
size_t len1 = io.size();
io.resize(len1*2,'\0');
for (size_t k=len1; k-->1;)
io[k*2] = io[k];
for (size_t k=1; k<len1; k+=2)
io[k] = '\0';
}

Cheers!
SG

Francesco S. Carta 09-05-2010 05:27 PM

Re: Fast way to add null after each char
 
SG <s.gesemann@gmail.com>, on 05/09/2010 10:17:37, wrote:

> On 5 Sep., 19:05, "Francesco S. Carta" wrote:
>> in place, yes: use the
>> std::string::insert() method.

>
> Or better yet, resize() to final size, assign the non-null characters
> in a backwards loop and set a couple of chars to zero:
>
> void sillify(string& io)
> {
> size_t len1 = io.size();
> io.resize(len1*2,'\0');
> for (size_t k=len1; k-->1;)
> io[k*2] = io[k];
> for (size_t k=1; k<len1; k+=2)
> io[k] = '\0';
> }


Define "better".

void smartify(string& s) {
for(int i = 1, e = s.size()*2; i < e; i+=2) {
s.insert(i, 1, '\0');
}
}

--
FSC - http://userscripts.org/scripts/show/59948
http://fscode.altervista.org - http://sardinias.com

Marc 09-05-2010 05:54 PM

Re: Fast way to add null after each char
 
On 5 sep, 19:27, "Francesco S. Carta" <entul...@gmail.com> wrote:
> SG <s.gesem...@gmail.com>, on 05/09/2010 10:17:37, wrote:
> > On 5 Sep., 19:05, "Francesco S. Carta" wrote:
> >> in place, yes: use the
> >> std::string::insert() method.

>
> > Or better yet, resize() to final size, assign the non-null characters
> > in a backwards loop and set a couple of chars to zero:

>
> > * * void sillify(string& *io)
> > * * {
> > * * * *size_t len1 = io.size();
> > * * * *io.resize(len1*2,'\0');
> > * * * *for (size_t k=len1; k-->1;)
> > * * * * * io[k*2] = io[k];
> > * * * *for (size_t k=1; k<len1; k+=2)
> > * * * * * io[k] = '\0';
> > * * }

>
> Define "better".
>
> * * *void smartify(string& s) {
> * * * * *for(int i = 1, e = s.size()*2; i < e; i+=2) {
> * * * * * * *s.insert(i, 1, '\0');
> * * * * *}
> * * *}


Faster. SG's code has linear complexity and yours is quadratic.
Readability is something else...

Francesco S. Carta 09-05-2010 06:04 PM

Re: Fast way to add null after each char
 
Marc <marc.glisse@gmail.com>, on 05/09/2010 10:54:46, wrote:

> On 5 sep, 19:27, "Francesco S. Carta"<entul...@gmail.com> wrote:
>> SG<s.gesem...@gmail.com>, on 05/09/2010 10:17:37, wrote:
>>> On 5 Sep., 19:05, "Francesco S. Carta" wrote:
>>>> in place, yes: use the
>>>> std::string::insert() method.

>>
>>> Or better yet, resize() to final size, assign the non-null characters
>>> in a backwards loop and set a couple of chars to zero:

>>
>>> void sillify(string& io)
>>> {
>>> size_t len1 = io.size();
>>> io.resize(len1*2,'\0');
>>> for (size_t k=len1; k-->1;)
>>> io[k*2] = io[k];
>>> for (size_t k=1; k<len1; k+=2)
>>> io[k] = '\0';
>>> }

>>
>> Define "better".
>>
>> void smartify(string& s) {
>> for(int i = 1, e = s.size()*2; i< e; i+=2) {
>> s.insert(i, 1, '\0');
>> }
>> }

>
> Faster. SG's code has linear complexity and yours is quadratic.
> Readability is something else...


Exactly. So neither is better than the other unless we associate
"better" to "more readable" or to "faster" ;-)

--
FSC - http://userscripts.org/scripts/show/59948
http://fscode.altervista.org - http://sardinias.com

Francesco S. Carta 09-05-2010 06:32 PM

Re: Fast way to add null after each char
 
Francesco S. Carta <entuland@gmail.com>, on 05/09/2010 20:04:18, wrote:

> Marc <marc.glisse@gmail.com>, on 05/09/2010 10:54:46, wrote:
>
>> On 5 sep, 19:27, "Francesco S. Carta"<entul...@gmail.com> wrote:
>>> SG<s.gesem...@gmail.com>, on 05/09/2010 10:17:37, wrote:
>>>> On 5 Sep., 19:05, "Francesco S. Carta" wrote:
>>>>> in place, yes: use the
>>>>> std::string::insert() method.
>>>
>>>> Or better yet, resize() to final size, assign the non-null characters
>>>> in a backwards loop and set a couple of chars to zero:
>>>
>>>> void sillify(string& io)
>>>> {
>>>> size_t len1 = io.size();
>>>> io.resize(len1*2,'\0');
>>>> for (size_t k=len1; k-->1;)
>>>> io[k*2] = io[k];
>>>> for (size_t k=1; k<len1; k+=2)
>>>> io[k] = '\0';
>>>> }
>>>
>>> Define "better".
>>>
>>> void smartify(string& s) {
>>> for(int i = 1, e = s.size()*2; i< e; i+=2) {
>>> s.insert(i, 1, '\0');
>>> }
>>> }

>>
>> Faster. SG's code has linear complexity and yours is quadratic.
>> Readability is something else...

>
> Exactly. So neither is better than the other unless we associate
> "better" to "more readable" or to "faster" ;-)
>


Just for the records, a better solution, in my opinion, is to build an
appropriately sized new string and copying the original chars at the
appropriate positions - a compromise between readability and speed,
somewhat:

void foo(string& s) {
string r(s.size()*2, '\0');
for(int i = 0, e = s.size(); i < e; ++i) {
r[i*2] = s[i];
}
s.swap(r);
}

ASSUMING that the OP really wants exactly this - WRT Alf P. Steinbach's
notes in the other post.

--
FSC - http://userscripts.org/scripts/show/59948
http://fscode.altervista.org - http://sardinias.com

SG 09-05-2010 06:53 PM

Re: Fast way to add null after each char
 
On 5 Sep., 20:04, Francesco S. Carta wrote:
> Marc wrote:
> > On 5 sep, 19:27, Francesco S. Carta wrote:
> >> Define "better".

> > Faster. [...]

> Exactly. So neither is better than the other unless we associate
> "better" to "more readable" or to "faster" ;-)


See the original post:

"...Is there a faster way to do this..."

Cheers!
SG

Juha Nieminen 09-05-2010 07:14 PM

Re: Fast way to add null after each char
 
Alf P. Steinbach /Usenet <alf.p.steinbach+usenet@gmail.com> wrote:
> * Brad, on 05.09.2010 18:54:
>> std::string s = "easy";
>>
>> std::string unicode_string;
>>
>> std::string::const_iterator it,
>>
>> for(it = s.begin(); it != s.end(); ++it)
>> {
>> unicode_string.push_back(*it);
>> unicode_string.push_back('\0');
>> }
>>
>> The above for loop would make unicode_string look like this:
>>
>> "e null a null s null y null"
>>
>> Is there a faster way to do this... in place maybe?

>
> Depends what you want.
>
> It /seems/ that you're assuming a little-endian architecture


No, he isn't. He is making the string UTF16LE, not assuming that the
architecture is little-endian.


All times are GMT. The time now is 02:08 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.