Go의Generics로 차분 알고리즘 구현 시도

12120 단어 Goalgorithmdifftech
Go1.18에 Generics를 넣었기 때문에 이전에 쓴 편집 거리(Edit Distance), LCS(Longst Common Subsequence), SES(Shorttest Edit Script)졸작의 diff 실복를 계산할 수 있도록 적용해 봤다.
use generics #3
원래 문자열에만 적용할 수 있습니다 (string)
diff := gonp.New("abc", "abd")
diff.Compose()
ed := diff.Editdistance() // 編集距離 is 2
lcs := diff.Lcs()) // lcs is "ab"
 
ses := diff.Ses()
// ses is []SesElem{
//   {e: 'a', t: Common},
//   {e: 'b', t: Common},
//   {e: 'c', t: Delete},
//   {e: 'd', t: Add},
//   }
이번 변경은 정수의 배열에 적용된다
diff := gonp.New([]int{1,2,3}, []int{1,5,3})
diff.Compose()
ed := diff.Editdistance() // 編集距離 is 2
lcs := diff.Lcs() // lcs is [1,3]

ses := diff.Ses()
// ses is []SesElem{
//        {e: 1, t: Common},
//        {e: 2, t: Delete},
//        {e: 5, t: Add},
//        {e: 3, t: Common},
//        }
문자열의 배열에 적용할 수 있습니다.
a := []string{"abc", "def", "ghi"}
b := []string{"abc", "def", "ihg"}
diff := gonp.New(a, b)
diff.Compose()
ed := diff.Editdistance() // 編集距離 is 2
lcs := diff.Lcs() // lcs is "[abc def]"
 
ses := diff.Ses()
// ses is []SesElem{
//        {e: "abc", t: Common},
//        {e: "def", t: Common},
//        {e: "ghi", t: Delete},
//        {e: "ihg", t: Add},
//        }
또한 문자열에 적용될 때rune의 배열로 전달한다.
diff := gonp.New([]rune("abc"), []rune("abd"))
diff.Compose()
ed := diff.Editdistance() // 編集距離 is 2
lcs := diff.Lcs() // lcs is "ab"
 
ses := diff.Ses()
// ses is []SesElem{
//        {e: 'a', t: Common},
//        {e: 'b', t: Common},
//        {e: 'c', t: Delete},
//        {e: 'd', t: Add},
//        }
TypeConstraints와 대원 구조체의 정의는 이렇다.(Generics 이전 T 섹션을 사용하여 rune 유형으로 고정)
type Elem interface {
        // int32 overlaps rune
        ~rune | ~string | ~byte | ~int | ~int8 | ~int16 | ~int64 | ~float32 | ~float64
}

// SesElem is element of SES
type SesElem[T Elem] struct {
        e T
        t SesType
}

// Diff is context for calculating difference between a and b
type Diff[T Elem] struct {
        a, b           []T
        m, n           int
        ed             int
        lcs            []T
        ses            []SesElem[T]
        reverse        bool
        path           []int
        onlyEd         bool
        pointWithRoute []PointWithRoute
}
그래서 저는 Go가 처음 도입한 Generics를 사용했는데 생각보다 간단하고 사용하기 편했습니다.다른 한편, 나는 더 많은 것을 하고 싶다. (이번 경우 SES를 출력할 때 사용하는 printf 문자열 안의 수식자를 특정한 유형에 따라 사용자 정의하고 방법을 원하는 과부하 기능)뭐, 앞으로를 기대해.

좋은 웹페이지 즐겨찾기