Browse Source

[tmp] BROKEN DIFF BACKUP

isundil 9 năm trước cách đây
mục cha
commit
ae47488773

+ 1 - 0
.gitignore

@@ -28,6 +28,7 @@
 *.out
 *.app
 *.swp
+vgcore.*
 
 # CMakeLists
 /CMakeCache.txt

+ 2 - 2
doc/jsonstroll.1

@@ -1,7 +1,7 @@
 .\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.47.3.
-.TH JSONSTROLL "1" "September 2016" "jsonstroll (jsonstroller suite) 1.0RC1 generated on Sep  6 2016" "User Commands"
+.TH JSONSTROLL "1" "September 2016" "jsonstroll (jsonstroller suite) 1.0RC1 generated on Sep 10 2016" "User Commands"
 .SH NAME
-jsonstroll \- manual page for jsonstroll (jsonstroller suite) 1.0RC1 generated on Sep  6 2016
+jsonstroll \- manual page for jsonstroll (jsonstroller suite) 1.0RC1 generated on Sep 10 2016
 .SH SYNOPSIS
 .B jsonstroll
 [\fI\,OPTIONS\/\fR]

+ 2 - 0
include/jsonContainer.hh

@@ -15,6 +15,8 @@ class JSonContainer: public JSonElement, public std::list<JSonElement*>
         JSonContainer(JSonContainer *parent);
         virtual ~JSonContainer();
 
+        virtual float diff(const JSonElement *) const;
+
         /**
          * Get the first item of this container
         **/

+ 1 - 1
include/jsonElement.hh

@@ -22,7 +22,7 @@ class JSonElement
         **/
         virtual std::string stringify() const =0;
 
-        virtual float diff(const JSonElement &) const;
+        virtual float diff(const JSonElement *) const;
 
         /**
          * get the number of col string will output

+ 113 - 3
include/levenshtein.hh

@@ -1,8 +1,118 @@
 #pragma once
 
 #include <string>
+#include <list>
+#include <limits.h>
+#include "jsonElement.hh"
 
-unsigned int levenshtein(const char *a, const size_t lenA, const char *b, const size_t lenB);
-unsigned int levenshtein(const std::string &a, const std::string &b);
-float levenshteinPercent(const std::string &strA, const std::string &strB);
+#include <iostream>
+
+float levenshteinPercent(const std::string &a, const std::string &b);
+template<class T> float levenshteinPercent(const std::list<T *> *a, const std::list<T *> *b);
+bool levenshteinCompare(const char &a, const char &b);
+bool levenshteinCompare(const JSonElement *a, const JSonElement *b);
+
+template<typename SIZE, class T, class SUBTYPE>
+static SIZE **_levenshteinMatrice(const T *a, const T *b, const size_t lenA, const size_t lenB)
+{
+    size_t i, j;
+    SIZE **matrice = new SIZE*[lenA +1]();
+
+    matrice[0] = new SIZE[lenB +1]();
+    for (j=0; j <= lenB; j++)
+        matrice[0][j] = j;
+    i = 1;
+    for (SUBTYPE it: *a)
+    {
+        j =1;
+        matrice[i] = new SIZE[lenB +1]();
+        matrice[i][0] = i;
+        for (SUBTYPE jt: *b)
+        {
+            matrice[i][j] = std::min(std::min(
+                    matrice[i -1][j] +1,
+                    matrice[i][j -1] +1),
+                    matrice[i -1][j -1] + ((levenshteinCompare(it, jt) > .9f) ? 0 : 1));
+            j++;
+        }
+        i++;
+    }
+
+    for (size_t i=0; i <= lenA; ++i)
+    {
+        for (size_t j=0; j <= lenB; ++j)
+            std::cerr << (size_t) matrice[i][j] << "\t";
+        std::cerr << std::endl << "[";
+    }
+    return matrice;
+};
+
+template<typename SIZE, class T, class SUBTYPE>
+static SIZE _levenshteinPercent(const T *a, const T *b, const size_t lenA, const size_t lenB)
+{
+    if (lenA == 0) return lenB;
+    if (lenB == 0) return lenA;
+    SIZE **matrice = _levenshteinMatrice<SIZE, T, SUBTYPE>(a, b, lenA, lenB);
+    size_t i;
+    const SIZE result = matrice[lenA][lenB];
+
+    for (i=0; i < lenA; ++i)
+        delete[] matrice[i];
+    delete[] matrice;
+    return 1 - (result / std::max(lenA, lenB));
+};
+
+template<class T> float levenshteinPercent(const std::list<T *> *a, const std::list<T *> *b)
+{
+    const size_t lenA = a->size();
+    const size_t lenB = b->size();
+
+    if (lenA < UCHAR_MAX && lenB < UCHAR_MAX)
+        return _levenshteinPercent<unsigned char, std::list<T *>, T *>(a, b, lenA, lenB);
+    if (lenA < USHRT_MAX && lenB < USHRT_MAX)
+        return _levenshteinPercent<unsigned short, std::list<T *>, T *>(a, b, lenA, lenB);
+    return _levenshteinPercent<unsigned int, std::list<T *>, T *>(a, b, lenA, lenB);
+}
+
+enum ePath: char
+{
+    add = '+',
+    rem = '-',
+    mod = '!',
+    equ = '='
+};
+
+template<typename SIZE, class T, class SUBTYPE>
+static std::list<ePath> _levenshteinShortestPath(const T *a, const T *b, const size_t lenA, const size_t lenB)
+{
+    std::list<ePath> result(std::max(lenA, lenB));
+
+    if (lenA == 0 || lenB == 0)
+    //TODO create deque<ePath>(std::max(lenA, lenB) populated with '-'
+        ;
+    SIZE **matrice = _levenshteinMatrice<SIZE, T, SUBTYPE>(a, b, lenA, lenB);
+    size_t i;
+
+    //TODO find shortest path
+
+
+    // Clean matrice
+    for (i=0; i < lenA; ++i)
+        delete[] matrice[i];
+    delete[] matrice;
+    return result;
+};
+
+template<class T>
+std::list<ePath> levenshteinShortestPath(const std::list<T*> *a, const std::list<T *> *b)
+{
+    const size_t lenA = a->size();
+    const size_t lenB = b->size();
+
+    if (lenA < UCHAR_MAX && lenB < UCHAR_MAX)
+        return _levenshteinShortestPath<unsigned char, std::list<T *>, T *>(a, b, lenA, lenB);
+    if (lenA < USHRT_MAX && lenB < USHRT_MAX)
+        return _levenshteinShortestPath<unsigned short, std::list<T *>, T *>(a, b, lenA, lenB);
+    return _levenshteinShortestPath<unsigned int, std::list<T *>, T *>(a, b, lenA, lenB);
+}
 

+ 12 - 1
src/curseSplitOutput.cpp

@@ -15,9 +15,11 @@
 #include "jsonArray.hh"
 #include "jsonPrimitive.hh"
 
+#include "levenshtein.hh"
+
 CurseSplitOutput::CurseSplitOutput(const Params &p): CurseOutput(p)
 {
-    init();
+    //init();
 }
 
 CurseSplitOutput::~CurseSplitOutput()
@@ -27,6 +29,14 @@ CurseSplitOutput::~CurseSplitOutput()
 
 void CurseSplitOutput::run(const std::deque<std::string> &inputName, const std::deque<JSonElement*> &roots)
 {
+    const JSonArray *a = (const JSonArray*)roots.at(0);
+    const JSonArray *b = (const JSonArray*)roots.at(1);
+    levenshteinShortestPath<JSonElement>(a, b);
+    return;
+
+
+
+
     nbInputs = inputName.size();
     selectedWin = 0;
     scrollTop.clear();
@@ -34,6 +44,7 @@ void CurseSplitOutput::run(const std::deque<std::string> &inputName, const std::
     select_down.clear();
     selection.clear();
     search_result.clear();
+
     for (short i =0; i < nbInputs; i++)
     {
         this->roots.push_back(roots.at(i));

+ 8 - 0
src/jsonContainer.cpp

@@ -5,6 +5,7 @@
 **/
 
 #include "jsonContainer.hh"
+#include "levenshtein.hh"
 
 JSonContainer::JSonContainer(JSonContainer *p):JSonElement(p)
 { }
@@ -12,3 +13,10 @@ JSonContainer::JSonContainer(JSonContainer *p):JSonElement(p)
 JSonContainer::~JSonContainer()
 { }
 
+float JSonContainer::diff(const JSonElement *other) const
+{
+    if (!dynamic_cast<const JSonContainer *> (other))
+        return 0.f;
+    return levenshteinPercent<JSonElement>(this, (const JSonContainer*)other);
+}
+

+ 3 - 2
src/jsonElement.cpp

@@ -108,8 +108,9 @@ bool JSonElement::match(const SearchPattern &searchPattern) const
     return searchPattern.match(stringify(), this);
 }
 
-float JSonElement::diff(const JSonElement &o) const
+float JSonElement::diff(const JSonElement *o) const
 {
-    return levenshteinPercent(stringify(), o.stringify());
+    // TODO check if o is a container
+    return levenshteinPercent(stringify(), o->stringify());
 }
 

+ 13 - 20
src/levenshtein.cpp

@@ -1,31 +1,24 @@
 #include "levenshtein.hh"
 
-unsigned int levenshtein(const char *a, const size_t lenA, const char *b, const size_t lenB)
+float levenshteinPercent(const std::string &a, const std::string &b)
 {
-    int **matrice = new int*[lenA]();
-    matrice[0] = new int[lenB]();
-    for (size_t j=0; j < lenB; j++)
-        matrice[0][j] = j;
-    for (size_t i=1; i < lenA; ++i)
-    {
-        matrice[i] = new int[lenB]();
-        matrice[i][0] = i;
-        for (size_t j=1; j < lenB; ++j)
-            matrice[i][j] = std::min(std::min(
-                    matrice[i -1][j] +1,
-                    matrice[i][j -1] +1),
-                    matrice[i -1][j -1] + (a[i] == b[j] ? 0 : 1));
-    }
-    return matrice[lenA -1][lenB -1];
+    const size_t lenA = a.size();
+    const size_t lenB = b.size();
+
+    if (lenA < UCHAR_MAX && lenB < UCHAR_MAX)
+        return _levenshteinPercent<unsigned char, std::string, char>(&a, &b, lenA, lenB);
+    if (lenA < USHRT_MAX && lenB < USHRT_MAX)
+        return _levenshteinPercent<unsigned short, std::string, char>(&a, &b, lenA, lenB);
+    return _levenshteinPercent<unsigned int, std::string, char>(&a, &b, lenA, lenB);
 }
 
-unsigned int levenshtein(const std::string &strA, const std::string &strB)
+bool levenshteinCompare(const char &a, const char &b)
 {
-    return levenshtein(strA.c_str(), strA.size(), strB.c_str(), strB.size());
+    return a == b;
 }
 
-float levenshteinPercent(const std::string &strA, const std::string &strB)
+bool levenshteinCompare(const JSonElement *a, const JSonElement *b)
 {
-    return 1 - (levenshtein(strA, strB) / std::max(strA.size(), strB.size()));
+    return a->diff(b) > .7f;
 }
 

+ 2 - 0
test/src/levenshtein_test.cpp

@@ -8,6 +8,7 @@ bool doTest()
     float pc;
     unsigned int lev;
 
+    /*
     if ((lev = levenshtein("coucou", "coucou")) != 0)
         FAILED(lev, "!=", 0);
     if ((pc = levenshteinPercent("coucou", "coucou")) != 1)
@@ -22,6 +23,7 @@ bool doTest()
         FAILED(lev, "!=", 1);
     if ((lev = levenshtein("a", "zabcdkfghijk")) != 11)
         FAILED(lev, "!=", 11);
+    */
     return true;
 }