开发者

String concatenation C++

开发者 https://www.devze.com 2023-04-03 15:57 出处:网络
Given an arbitrary floating point number, say -0.13, suppose we have an algorithm which calculates a binary string of known length L for this number, one by one, from left to right.

Given an arbitrary floating point number, say -0.13, suppose we have an algorithm which calculates a binary string of known length L for this number, one by one, from left to right.

(I need to do this computation for calculating the Morton Key ordering for particles(co-orindates given) which in turn in used in building octrees. I am creating such binary strings for each o开发者_开发知识库f x,y,z dimensions)

Is it better/efficient to first create a character array of length L, and then convert this array into a string? i.e.

char ch[L];

for(i = 0; i < L; ++i)
{
    // calculation of ch[i]
}

//convert array into string

Or is it better/efficient to start of with a empty string, and then concatenate a new calculated bit into the string on the fly. i.e.

string s = "";

for(i = 0; i < L; ++i)
{
    // calculation of ch[i]
    s = s + string(ch);
}


Why not do both?

std::string myStr(L);

for(i = 0; i < L; ++i)
{
    // calculation of ch[i]
    myStr[i] = ch;
}

This creates a std::string with a given size. You then just set each character. This will only work if you can know the size beforehand exactly.

Alternatively, if you want something that is safe, even if you have to add more than L characters:

std::string myStr;
myStr.reserve(L);

for(i = 0; i < L; ++i)
{
    // calculation of ch[i]
    myStr.push_back(ch);
}

std::string::reserve preallocates the storage, but push_back will allocate more if needs be. If you don't go past L characters, then you will only get the one initial allocation.


Can't you just use a string with a pre-allocated length?

string s(L, '\0');
for(i = 0; i < L; ++i)
{
    // calculation of ch[i]
}


I'm not sure I fully understand the conversion happening, but we have objects for a reason. If you use std::string::reserve() first, the performance should be minuscule, and it's obvious what the intent is.

string s;
s.reserve(L);
for(i = 0; i < L; ++i)
{
    // calculation of ch[i]
    string.push_back(ch);
}

If speed is absolutely necessary, you can instead initialize the string as length L, and bypass length checks:

string s(L,'\0');
for(i = 0; i < L; ++i)
{
    // calculation of ch[i]
    string[i] = ch;
}


Personally, i am probably out of date, but i use

sprintf ( char * str, const char * format, ... );

to create strings from numbers

sprintf ( outString,"%f", floatingPointNumber);


Use the latter, but also call s.reserve(L) before entering the loop. This is almost as efficient as direct array assignment, but still easier to grok.

EDIT: Other answers suggest using push_back(). Vote for them.

Sidebar: I'm not sure what you are computing, but if you just want to generate a string representation of the number, I'd suggest you simply call sprintf(), or insert the number into a std::stringstream.


If you want the C++ way, use ostringstream. This is generally cleaner code, less error-prone, and easier to read:

float f = ... // whatever you set it to
std::ostringstream s;
s << f;
std::string stringifiedfloat = s.str();
// now you have the float in a string.

Alternately, you can use the C way, sprintf. This is generally more error-prone, and harder to read, but faster performance:

float f = ... // whatever you set it to
char* buffer = new char[L];
sprintf(buffer, "%f", f);
// now you have the float in a string.

Or, you could even use boost's lexical_cast. This has better performance than ostringstream, and better readability than sprintf, but it gives you a dependency on boost:

float f = ... // whatever you set it to
std::string stringified = boost::lexical_cast<std::string>(f);
// now you have the float in a string.
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号