calculate value between two strings

J

John Green

Hi,

I would like to calculate the value between two strings. For example:
abc-aaa would be 29.

I tried:
printf("abc-aaa = %d\n","abc"-"aaa");
but I get -4.

How can I do what I want?

Thanks,
 
I

Ian Collins

Hi,

I would like to calculate the value between two strings. For example:
abc-aaa would be 29.

I tried:
printf("abc-aaa = %d\n","abc"-"aaa");
but I get -4.

So the address of "abc" is 4 less than the address of "aaa", which isn't
surprising.
How can I do what I want?

What do you want?
 
E

Eric Sosman

Hi,

I would like to calculate the value between two strings. For example:
abc-aaa would be 29.

Did you mean 28? I'm going to assume that you want to treat
each string as a base-26 number with digits a=0,...,z=25; if that's
not your intent, please explain it more fully.
I tried:
printf("abc-aaa = %d\n","abc"-"aaa");
but I get -4.

You might have gotten almost anything, including herpes.
How can I do what I want?

A couple of ways, depending on what you already know about the
strings (e.g., will they always be of the same length, are they known
to be free of strange characters like '#', do you treat 'A' and 'a'
as equivalent, and so on). Here are a few sketches:

1) If the strings will always be of the same length, you could
march across them from left to right, comparing corresponding
characters. You'd find 'a'-'a' == 0, so you'd set delta=0.
At the next position you'd have 'b'-'a' == 1, and you'd set
delta = delta * 26 + 1 == 1. In the third position you'd get
'c'-'a' == 2, delta = delta * 26 + 2 == 28. Since the strings
are now exhausted, that's your final answer.

2) Method (1) has a flaw, because it assumes 'b'-'a' == 'c'-'b'
== ... == 'z'-'y' == 1. This is a very common scheme for
encoding letter values, but it is not universal. You could
salvage the method by looking up each character in a separate
string "abcdefghijklmnopqrstuvwxyz" and subtracting their
positions rather than their code values. The strchr() function
could be your friend here, and there are other possibilities too.

3) If the strings are of unequal length, you could pretend that the
shorter had a prefix of "aaa...aaa" to extend it to the length
of the longer. In this case it might be easier to work from
right to left and accumulate delta a little differently.

4) A sneaky possibility: The strtol() function can be made to
treat the string as a base-36 number, with a=10,...,z=35. You
could convert each string to a number this way, subtract them,
and then fiddle with the answer to correct the 36-vs-26 bias.
This approach treats 'A' and 'a' as the same.

5) All the above methods assume that the strings are not "too long."
If they get long enough so that their values or differences
exceed the capacity of your machine's numbers, you'll need to get
more imaginative. For most machines strings of up to length 6
will be all right, while longer strings may encounter trouble.
With very little effort you could push the upper limit to 13, but
beyond that you'd have a good deal more work to do.

However, I have a sneaking suspicion that your current level of
expertise in C might not be adequate for any of these approaches. This
is not a slight on your character (there's no shame in starting to learn
something new to you), but I really, really think you should spend some
more time with your C textbook before you try to go much further.
 
K

Keith Thompson

John Green said:
I would like to calculate the value between two strings. For example:
abc-aaa would be 29.

I tried:
printf("abc-aaa = %d\n","abc"-"aaa");
but I get -4.

How can I do what I want?

Start by clearly defining what you want.

C defines the difference between two numbers (it's simple
subtraction, though with some odd characteristics when you consider
overflow and/or unsigned types). It also defines the difference
between two pointer values (which is what your program happens
to be doing, but in a way that's several kinds of incorrect).
And you can subtract an integer from a pointer value, yielding a
new pointer value, but that's not what you want either.

You've shown us an example, "abc-aaa would be 29", which has led
some posters to speculate on what you might mean (which leads to a
result of 28, not 29). But that's only a guess. Another perfectly
plausible meaning, given the arguments "abc" and "aaa", would be
to treat both strings as hexadecimal representations, yielding 18
in this case.

Or, since you said "the value between two strings" rather than
"the difference between two strings", and string values can be
meaningfully ordered by strcmp(), the result could be anything from
"aab" to "abb", or even "aaazzzzzzzzzzzzzql" for that matter.

There is no obvious meaning for "the value between two strings",
and a single example isn't enough to specify one. It's up to you
to define (preferably not just by example) exactly what you mean.
Not only does it make it a lot easier for us to help you, it goes
a long way towards writing a solution in C. If you can write a
good English description of what you want to compute, you may be
able to translate that description into C.

Recommended reading:
http://www.catb.org/~esr/faqs/smart-questions.html
 
E

Eyegor

Start by clearly defining what you want.

C defines the difference between two numbers (it's simple
subtraction, though with some odd characteristics when you consider
overflow and/or unsigned types).  It also defines the difference
between two pointer values (which is what your program happens
to be doing, but in a way that's several kinds of incorrect).
And you can subtract an integer from a pointer value, yielding a
new pointer value, but that's not what you want either.

You've shown us an example, "abc-aaa would be 29", which has led
some posters to speculate on what you might mean (which leads to a
result of 28, not 29).  But that's only a guess.  Another perfectly
plausible meaning, given the arguments "abc" and "aaa", would be
to treat both strings as hexadecimal representations, yielding 18
in this case.

Or, since you said "the value between two strings" rather than
"the difference between two strings", and string values can be
meaningfully ordered by strcmp(), the result could be anything from
"aab" to "abb", or even "aaazzzzzzzzzzzzzql" for that matter.

There is no obvious meaning for "the value between two strings",
and a single example isn't enough to specify one.  It's up to you
to define (preferably not just by example) exactly what you mean.
Not only does it make it a lot easier for us to help you, it goes
a long way towards writing a solution in C.  If you can write a
good English description of what you want to compute, you may be
able to translate that description into C.

Recommended reading:http://www.catb.org/~esr/faqs/smart-questions.html

--
Keith Thompson (The_Other_Keith) (e-mail address removed)  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

Assuming your string variables are of the same length SL and your
strings are LSB aligned you can do the flowing:

X=0
for(i=SL; i--; i>0){
X=X+(S1-S2)*26^(SL-i-1);
}
By default your strings are MSB aligned, so you have to create 2
strings, fill them with "nulls" and strcopy the input strings to the
most right section of addresses of the S1 and S2 buffers. SL is the
size in bytes of S1 and S2 Buffers.
 
E

Eyegor

Start by clearly defining what you want.
C defines the difference between two numbers (it's simple
subtraction, though with some odd characteristics when you consider
overflow and/or unsigned types).  It also defines the difference
between two pointer values (which is what your program happens
to be doing, but in a way that's several kinds of incorrect).
And you can subtract an integer from a pointer value, yielding a
new pointer value, but that's not what you want either.
You've shown us an example, "abc-aaa would be 29", which has led
some posters to speculate on what you might mean (which leads to a
result of 28, not 29).  But that's only a guess.  Another perfectly
plausible meaning, given the arguments "abc" and "aaa", would be
to treat both strings as hexadecimal representations, yielding 18
in this case.
Or, since you said "the value between two strings" rather than
"the difference between two strings", and string values can be
meaningfully ordered by strcmp(), the result could be anything from
"aab" to "abb", or even "aaazzzzzzzzzzzzzql" for that matter.
There is no obvious meaning for "the value between two strings",
and a single example isn't enough to specify one.  It's up to you
to define (preferably not just by example) exactly what you mean.
Not only does it make it a lot easier for us to help you, it goes
a long way towards writing a solution in C.  If you can write a
good English description of what you want to compute, you may be
able to translate that description into C.
--
Keith Thompson (The_Other_Keith) (e-mail address removed)  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

Assuming your string variables are of the same length SL and your
strings are LSB aligned you can do the flowing:

X=0
for(i=SL; i--; i>0){
X=X+(S1-S2)*26^(SL-i-1);}

By default your strings are MSB aligned, so you have to create 2
strings, fill them with "nulls" and strcopy the input strings to the
most right section of addresses of the S1 and S2 buffers. SL is the
size in bytes of S1 and S2 Buffers.


I know i used ^ as power, which is a no-no, but i got lazy.
 
K

Keith Thompson

Eyegor said:
John Green said:
I would like to calculate the value between two strings.  For example:
abc-aaa would be 29. [...]
How can I do what I want?

Start by clearly defining what you want.
[...]
Assuming your string variables are of the same length SL and your
strings are LSB aligned you can do the flowing:

X=0
for(i=SL; i--; i>0){
X=X+(S1-S2)*26^(SL-i-1);
}
By default your strings are MSB aligned, so you have to create 2
strings, fill them with "nulls" and strcopy the input strings to the
most right section of addresses of the S1 and S2 buffers. SL is the
size in bytes of S1 and S2 Buffers.


What??

You already acknowledged that "^" is xor, not exponentation. But what's
all this about the strings being "MSB aligned" or "LSB aligned"? As far
as I can tell, it just doesn't make any sense.

Given:
char s[] = "abc";
s[0] == 'a', s[1] == 'b', s[2] == 'c', and s[3] == '\0'. There's
no alignment to consider.
 
B

Ben Bacarisse

Keith Thompson said:
Eyegor said:
I would like to calculate the value between two strings.  For example:
abc-aaa would be 29. [...]
How can I do what I want?

Start by clearly defining what you want.
[...]
Assuming your string variables are of the same length SL and your
strings are LSB aligned you can do the flowing:

X=0
for(i=SL; i--; i>0){
X=X+(S1-S2)*26^(SL-i-1);
}
By default your strings are MSB aligned, so you have to create 2
strings, fill them with "nulls" and strcopy the input strings to the
most right section of addresses of the S1 and S2 buffers. SL is the
size in bytes of S1 and S2 Buffers.


What??

You already acknowledged that "^" is xor, not exponentation. But what's
all this about the strings being "MSB aligned" or "LSB aligned"? As far
as I can tell, it just doesn't make any sense.


Following Seebs's advice, one might ask what could this notion of
alignment be since it clearly is not C's notion of it. I am pretty sure
that the OP means "lined up" rather than any C-like notion of alignment.

It's not easy to get to this conclusion because that condition is
redundant. Once the OP has said that the string must be the same
length, then their LSBs will "line up". Furthermore, when the OP says
"nulls" he means "whatever character is used to represent zero".
I.e. you must pad the shorter string with 'a's on the left.

The whole thing is a mess. Not only is there a ^ in place of pow(), but
the 'for' loop looks all wrong despite the fact that it works fine with
it's pointless third clause. The alignment condition uses the wrong
words and is redundant. There is no need to create 2 strings (you don't
need any in fact but, as described, the algorithm needs at more one of
them to be copied) and the padding with "nulls" is not right.

Oddly though, despite all that, I understood exactly what the OP meant
on first reading! I suppose that comes from years of looking at
students' programs.

<snip>
 
B

Barry Schwarz

snip


/*-1 for error */
unsigned value(char* a)
{int i;
unsigned tot;

if(a==0) return -1;

value() returns an unsigned. -1 will be converted to UINT_MAX.
for(i=0, tot=0; i>=0 && a; ++i)


i starts at 0. i is incremented but never decremented. Does the test
i>=0 ever evaluate to 0?
{tot+=a;
if((int)tot<0) return -1;


tot is unsigned. It cannot be negative. (int)tot must be
non-negative if the value is between 0 and INT_MAX. If the value
exceeds INT_MAX, it can be negative only if that is the documented
implementation specific behavior. Do you know of any implementations
that do so? Will the test ever portably evaluate to 1?
}
if(i<0) return -1;

When will this test ever evaluate to 1?
return tot;
}

Or was it your intent to teach the OP as many bad ideas as possible?
 
C

Chad

     Did you mean 28?  I'm going to assume that you want to treat
each string as a base-26 number with digits a=0,...,z=25; if that's
not your intent, please explain it more fully.


     You might have gotten almost anything, including herpes.


     A couple of ways, depending on what you already know about the
strings (e.g., will they always be of the same length, are they known
to be free of strange characters like '#', do you treat 'A' and 'a'
as equivalent, and so on).  Here are a few sketches:

    1) If the strings will always be of the same length, you could
       march across them from left to right, comparing corresponding
       characters.  You'd find 'a'-'a' == 0, so you'd set delta=0.
       At the next position you'd have 'b'-'a' == 1, and you'd set
       delta = delta * 26 + 1 == 1.  In the third position you'd get
       'c'-'a' == 2, delta = delta * 26 + 2 == 28.  Since the strings
       are now exhausted, that's your final answer.

     2) Method (1) has a flaw, because it assumes 'b'-'a' == 'c'-'b'
        == ... == 'z'-'y' == 1.  This is a very common scheme for
        encoding letter values, but it is not universal.  You could
        salvage the method by looking up each character in a separate
        string "abcdefghijklmnopqrstuvwxyz" and subtracting their
        positions rather than their code values.  The strchr() function
        could be your friend here, and there are other possibilities too.

     3) If the strings are of unequal length, you could pretend that the
        shorter had a prefix of "aaa...aaa" to extend it to the length
        of the longer.  In this case it might be easier to work from
        right to left and accumulate delta a little differently.

Bear with this. I have enough alcohol in my system right now that if I
would get pulled over for a DUI, the thingy the California cops use to
test how much alcohol is on your breathe would probably be three times
the legal limit. With that, what strategies would you use to attack
case 3?

Uhh... cause like, here is what I came up with so far....

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char calculate(char first[], char second[])
{
char delta = 0;
char difference = 0;

for( ;*first && *second; *first++,*second++) {
difference = *first - *second;
delta = delta * 26 + difference;
}

return delta;
}

int main(void)
{
char first[BUFSIZ];
char second[BUFSIZ];

printf("Enter the first string: ");
scanf("%s", first);
fflush(stdout);
printf("Enter the second string: ");
scanf("%s", second);
fflush(stdout);

printf("The difference between %s - %s is %d\n", first, second, \
calculate(first, second));

return 0;
}
[cdalten@localhost oakland]$ gcc -Wall -Wextra subtractstring.c -o
subtractstring
subtractstring.c: In function ‘calculate’:
subtractstring.c:10: warning: value computed is not used
subtractstring.c:10: warning: value computed is not used
[cdalten@localhost oakland]$ ./subtractstring
Enter the first string: aaa
Enter the second string: aaa
The difference between aaa - aaa is 0
[cdalten@localhost oakland]$ ./subtractstring
Enter the first string: aad
Enter the second string: aaa
The difference between aad - aaa is 3
[cdalten@localhost oakland]$ ./subtractstring
Enter the first string: abc
Enter the second string: aaa
The difference between abc - aaa is 28
[cdalten@localhost oakland]$

Yes, I could have automated the test. But like, ya know, this is
comp.lang.c. And like the standard doesn't cover such things.

Chad
 
B

Ben Bacarisse

Chad said:
On 10/23/2010 4:51 PM, John Green wrote:
     3) If the strings are of unequal length, you could pretend that the
        shorter had a prefix of "aaa...aaa" to extend it to the length
        of the longer.  In this case it might be easier to work from
        right to left and accumulate delta a little differently.

Bear with this. I have enough alcohol in my system right now that if I
would get pulled over for a DUI, the thingy the California cops use to
test how much alcohol is on your breathe would probably be three times
the legal limit.
http://xkcd.com/323/

With that, what strategies would you use to attack
case 3?

Uhh... cause like, here is what I came up with so far....

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char calculate(char first[], char second[])
{
char delta = 0;

This is unlikely to be big enough.
char difference = 0;

for( ;*first && *second; *first++,*second++) {

The *s in the third clause are not doing any good.
difference = *first - *second;
delta = delta * 26 + difference;
}

return delta;
}

But the main point is that the above seems to have nothing much to do
with "case 3" where the strings are of different lengths.

<snip>
 
B

Barry Schwarz

snip
Uhh... cause like, here is what I came up with so far....

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char calculate(char first[], char second[])

Do you really expect the calculated value to fit in a char?
{
char delta = 0;
char difference = 0;

for( ;*first && *second; *first++,*second++) {

*first++ is equivalent to *(first++). What purpose do you think the *
serves?
difference = *first - *second;
delta = delta * 26 + difference;
}

return delta;
}

int main(void)
{
char first[BUFSIZ];
char second[BUFSIZ];

printf("Enter the first string: ");
scanf("%s", first);
fflush(stdout);

This is one statement too late.
 
C

Chad

snip


Uhh... cause like, here is what I came up with so far....
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char calculate(char first[], char second[])

Do you really expect the calculated value to fit in a char?
{
 char delta = 0;
 char difference = 0;
 for( ;*first && *second; *first++,*second++) {

*first++ is equivalent to *(first++).  What purpose do you think the *
serves?

To get what first (and second) is pointing at?

If I redo the for statement as

for( ;*first && *second; first++,second++) {
difference = *first - *second;
delta = delta * 26 + difference;
}

The warnings go away. I tried to think about it. But quite frankly, I
have so much alcohol in my system right now that I have enough issue
typing. I mean, can you only imagine what would happen if I would stop
and think about why the latter construction actually doesn't produce
any warnings?!
   difference = *first - *second;
   delta  = delta * 26 + difference;
 }
 return delta;
}
int main(void)
{
 char first[BUFSIZ];
 char second[BUFSIZ];
 printf("Enter the first string: ");
 scanf("%s", first);
 fflush(stdout);

This is one statement too late.


Does the order matter in this case?

Chad
 
C

Chad

Bear with this. I have enough alcohol in my system right now that if I
would get pulled over for a DUI, the thingy the California cops use to
test how much alcohol is on your breathe would probably be three times
the legal limit.
http://xkcd.com/323/

With that, what strategies would you use to attack
case 3?
Uhh... cause like, here is what I came up with so far....
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char calculate(char first[], char second[])
{
  char delta = 0;

This is unlikely to be big enough.
  char difference = 0;
  for( ;*first && *second; *first++,*second++) {

The *s in the third clause are not doing any good.
    difference = *first - *second;
    delta  = delta * 26 + difference;
  }
  return delta;
}

But the main point is that the above seems to have nothing much to do
with "case 3" where the strings are of different lengths.

I was doing case 1. Then, right as I finished case 1, I realized that
I had no idea on how to attack case 3. So instead, I posted my
attempted solution at case one. Now I would like to point out that I
should get a passing grade since..

a)I was under the influence at the time I wrote this code. Wait, I
still am.
b)I crank this code out in less than 30 minutes. And this was done
without the aid of google.
c)I don't work as a computer programmer for a living.
 
B

Barry Schwarz

snip


Uhh... cause like, here is what I came up with so far....
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char calculate(char first[], char second[])

Do you really expect the calculated value to fit in a char?
{
 char delta = 0;
 char difference = 0;
 for( ;*first && *second; *first++,*second++) {

*first++ is equivalent to *(first++).  What purpose do you think the *
serves?

To get what first (and second) is pointing at?

But you never use the dereferenced value. That is what the diagnostic
from your compiler was trying to tell you. The only useful effect of
these two expressions is the side effect of increasing the pointers.
If I redo the for statement as

for( ;*first && *second; first++,second++) {
difference = *first - *second;
delta = delta * 26 + difference;
}

The warnings go away. I tried to think about it. But quite frankly, I
have so much alcohol in my system right now that I have enough issue
typing. I mean, can you only imagine what would happen if I would stop
and think about why the latter construction actually doesn't produce
any warnings?!

What you are saying is your opinions are irrelevant. This discussion
is for the benefit of the OP who might otherwise be tempted to follow
your example.
   difference = *first - *second;
   delta  = delta * 26 + difference;
 }
 return delta;
}
int main(void)
{
 char first[BUFSIZ];
 char second[BUFSIZ];
 printf("Enter the first string: ");
 scanf("%s", first);
 fflush(stdout);

This is one statement too late.


Does the order matter in this case?

Of course it does. On some systems, your printf output will not be
visible until the fflush executes. On those systems, your user will
not know why the system has stopped.
 
C

Chad

Of course it does.  On some systems, your printf output will not be
visible until the fflush executes.  On those systems, your user will
not know why the system has stopped.

I don't know if the OP is still reading this, but how about something
like the following (for case 1)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void calculate(char *value, char first[], char second[])
{
char difference = 0;
char delta = 0;

for( ;*first && *second; first++,second++) {
difference = *first - *second;
delta = delta * 26 + difference;
}
*value = delta;
}

int main(void)
{
char first[BUFSIZ];
char second[BUFSIZ];
size_t f_len, s_len;
char value;

printf("Enter the first string: ");
fflush(stdout);
if (scanf("%s", first) == 1) {
f_len = strlen(first) + 1;
} else {
fprintf(stderr, "Try again\n");
}

printf("Enter the second string: ");
fflush(stdout);
if (scanf("%s", second) == 1) {
s_len = strlen(second) + 1;
} else {
fprintf(stderr, "Try again\n");
}

if (f_len == s_len) {
calculate(&value, first, second);
printf("The difference between %s - %s is %d\n", first, second,
value);
} else {
fprintf(stderr, "Lengths don't match\n");
}

return 0;
}
 
K

Keith Thompson

Chad said:
Of course it does.  On some systems, your printf output will not be
visible until the fflush executes.  On those systems, your user will
not know why the system has stopped.

I don't know if the OP is still reading this, but how about something
like the following (for case 1)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void calculate(char *value, char first[], char second[])
{
char difference = 0;
char delta = 0;

for( ;*first && *second; first++,second++) {
difference = *first - *second;
delta = delta * 26 + difference;
}
*value = delta;
}

Wouldn't it be more convenient to have the function return the result
rather than assigning it via a pointer parameter?

The OP never bothered to tell us what "difference" means. Actually, he
didn't even use the word "difference"; he said "the value between two
strings".
int main(void)
{
char first[BUFSIZ];
char second[BUFSIZ];

Why would BUFSIZ (the size of the buffer used by the setbuf function)
be a reasonable size for an array used for interactive input? (It's
8192 on my system.)
size_t f_len, s_len;
char value;

printf("Enter the first string: ");
fflush(stdout);
if (scanf("%s", first) == 1) {
f_len = strlen(first) + 1;
} else {
fprintf(stderr, "Try again\n");
}

scanf() with a "%s" format is as dangerous as gets(). It's also odd
to ask for a string, but then read a whitespace-delimited word.
printf("Enter the second string: ");
fflush(stdout);
if (scanf("%s", second) == 1) {
s_len = strlen(second) + 1;
} else {
fprintf(stderr, "Try again\n");
}

if (f_len == s_len) {

The only thing you do with f_len and s_len is compare them here.
You *could* just write
if (strlen(first) == strlen(second) ...

That's not to say that storing the lengths in variables is a bad thing
-- but why did you add 1 to them?
 
C

Chad

I don't know if the OP is still reading this, but how about something
like the following (for case 1)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void calculate(char *value, char first[], char second[])
{
  char difference = 0;
  char delta = 0;
  for( ;*first && *second; first++,second++) {
    difference = *first - *second;
    delta  = delta * 26 + difference;
  }
  *value = delta;
}

Wouldn't it be more convenient to have the function return the result
rather than assigning it via a pointer parameter?

A lot of the engineers at Lawrence Berkeley National Laboratory use
this method. I guess in my case, it's monkey see, monkey do. I don't
know if there is a formal computer science name to this technique or
if this is just some kind of strange Berkeley thing.
The OP never bothered to tell us what "difference" means.  Actually, he
didn't even use the word "difference"; he said "the value between two
strings".
int main(void)
{
  char first[BUFSIZ];
  char second[BUFSIZ];

Why would BUFSIZ (the size of the buffer used by the setbuf function)
be a reasonable size for an array used for interactive input?  (It's
8192 on my system.)

I was drunk at the time at wrote the original code. It was really
hurting to think about anything at the time. So instead of trying to
think about a reasonable buffer size, I just used BUFSIZ.
scanf() with a "%s" format is as dangerous as gets().  It's also odd
to ask for a string, but then read a whitespace-delimited word.

It was the first thing that popped into my head while I was under the
influence. In retrospect, would fgets() have been better?
The only thing you do with f_len and s_len is compare them here.
You *could* just write
    if (strlen(first) == strlen(second) ...

That's not to say that storing the lengths in variables is a bad thing
-- but why did you add 1 to them?

I was starting to do case three[1], but then I quit because my mom was
calling me. When I got back to my computer, I totally lost my mojo to
write code.

[1]Case three is what Eric talked about. And I quote

"3) If the strings are of unequal length, you could pretend that the
shorter had a prefix of "aaa...aaa" to extend it to the length
of the longer. In this case it might be easier to work from
right to left and accumulate delta a little differently. "

Chad
 
B

Ben Bacarisse

Chad said:
Chad said:
Of course it does.  On some systems, your printf output will not be
visible until the fflush executes.  On those systems, your user will
not know why the system has stopped.
I don't know if the OP is still reading this, but how about something
like the following (for case 1)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void calculate(char *value, char first[], char second[])
{
  char difference = 0;
  char delta = 0;
  for( ;*first && *second; first++,second++) {
    difference = *first - *second;
    delta  = delta * 26 + difference;
  }
  *value = delta;
}

You are still returning a char. That unlikely to be able to represent
the result for everything but a few pairs of string.
A lot of the engineers at Lawrence Berkeley National Laboratory use
this method. I guess in my case, it's monkey see, monkey do. I don't
know if there is a formal computer science name to this technique or
if this is just some kind of strange Berkeley thing.

It's worth thinking about Keith's question. Another way to think about
the same thing is this: what *would* make you write a function that
returns the result rather than using a pointer parameter? If the answer
is "nothing", why do programming languages have value-returning
functions at all? If you *can* think of reasons to return a value, why
do they not apply in this case?

If you can't say *why* the good folks at LBL write their programs the
way they do, you can't draw any lessons from their code. Learning by
copying code you don't understand is slow and error prone.

<snip>
 
K

Keith Thompson

Chad said:
void calculate(char *value, char first[], char second[])
{
  char difference = 0;
  char delta = 0;
  for( ;*first && *second; first++,second++) {
    difference = *first - *second;
    delta  = delta * 26 + difference;
  }
  *value = delta;
}

Wouldn't it be more convenient to have the function return the result
rather than assigning it via a pointer parameter?

A lot of the engineers at Lawrence Berkeley National Laboratory use
this method. I guess in my case, it's monkey see, monkey do. I don't
know if there is a formal computer science name to this technique or
if this is just some kind of strange Berkeley thing.

A common style is to have functions return a result that indicates
whether they succeeded or not, which means that the actual result has to
be communicated via a pointer argument. For example, a square root
function in this style might look something like this:

int square_root(double *result, double x) {
if (x < 0.0) {
return BAD_ARGUMENT;
}
else {
*result = sqrt(x);
return OK;
}
}

My guess is that that's what's going on at LBNL, and you've
misunderstood it (it doesn't make much sense for a void function to be
written this way).

[...]
I was drunk at the time at wrote the original code.

Ok, I give up.

If you're not able to write coherent code (or English), you always
have the option of *not writing anything*.

[...]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top