diegoaguilar
diegoaguilar

Reputation: 8376

Result value logic in Delphi?

I'm coding this function where if a string differs only by one character, returns the distinct characters position, if they're right the same is supposed to return -1 and -10 in the case they differ by more than 1 character.

Just for giving and example, '010' and '110' or '100' and '110' works good, returning 0 and 1 each...

However, when I try with '100' and '101'or with '110' and '111' I get a result of -1 when it should be 2! I've done the desktop testing and I can't just see the mistake.

function combine (m1, m2 : string) : integer;
var
dash : integer;
distinct : integer;
i : integer;

begin
distinct := 0;
dash := -1;

for i := 0 to Length(m1)-1 do
begin
    if m1[i] <> m2[i] then
    begin
      distinct := distinct+1;
      dash := i;
      if distinct > 1 then
        begin
          result:= -10;
          exit;
        end;
    end;
end;
result := dash;
end;

I'm always getting same length strings, What am I doing wrong?

Upvotes: 1

Views: 183

Answers (1)

David Heffernan
David Heffernan

Reputation: 612784

The main problem is that Delphi strings are 1-based. Your loop needs to run from 1 to Length(m1).

If you enabled range checking in the compiler options, then the compiler would have raised an error at runtime which would have led you to the fault. I cannot stress enough that you should enable range checking. It will lead to the compiler finding errors in your code.

Note also that this means that the returned values will also be 1-based. So an input of '100', '101' will give the result 3 since that is the index of the first difference.

You should also check that m1 and m2 are the same length. If not raise an exception.

Another tip. The idiomatic way to increment a variable by 1 is like so:

inc(distinct);

If you want to increment by a different value write:

inc(distinct, n);

So, I would write the function like this:

function combine(const m1, m2: string): integer;
var
  i: integer;
  dash: integer;
  distinct: integer;
begin
  if Length(m1)<>Length(m2) then begin
    raise EAssertionFailed.Create('m1 and m2 must be the same length');
  end;

  distinct := 0;
  dash := -1;

  for i := 1 to Length(m1) do
  begin
    if m1[i] <> m2[i] then
    begin
      inc(distinct);
      dash := i;
      if distinct > 1 then
      begin
        result := -10;
        exit;
      end;
    end;
  end;
  result := dash;
end;

Upvotes: 4

Related Questions