3

Is there a faster/ more efficient way to split a char array into chunks (say 21 chars/ array) other than looping over the whole array?

This is my attempt right now

const char* arr = line.c_str();
char smallArr[(int)ceil((double)strlen(arr)/(double)21)][21];
int arrSisze[(int)ceil((double)strlen(arr)/(double)21)][1];
int m=0;int n=0;
for (int i=0; i<strlen(arr); i++) {
    smallArr[m][i]=arr[i];
    arrSisze[m][0]=(i+1)-n;
    if ((i-n)==19) {
        m++;
        n+=20;
    }
}
2
  • 1
    Why double is even involved at all? This indicates some very low-quality code. Not to mention the dupe call to strlen()... And no, you can't have array operations better than O(n), you have to walk through the array. Also, you forget to NUL-terminate the substrings. And don't reinvent the wheel, use the standard library instead of rolling your own strcpy(). Commented Jun 16, 2013 at 6:48
  • @H2CO3 Whilst I agree it was probably a mistake, recording the sizes of the strings could indicate he didn't need NUL-terminated strings. Commented Jun 16, 2013 at 6:58

3 Answers 3

3

1) Using memcpy

char myname[] = "hello";
char dest[20] = {0};    
/* using memcpy to copy string: */
 memcpy ( dest, myname, 5);

2) using strncpy

char str1[]= "To be or not to be";
char str2[40];

strncpy ( str2, str1, sizeof(str2) );
Sign up to request clarification or add additional context in comments.

Comments

3

Yes, pointer arithmetic and memcpy. However, seeing as you're using C++, let's stick to std::strings and assume they do a memcpy for us.

std::vector<std::string> output;
output.reserve(line.length() / 21 + (line.length() % 21) ? 1 : 0);

auto i = line.begin(), j = i + 21;
for(; line.end() - j > 21; i = j, j+= 21)
{
    output.emplace(i, j)
}

if(j != line.end())
{
    output.emplace(j, line.end());
}

So, what is going on here? For our purpose, it is good enough to think of a std::string as a char array and a length variable.

First, we reserve enough space for our output. You did this too.

Next, we define 2 variables i and j. i represents the beginning of the current substring and j the one-past-the-end iterator. Iterators here can be thought of as pointers into the internal structure of the string's char array - they may even be char*s!

We then iterate over the original string a line at a time. emplace just constructs a new element of a vector in the correct place. The call is equivalent to output.push_back(std::string(i, j)) and is only available in C++11.

To finish, we check whether there is another whole chunk using line.end() - j > 21; line.end() is the one-past-the-end iterator for the char array - it points at the NUL character (if there is one). If there is not a whole chunk, we check for a partial chunk using j != line.end().

1 Comment

He may not be familiar with iterators - you may want to explain what's going on here.
0

Don't re-optimize the standard library.

  • If you have a std::string, just use it.
  • Don't use floating point for integer calculations: just use integer arthmetic porperly
  • the problem complexity is O(1). No other solution will cover it with less of one string walk span, and related copies
  • Use C++ properly, and forget C.

=

std::vector<std::string> chunks;
chunks.resize(21);
size_t chunksize = line.size()/21+1;
for(size_t i=0,j=0; i<line.size(); i+=chunksize, ++j)
{  chunks[j] = line.substr(i,chunksize); }

Note that sting::size takes N^0, while strlen takes N^1 complexity (it has a loop inside).

In this code, my loop is 21^1 on chunks and substr is (N/21)^1 each chunk content, giving N^1 on the whole length.

There is no need to track string length and null terminate the strings. All is handled by std::string class.

3 Comments

-1 all your big-Os are off; it should read, for example, "std::string::size is O(1), while strlen is O(N), where N is the length of the string itself`. Furthermore, your algorithm doesn't do what the OP asked for.
Duh! I was meaning N^0, N^1 etc. but I didn't find a way to represent it. Big O is just an incidentally similar notation. Being confusingm better to change it properly.
...About the algorithm: the request is "split a line into smaller chunks". It has not necessarily to be the same as the OP attempt.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.