0

(I have simplified my code after reading advice)

I am writing a program to take 2 strings and return the smallest editing distance as int.

eg. str1 = ab, str2 = ab ; //distance will be 0. 
(when both char of str1 and str2 are the same, distance will be 0)

eg. str1 = abc, str2 = c ; distance will be 2.

In my code,I have used below strings.

str1 = editing
str2 = distance

correct answer should be 5 (e, s, i&a, g&c, e), but my program returns 6. I have tried other strings eg, (short & ports) which gives the answer what it is supposed to be.

I have tried to debug, but I do not understand why sometimes those 3 options (ans1, ans2, ans3) in the function "check" give correct outcome, sometimes they dont.

 ans1 is the result when index of str1 +1
 ans2 is the result when index of str2 +1
 ans3 is the result when index of both str1 and str2 +1

I have read my code many times and I cant find what went wrong. please help me to understand my problems.

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

int check(const char* str1, const char* str2, int i, int j, int dp[10][10])
{
  int steps = 0;
  while (str1[i] != '\0' || str2[j] != '\0')
  { //while one side has not reach '\0'
        while (str1[i] != '\0' && str2[j] != '\0')
        { //while both sides has not reach '\0'
            if (dp[i][j] != -1){ return dp[i][j];} //if there is stored answer, return that
             if (str1[i] == str2[j]) 
            { // if both char are the same, both move forward
                i++;
                j++;
            }
            else  //if both char are not the same
            { 
              int ans1 = check(str1, str2, i+1, j, dp);  //ans1 = when str1 move forward
              int ans2 = check(str1, str2, i, j+1, dp);  //ans2 = when str2 move forward
              int ans3 = check(str1, str2, i+1, j+1, dp);//ans3 = when both move forward

                //compare the result below to find the smallest steps(distance)
            
                if (ans1 <= ans2)
                { //ans1 is smaller than ans2
                    if (ans1 <= ans3)
                    { //ans1 is smallest
                        dp[i][j] = ans1 + 1; //store the answer to dp array
                        i++;                        //move forward
                        steps++;                    //steps +1
                    }
                    else //ans3 is smallest
                    { 
                        dp[i][j] = ans3 + 1;
                        i++;
                        j++;
                        steps++;
                    }
                }
                else //ans2 is smaller than ans1
                { 
                    if (ans2 <= ans3)
                    { //ans2 is smallest
                        dp[i][j] = ans2 + 1;
                        j++;
                        steps++;
                    }
                    else //ans3 is smallest
                    { 
                        dp[i][j] = ans3 + 1;
                        i++;
                        j++;
                        steps++;
                    }
                }
            }//else ends here
        }//while loop ends (both sides are not \0) 
        
        //when str1 or str2 reaches the end '\0'
        if (str1[i] != '\0')
        {
            i++;
            steps++;
        }
        else if (str2[j] != '\0')
        {
            j++;
            steps++;
        }
  }//while loop ends(one side is not \0)
    
  //printf("i=%d\nj=%d\nsteps=%d\n", i, j, steps);
  return steps;
  
}//function ends here


int main() {
  char str1[10] = "editing";
  char str2[10] = "distance";
    int min_step[10][10]; //with index [i][j]
  for (int i = 0; i < 10; i++)
    for (int j = 0; j < 10; j++)
      min_step[i][j] = -1; 
  //scanf("%s %s", str1, str2);
  printf("%d\n", check(str1, str2, 0, 0, min_step));
  return 0;
}
keitou777
  • 21
  • 2
  • 2
    I recommend you take some time to scale back your code, and actually kind of start over from scratch. Then before you start any coding, divide the main problem into smaller and simpler problems. Continue to do this division for all sub-problems until no sub-problem can be divided any further. Then you start implementing a solution for each sub-problem, one by one while testing each part before continuing onto the next one. When (if) you find a problem use a *debugger* to step through the code statement by statement to help you figure out when, where and why you have a problem. – Some programmer dude Jan 21 '21 at 16:16
  • 1
    For what it's worth, if you swap the input strngs, you get 5, which shouldn't happen, because `dist(a, b) == dist(b, a)`. I think you don't handle ties for the smallest distance correctly. Prefer `ans1/2`, where you look ahead on one string, over `ans3`, where you look ahead on both strings. That means the innermost `if (ans1/2 < ans3)` should be `if(ans1/2 <= ans3)`. – M Oehm Jan 21 '21 at 16:55
  • @ghilesZ: Isn't that a bit harsh? Code blocks are an easy way to style preformatted data. I don't think they are strictly for code. Anyway, if you are really _disturbed_ by the formatting, why don't you edit the post? – M Oehm Jan 21 '21 at 16:59
  • Thank you everyone for advice! I have simplified my code. now I have found out that if i mute(comment out) line 12 which is the first line in the second while loop, I will get correct answer. But I dont understand why it is screwing up. I still want to use a dp array if string become huge. `if (dp[i][j] != -1){ return dp[i][j];}` – keitou777 Jan 21 '21 at 18:00
  • 1
    When you store your memoized results, you may have made some steps already, so you should say `if (dp[i][j] != -1) return dp[i][j] + steps;`. – M Oehm Jan 21 '21 at 18:43
  • @M Oehm harsh? that certainly was not my intention, i meant it as an advice. Although i'm not sure what part of my comment can be interpreted as being harsh. Also i tried editing the post, bu my edit queue is full, hence the comment instead. – ghilesZ Jan 21 '21 at 18:49
  • @MOehm: i thought `{ return dp[i][j];} ` will only return the value from array back to the caller. Meaning... the function from the outer layer (previous step). and in the outer layer, there should be its own `steps`. Am i understanding it wrong? – keitou777 Jan 21 '21 at 19:49
  • @ghilesZ: Sorry, I just started programming and I am not so familiar with this this platform - stackflow. At first it kept saying there are some "code" in my post, which I have to format them using code style, and it wouldnt allow me to submit. Thats why I tried everything, eg...intended whole code, added all the strange quotations, etc.. – keitou777 Jan 21 '21 at 19:50
  • 1
    Yes, in general that is so. Usually, you check for memoized values first thing, then store the memoized value before returning. But your approach is a kind of hybrid between a loop and recursion. You memoize before returning. And the `i` and `j` for which you memoize are not necessarily the values the function was called with. – M Oehm Jan 21 '21 at 20:49
  • @M Oehm; Thanks! Now i understand much better. – keitou777 Jan 21 '21 at 21:15
  • 1
    That's good. [Here's](https://ideone.com/JKaFEB) a variant of your code without loops. Everything is done recursively. Memoized values are checked on entering the function and are stored on returning. – M Oehm Jan 21 '21 at 21:24

0 Answers0