# I do I eliminate the 2 strlens from this?

1. Jun 17, 2015

### Jamin2112

I have a chunk of code that is like

Code (Text):

if (rt->op) // if rt is of the form rt = gx op hx
{
char * dgdx = deriveFromTree(rt->gx); // g'(x)
char * dhdx = deriveFromTree(rt->hx); // h'(x)
char thisop = *rt->op;
if (thisop == '+' || thisop == '-')
{
//  dfdx = dgdx + thisop + dhdx
long n = strlen(dgdx) + strlen(dhdx) + 2;
dfdx = malloc(sizeof(char) * n); dfdx[n-1]='\0';
dfdx = strcat(dfdx, dgdx);
dfdx = strcat(dfdx, charToString(thisop));
dfdx = strcat(dfdx, dhdx);
}

and I want to do it without the strlen(dgdx) and strlen(dhdx) because they seem redundant considering that the implementation of strcat iterates over all the characters of the string again. How do I redo this overall crappy procedure?

2. Jun 17, 2015

### serp777

So you're trying to just add or subtract two numbers by trying to incorporate the operation into a string, that takes up the appropriate amount of memory as defined by the numbers and the operation, so then you can solve it im guessing? Or whats the end goal of this supposed to be? There are also vastly better, infinitely easier languages to do this in then C.

I suppose you could always rewrite your own strcat function that takes a character (for the operation) and two character pointers to count how many characters are in the string and then use malloc from that result, which would let avoid calling strlen twice and enable you to only have to call modified strcat once making your code much cleaner and more efficient. But does that small amount of efficiency really even matter? Are you writing for a microcontroller or a mega database or something?

3. Jun 17, 2015

### Svein

How about a very short expression to do everything below // ADDITION...? (except the malloc part)

n = sprintf(dfdx, "%s %c %s", dgdx, thisop, dhdx);

4. Jun 17, 2015

### D H

Staff Emeritus
An alternative is to use C++ and std::string rather than C and C-style strings. Then you can just add the strings, using the "+" operator:

Code (C):

std::string dgdx = deriveFromTree(rt.gx); // g'(x)
std::string dhdx = deriveFromTree(rt.hx); // h'(x)
std::string dfdx;
if (rt.op == '+' || rt.op == '-')
{
dfdx = dgdx + rt.op + dhdx;
}

5. Jun 17, 2015

### Jamin2112

The point is to make things harder

6. Jun 17, 2015

### Jamin2112

That greatly helps make my procedure more compact, but I still need a way to know how large to make buffer dfdx.

7. Jun 17, 2015

### Staff: Mentor

There was a long thread recently about the advantages of making code more compact (https://www.physicsforums.com/threads/code-readability-for-higher-level-languages.816168/). The upshot was that there really isn't much advantage in making the source code more compact, especially if it makes the code more opaque to the reader.
I don't see the calls to strlen() being redundant, as you say. You need to know the lengths of the two strings that you are going to concatenate. The fact that strcat copies character-by-character doesn't obviate the need to know how large the buffer for dfdx needs to be.

8. Jun 17, 2015

### D H

Staff Emeritus
There is little point in doing that in professional programming. A major aspect of professional programming is making things easier. From other threads, you are an aspiring C++ programmer. If that's still the case, you should stop thinking like a C programmer, or like a Java programmer. Well-written C++ has zero calls to malloc and free, and very few calls to new and delete.

Given that, ...
Unlike many other languages, C-style strings don't store the length as a separate property. That coupled with the need to allocate storage means there's no way around calling strlen twice for this problem. There is however something you can do since you know the lengths of the strings:
Code (C):

char * dgdx = deriveFromTree(rt->gx); // g'(x)
char * dhdx = deriveFromTree(rt->hx); // h'(x)
char thisop = *rt->op;
std::size_t dgdx_len = std::strlen(dgdx);  // Omit std:: if you are using C.
std::size_t dhdx_len = std::strlen(dhdx);
char *dfdx;
if ((thisop == '+') || (thisop == '-'))
{
dfdx = new char[dgdx_len+1+dhdx_len+1]; // Use malloc instead of new in C.
std::strcpy (dfdx, dgdx);
dfdx[dgdx_len] = thisop;                // There's no need for calling strcat here.
std::strcpy (dfdx+dgdx_len+1, dhdx);    // Nor here.
}
...
delete[] dfdx; // Replace with free if you are using C, but never omit this.
There are some issues with the above. What if thisop is '-' and dhdx is "a+b*x+c*x^2"? You probably want to put parentheses around the embedded dhdx. I'll leave that as an exercise for the OP. You may also want to simplify the resultant expression. That is not an exercise for the OP. It means you need a symbolic mathematics library or a symbolic mathematics tool.

You might want to rethink your use of C/C++ here.

Last edited: Jun 17, 2015
9. Jun 17, 2015

### Svein

If you still want to use C:

Declare a local character array with space for the longest possible string plus some extra headroom: char temp[MAX_OP_SIZE];
Then do what I said above (and introduce the parentheses suggested by D H):
n = sprintf(temp, "(%s) %c (%s)", dgdx, thisop, dhdx);
Then store the result:
dfdx = strdup(temp);
And you want to check for errors:
if (dfdx==NULL)
// Run in circles, scream and shout...

10. Jun 18, 2015

### Jamin2112

Good call. I can't believe I didn't think of that.

I'm handrolling a tool for symbolic differentiation and don't have any plan to simplify. Right now it looks atrocious (http://codepad.org/mRv44sr1), but is close to working. The insertInTree function is what's giving me trouble (I asked a question about it here: http://stackoverflow.com/questions/...algorithm-to-insert-a-node-in-a-function-tree).