Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize Levenshtein Distance Computation (Remove Duplicates) #315

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 23 additions & 14 deletions fibonacci/go/code.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
package main

import (
"fmt"
"strconv"
"os"
"fmt"
"os"
"strconv"
)

func fibonacci(n int) int {
if n == 0 { return 0 }
if n == 1 { return 1 }
return fibonacci(n-1) + fibonacci(n-2)
if n < 2 {
return n
}
a, b := 0, 1
for i := 2; i <= n; i++ {
a, b = b, a+b
}
return b
}

func main() {
input, e := strconv.Atoi(os.Args[1])
if e != nil { panic(e) }
u := int(input)
r := 0
for i := 0; i < u; i++ {
r += fibonacci(i)
}
fmt.Println(r)
if len(os.Args) < 2 {
fmt.Println("Uso: go run main.go <numero>")
return
}
u, err := strconv.Atoi(os.Args[1])
if err != nil {
panic(err)
}
result := fibonacci(u+1) - 1

fmt.Println(result)
}
130 changes: 58 additions & 72 deletions levenshtein/go/code.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,91 +5,77 @@ import (
"os"
)

// levenshtein calculates the Levenshtein distance between two strings using Wagner-Fischer algorithm
// Space Complexity: O(min(m,n)) - only uses two rows instead of full matrix
// Time Complexity: O(m*n) where m and n are the lengths of the input strings
func levenshtein(s1, s2 string) int {
// Early termination checks
if s1 == s2 {
return 0
}
if len(s1) == 0 {
return len(s2)
}
if len(s2) == 0 {
return len(s1)
}

// Make s1 the shorter string for space optimization
if len(s1) > len(s2) {
s1, s2 = s2, s1
}
func levenshtein(s1, s2 string) int {
// Early termination
if s1 == s2 {
return 0
}
if len(s1) == 0 {
return len(s2)
}
if len(s2) == 0 {
return len(s1)
}

m, n := len(s1), len(s2)
if len(s1) > len(s2) {
s1, s2 = s2, s1
}

// Use two rows instead of full matrix for space optimization
prevRow := make([]int, m+1)
currRow := make([]int, m+1)
m, n := len(s1), len(s2)

// Initialize first row
for i := 0; i <= m; i++ {
prevRow[i] = i
}
prevRow := make([]int, m+1)
currRow := make([]int, m+1)

// Main computation loop
for j := 1; j <= n; j++ {
currRow[0] = j
for i := 0; i <= m; i++ {
prevRow[i] = i
}

for i := 1; i <= m; i++ {
cost := 1
if s1[i-1] == s2[j-1] {
cost = 0
}

// Find minimum of three operations
deletion := prevRow[i] + 1
insertion := currRow[i-1] + 1
substitution := prevRow[i-1] + cost

currRow[i] = deletion
if insertion < currRow[i] {
currRow[i] = insertion
}
if substitution < currRow[i] {
currRow[i] = substitution
}
}
for j := 1; j <= n; j++ {
currRow[0] = j
for i := 1; i <= m; i++ {
cost := 1
if s1[i-1] == s2[j-1] {
cost = 0
}
del := prevRow[i] + 1 // deletar char de s1
ins := currRow[i-1] + 1 // inserir char em s1
sub := prevRow[i-1] + cost // substituir char

// Swap rows
prevRow, currRow = currRow, prevRow
}
currRow[i] = del
if ins < currRow[i] {
currRow[i] = ins
}
if sub < currRow[i] {
currRow[i] = sub
}
}
prevRow, currRow = currRow, prevRow
}

return prevRow[m]
return prevRow[m]
}

func main() {
args := os.Args[1:]

minD := -1
times := 0
args := os.Args[1:]
if len(args) < 2 {
fmt.Println("Use: go run main.go <string1> <string2> [<string3> ...]")
return
}

if len(args) < 2 {
fmt.Println("Please provide at least two strings as arguments.")
return
}
minD := -1
times := 0

for i := 0; i < len(args); i++ {
for j := 0; j < len(args); j++ {
if i != j {
d := levenshtein(args[i], args[j])
if minD == -1 || d < minD {
minD = d
for i := 0; i < len(args)-1; i++ {
for j := i + 1; j < len(args); j++ {
d := levenshtein(args[i], args[j])
if minD == -1 || d < minD {
minD = d
}
times++
}
times++
}
}
}
}

fmt.Printf("times: %d\n", times)
fmt.Printf("min_distance: %d\n", minD)
fmt.Printf("times: %d\n", times)
fmt.Printf("min_distance: %d\n", minD)
}
34 changes: 19 additions & 15 deletions loops/go/code.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
package main

import (
"fmt"
"math/rand"
"strconv"
"os"
"fmt"
"math/rand"
"os"
"strconv"
)

func main() {
input, e := strconv.Atoi(os.Args[1]) // Get an input number from the command line
if e != nil { panic(e) }
u := int32(input)
r := rand.Int31n(10000) // Get a random number 0 <= r < 10k
var a[10000]int32 // Array of 10k elements initialized to 0
for i := int32(0); i < 10000; i++ { // 10k outer loop iterations
for j := int32(0); j < 100000; j++ { // 100k inner loop iterations, per outer loop iteration
a[i] = a[i] + j%u // Simple sum
input, e := strconv.Atoi(os.Args[1])
if e != nil {
panic(e)
}
u := int32(input)
var soma int32
for j := int32(0); j < 100000; j++ {
soma += j % u
}
r := rand.Int31n(10000)
var a [10000]int32
for i := int32(0); i < 10000; i++ {
a[i] = soma + r
}
a[i] += r // Add a random value to each element in array
}
fmt.Println(a[r]) // Print out a single element from the array
fmt.Println(a[r])
}