#include <iostream>
#include <vector>
using namespace std;
class LevenshteinDistance
{
public:
  static int isutf8(const string &c)
  {
    int ret;
    if((c[0]&0x80) == 0x00) ret = 1;
    else if((c[0]&0xe0) == 0xc0 && (c[1]&0xc0) == 0x80) ret = 2;
    else if((c[0]&0xf0) == 0xe0 && (c[1]&0xc0) == 0x80 
                               && (c[2]&0xc0) == 0x80 ) ret = 3;
    return(ret);
  }
  static bool equal(const string &s1, const string &s2)
  {
    bool ret = false;
    if(isutf8(s1)==isutf8(s2))
    {
      int f=0;
      for(int i=0;i<isutf8(s1);++i)
      {
        if(s1[i]==s2[i]) ++f;
      }
      if(f==isutf8(s1)) ret = true;
    }
    return(ret);
  }
  static int edit(const string &px, const string &py)
  {
    int len1=0,len2=0;
    int i,j;
    int result;
    for(unsigned i=0;i<px.size();)
    {
      i += isutf8(&px[i]);
      ++len1;
    }
    for(unsigned i=0;i<py.size();)
    {
      i += isutf8(&py[i]);
      ++len2;
    }
    vector<vector<int> > row(len1+1, vector<int>(len2+1));

    for(i=0;i<len1+1;i++) row[i][0]=i;
    for(i=0;i<len2+1;i++) row[0][i]=i;
    int k=0,l=0;
    for(i=1;i<=len1;++i)
    {
      l = 0;
      for(j=1;j<=len2;++j)
      {
        row[i][j] = min(min(
                      row[i-1][j-1] + (equal(&px[k],&py[l])?0:1) , // replace
                      row[i][j-1] + 1),     // delete
                       row[i-1][j] + 1  );  // insert
        l += isutf8(&py[l]);
      }
      k += isutf8(&px[k]);
    }
    result=row[i-1][j-1];

    return result;
  }
};
int main()
{
  cout<<LevenshteinDistance::edit("あい","あいう")<<endl;
  return(0);
}
