algorithms 0.2.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/{History.txt → CHANGELOG.markdown} +25 -0
- data/Gemfile +9 -0
- data/Manifest +16 -6
- data/README.markdown +40 -66
- data/Rakefile +16 -25
- data/algorithms.gemspec +14 -24
- data/benchmarks/treemaps.rb +25 -10
- data/ext/algorithms/string/extconf.rb +4 -0
- data/ext/algorithms/string/string.c +68 -0
- data/ext/containers/bst/bst.c +247 -0
- data/ext/containers/bst/extconf.rb +4 -0
- data/ext/containers/deque/deque.c +3 -3
- data/ext/containers/rbtree_map/rbtree.c +43 -18
- data/ext/containers/splaytree_map/splaytree.c +154 -105
- data/lib/algorithms.rb +5 -6
- data/lib/algorithms/sort.rb +130 -0
- data/lib/algorithms/string.rb +9 -0
- data/lib/containers/heap.rb +16 -0
- data/lib/containers/kd_tree.rb +40 -17
- data/lib/containers/trie.rb +1 -1
- data/spec/bst_gc_mark_spec.rb +25 -0
- data/spec/bst_spec.rb +25 -0
- data/spec/deque_gc_mark_spec.rb +1 -1
- data/spec/deque_spec.rb +20 -20
- data/spec/heap_spec.rb +28 -23
- data/spec/kd_expected_out.txt +10000 -0
- data/spec/kd_test_in.txt +10000 -0
- data/spec/kd_tree_spec.rb +31 -1
- data/spec/{rb_tree_map_gc_mark_spec.rb → map_gc_mark_spec.rb} +10 -6
- data/spec/priority_queue_spec.rb +20 -20
- data/spec/queue_spec.rb +10 -10
- data/spec/rb_tree_map_spec.rb +25 -25
- data/spec/search_spec.rb +9 -9
- data/spec/sort_spec.rb +6 -5
- data/spec/splay_tree_map_spec.rb +21 -17
- data/spec/stack_spec.rb +10 -10
- data/spec/string_spec.rb +15 -0
- data/spec/suffix_array_spec.rb +17 -17
- data/spec/trie_spec.rb +16 -16
- metadata +49 -62
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7cee1c06e078dc124212a3462d765d26ce5fbe16dd6b31ca6392388d8f51644c
|
4
|
+
data.tar.gz: 491e3540ee5567752d208bb7b8502d1ee998b55e9664c66b5cf5fc17394e10e7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a4a533a2053ae799f87df22b51ff93744e8128e0982239f3d6717bfb6f8ee8817d9c6ebffd6b4a2b478694a3f2f742fc4465eba242e5d2d0d23bfc0c881c1daa
|
7
|
+
data.tar.gz: 4ffaed30fc92fca18dd258102a702f8fceb1a77594ac6b086c627e1a3ab8ae1ad6650295acd0fb423a6ce441b6b7ab686bb56ae9ff937448d031f319d937a427
|
@@ -1,3 +1,28 @@
|
|
1
|
+
=== January 22, 2013
|
2
|
+
|
3
|
+
* JRuby support
|
4
|
+
|
5
|
+
=== April 15, 2012
|
6
|
+
|
7
|
+
* Use long instead of int for string methods
|
8
|
+
* Use VALUE instead of int for comparison vars
|
9
|
+
* Now compiles without warnings (OS X 10.7)
|
10
|
+
|
11
|
+
=== April 19, 2012
|
12
|
+
|
13
|
+
* Pulled in fix for ruby 1.9 compilation error (sorry!!)
|
14
|
+
* Fix specs that broke with new rspec
|
15
|
+
* Migration to rubygems.org
|
16
|
+
* 0.4.0 release
|
17
|
+
|
18
|
+
=== Jan 3, 2009
|
19
|
+
|
20
|
+
* Levenshtein distance in C
|
21
|
+
|
22
|
+
=== April 3, 2009
|
23
|
+
|
24
|
+
* Finished C refactorization of SplayTree
|
25
|
+
|
1
26
|
=== March 28, 2009
|
2
27
|
|
3
28
|
* Implemented SplayTree in C
|
data/Gemfile
ADDED
data/Manifest
CHANGED
@@ -1,17 +1,25 @@
|
|
1
|
+
CHANGELOG.markdown
|
2
|
+
Manifest
|
3
|
+
README.markdown
|
4
|
+
Rakefile
|
1
5
|
algorithms.gemspec
|
2
6
|
benchmarks/deque.rb
|
3
7
|
benchmarks/sorts.rb
|
4
8
|
benchmarks/treemaps.rb
|
9
|
+
ext/algorithms/string/extconf.rb
|
10
|
+
ext/algorithms/string/string.c
|
11
|
+
ext/containers/bst/bst.c
|
12
|
+
ext/containers/bst/extconf.rb
|
5
13
|
ext/containers/deque/deque.c
|
6
14
|
ext/containers/deque/extconf.rb
|
7
15
|
ext/containers/rbtree_map/extconf.rb
|
8
16
|
ext/containers/rbtree_map/rbtree.c
|
9
17
|
ext/containers/splaytree_map/extconf.rb
|
10
18
|
ext/containers/splaytree_map/splaytree.c
|
11
|
-
|
19
|
+
lib/algorithms.rb
|
12
20
|
lib/algorithms/search.rb
|
13
21
|
lib/algorithms/sort.rb
|
14
|
-
lib/algorithms.rb
|
22
|
+
lib/algorithms/string.rb
|
15
23
|
lib/containers/deque.rb
|
16
24
|
lib/containers/heap.rb
|
17
25
|
lib/containers/kd_tree.rb
|
@@ -22,20 +30,22 @@ lib/containers/splay_tree_map.rb
|
|
22
30
|
lib/containers/stack.rb
|
23
31
|
lib/containers/suffix_array.rb
|
24
32
|
lib/containers/trie.rb
|
25
|
-
|
26
|
-
|
27
|
-
README.markdown
|
33
|
+
spec/bst_gc_mark_spec.rb
|
34
|
+
spec/bst_spec.rb
|
28
35
|
spec/deque_gc_mark_spec.rb
|
29
36
|
spec/deque_spec.rb
|
30
37
|
spec/heap_spec.rb
|
38
|
+
spec/kd_expected_out.txt
|
39
|
+
spec/kd_test_in.txt
|
31
40
|
spec/kd_tree_spec.rb
|
41
|
+
spec/map_gc_mark_spec.rb
|
32
42
|
spec/priority_queue_spec.rb
|
33
43
|
spec/queue_spec.rb
|
34
|
-
spec/rb_tree_map_gc_mark_spec.rb
|
35
44
|
spec/rb_tree_map_spec.rb
|
36
45
|
spec/search_spec.rb
|
37
46
|
spec/sort_spec.rb
|
38
47
|
spec/splay_tree_map_spec.rb
|
39
48
|
spec/stack_spec.rb
|
49
|
+
spec/string_spec.rb
|
40
50
|
spec/suffix_array_spec.rb
|
41
51
|
spec/trie_spec.rb
|
data/README.markdown
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
# algorithms
|
1
|
+
# algorithms [](https://travis-ci.org/kanwei/algorithms)
|
2
2
|
|
3
|
-
|
4
|
-
* Documentation: [http://algorithms.rubyforge.org/](http://algorithms.rubyforge.org/)
|
3
|
+
[API Documentation](http://kanwei.github.io/algorithms/)
|
5
4
|
|
6
5
|
## DESCRIPTION:
|
7
6
|
|
@@ -9,7 +8,9 @@ Started as a [Google Summer of Code 2008](http://code.google.com/soc/2008/ruby/a
|
|
9
8
|
|
10
9
|
Written by [Kanwei Li](http://kanwei.com/), mentored by Austin Ziegler
|
11
10
|
|
12
|
-
Original Proposal:
|
11
|
+
### Original Proposal: ###
|
12
|
+
|
13
|
+
Using the right data structure or algorithm for the situation is an important
|
13
14
|
aspect of programming. In computer science literature, many data structures
|
14
15
|
and algorithms have been researched and extensively documented. However, there
|
15
16
|
is still no standard library in Ruby implementing useful structures and
|
@@ -18,75 +19,48 @@ This project will create such a library with documentation on when to use a
|
|
18
19
|
particular structure/algorithm. It will also come with a benchmark suite to
|
19
20
|
compare performance in different situations.
|
20
21
|
|
21
|
-
##
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
- Mergesort Algorithms::Sort.mergesort
|
22
|
+
## COMPLETED:
|
23
|
+
|
24
|
+
* Heaps Containers::Heap, Containers::MaxHeap, Containers::MinHeap
|
25
|
+
* Priority Queue Containers::PriorityQueue
|
26
|
+
* Deque Containers::Deque, Containers::CDeque (C ext)
|
27
|
+
* Stack Containers::Stack
|
28
|
+
* Queue Containers::Queue
|
29
|
+
* Red-Black Trees Containers::RBTreeMap, Containers::CRBTreeMap (C ext)
|
30
|
+
* Splay Trees Containers::SplayTreeMap, Containers::CSplayTreeMap (C ext)
|
31
|
+
* Tries Containers::Trie
|
32
|
+
* Suffix Array Containers::SuffixArray
|
33
|
+
|
34
|
+
* Search algorithms
|
35
|
+
- Binary Search Algorithms::Search.binary_search
|
36
|
+
- Knuth-Morris-Pratt Algorithms::Search.kmp_search
|
37
|
+
* Sorting algorithms
|
38
|
+
- Bubble sort Algorithms::Sort.bubble_sort
|
39
|
+
- Comb sort Algorithms::Sort.comb_sort
|
40
|
+
- Selection sort Algorithms::Sort.selection_sort
|
41
|
+
- Heapsort Algorithms::Sort.heapsort
|
42
|
+
- Insertion sort Algorithms::Sort.insertion_sort
|
43
|
+
- Shell sort Algorithms::Sort.shell_sort
|
44
|
+
- Quicksort Algorithms::Sort.quicksort
|
45
|
+
- Mergesort Algorithms::Sort.mergesort
|
46
|
+
- Dual-Pivot Quicksort Algorithms::Sort.dualpivotquicksort
|
47
47
|
|
48
48
|
## SYNOPSIS:
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
max_heap = Containers::MaxHeap.new
|
54
|
-
|
55
|
-
# To not have to type "Containers::" before each class, use:
|
56
|
-
include Containers
|
57
|
-
max_heap = MaxHeap.new
|
58
|
-
|
50
|
+
require 'rubygems'
|
51
|
+
require 'algorithms'
|
59
52
|
|
60
|
-
|
53
|
+
max_heap = Containers::MaxHeap.new
|
61
54
|
|
62
|
-
|
63
|
-
|
55
|
+
# To not have to type "Containers::" before each class, use:
|
56
|
+
include Containers
|
57
|
+
max_heap = MaxHeap.new
|
64
58
|
|
65
|
-
##
|
59
|
+
## REQUIREMENTS:
|
66
60
|
|
67
|
-
*
|
61
|
+
* Ruby 1.8, Ruby 1.9, JRuby
|
62
|
+
* C extensions (optional, but very much recommended for vast performance benefits)
|
68
63
|
|
69
64
|
## LICENSE:
|
70
65
|
|
71
|
-
(
|
72
|
-
|
73
|
-
Algorithms and Containers project is Copyright (c) 2009 Kanwei Li
|
74
|
-
|
75
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
76
|
-
a copy of this software and associated documentation files (the
|
77
|
-
'Software'), to deal in the Software without restriction, including
|
78
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
79
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
80
|
-
permit persons to whom the Software is furnished to do so, subject to
|
81
|
-
the following conditions:
|
82
|
-
|
83
|
-
The above copyright notice and this permission notice shall be
|
84
|
-
included in all copies or substantial portions of the Software.
|
85
|
-
|
86
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
87
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
88
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
89
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
90
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
91
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
92
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
66
|
+
See [LICENSE.md](LICENSE.md).
|
data/Rakefile
CHANGED
@@ -1,31 +1,22 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require '
|
3
|
-
|
4
|
-
|
5
|
-
p.author = 'Kanwei Li'
|
6
|
-
p.email = 'kanwei@gmail.com'
|
7
|
-
p.summary = 'A library of algorithms and containers.'
|
8
|
-
p.url = 'http://rubyforge.org/projects/algorithms/'
|
9
|
-
p.version = "0.2.0"
|
10
|
-
p.runtime_dependencies = []
|
11
|
-
end
|
12
|
-
|
13
|
-
task :default => :spec
|
2
|
+
require 'rake/extensiontask'
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
require 'bundler/gem_tasks'
|
14
5
|
|
15
|
-
|
16
|
-
|
17
|
-
|
6
|
+
Rake::ExtensionTask.new('algorithms/string') { |ext| ext.name = "CString" }
|
7
|
+
Rake::ExtensionTask.new('containers/deque') { |ext| ext.name = "CDeque" }
|
8
|
+
Rake::ExtensionTask.new('containers/bst') { |ext| ext.name = "CBst" }
|
9
|
+
Rake::ExtensionTask.new('containers/rbtree_map') { |ext| ext.name = "CRBTreeMap" }
|
10
|
+
Rake::ExtensionTask.new('containers/splaytree_map') { |ext| ext.name = "CSplayTreeMap" }
|
18
11
|
|
19
|
-
|
20
|
-
sh "git push" # Rubyforge
|
21
|
-
sh "git push --tags" # Rubyforge
|
22
|
-
sh "git push gh" # Github
|
23
|
-
sh "git push gh --tags" # Github
|
24
|
-
end
|
12
|
+
RSpec::Core::RakeTask.new
|
25
13
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
14
|
+
if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
|
15
|
+
task :default => [:spec]
|
16
|
+
else
|
17
|
+
task :default => [:compile, :spec]
|
30
18
|
end
|
31
19
|
|
20
|
+
task :rdoc do
|
21
|
+
`rdoc -f hanna --main algorithms.rb -t "Ruby Algorithms and Containers Documentation"`
|
22
|
+
end
|
data/algorithms.gemspec
CHANGED
@@ -1,32 +1,22 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
|
-
s.name =
|
5
|
-
s.version = "0.
|
4
|
+
s.name = "algorithms"
|
5
|
+
s.version = "1.0.0"
|
6
6
|
|
7
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
7
|
s.authors = ["Kanwei Li"]
|
9
|
-
s.
|
10
|
-
s.
|
11
|
-
s.
|
12
|
-
s.
|
13
|
-
s.
|
14
|
-
|
15
|
-
|
16
|
-
s.homepage = %q{http://rubyforge.org/projects/algorithms/}
|
17
|
-
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Algorithms", "--main", "README.markdown"]
|
18
|
-
s.require_paths = ["lib", "ext"]
|
19
|
-
s.rubyforge_project = %q{algorithms}
|
20
|
-
s.rubygems_version = %q{1.3.1}
|
21
|
-
s.summary = %q{A library of algorithms and containers.}
|
22
|
-
|
23
|
-
if s.respond_to? :specification_version then
|
24
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
25
|
-
s.specification_version = 2
|
26
|
-
|
27
|
-
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
28
|
-
else
|
29
|
-
end
|
8
|
+
s.email = "kanwei@gmail.com"
|
9
|
+
s.license = 'MIT'
|
10
|
+
s.date = "2021-04-04"
|
11
|
+
s.summary = "Useful algorithms and data structures for Ruby. Optional C extensions."
|
12
|
+
s.description = "Heap, Priority Queue, Deque, Stack, Queue, Red-Black Trees, Splay Trees, sorting algorithms, and more"
|
13
|
+
if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
|
14
|
+
s.platform = "java"
|
30
15
|
else
|
16
|
+
s.extensions = ["ext/algorithms/string/extconf.rb", "ext/containers/bst/extconf.rb", "ext/containers/deque/extconf.rb", "ext/containers/rbtree_map/extconf.rb", "ext/containers/splaytree_map/extconf.rb"]
|
31
17
|
end
|
18
|
+
s.files = ["Gemfile", "CHANGELOG.markdown", "Manifest", "README.markdown", "Rakefile", "algorithms.gemspec", "benchmarks/deque.rb", "benchmarks/sorts.rb", "benchmarks/treemaps.rb", "ext/algorithms/string/extconf.rb", "ext/algorithms/string/string.c", "ext/containers/bst/bst.c", "ext/containers/bst/extconf.rb", "ext/containers/deque/deque.c", "ext/containers/deque/extconf.rb", "ext/containers/rbtree_map/extconf.rb", "ext/containers/rbtree_map/rbtree.c", "ext/containers/splaytree_map/extconf.rb", "ext/containers/splaytree_map/splaytree.c", "lib/algorithms.rb", "lib/algorithms/search.rb", "lib/algorithms/sort.rb", "lib/algorithms/string.rb", "lib/containers/deque.rb", "lib/containers/heap.rb", "lib/containers/kd_tree.rb", "lib/containers/priority_queue.rb", "lib/containers/queue.rb", "lib/containers/rb_tree_map.rb", "lib/containers/splay_tree_map.rb", "lib/containers/stack.rb", "lib/containers/suffix_array.rb", "lib/containers/trie.rb", "spec/bst_gc_mark_spec.rb", "spec/bst_spec.rb", "spec/deque_gc_mark_spec.rb", "spec/deque_spec.rb", "spec/heap_spec.rb", "spec/kd_expected_out.txt", "spec/kd_test_in.txt", "spec/kd_tree_spec.rb", "spec/map_gc_mark_spec.rb", "spec/priority_queue_spec.rb", "spec/queue_spec.rb", "spec/rb_tree_map_spec.rb", "spec/search_spec.rb", "spec/sort_spec.rb", "spec/splay_tree_map_spec.rb", "spec/stack_spec.rb", "spec/string_spec.rb", "spec/suffix_array_spec.rb", "spec/trie_spec.rb"]
|
19
|
+
s.homepage = "https://github.com/kanwei/algorithms"
|
20
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Algorithms", "--main", "README.markdown"]
|
21
|
+
s.require_paths = ["lib", "ext"]
|
32
22
|
end
|
data/benchmarks/treemaps.rb
CHANGED
@@ -1,20 +1,19 @@
|
|
1
1
|
$: << File.join(File.expand_path(File.dirname(__FILE__)), '../lib')
|
2
2
|
require 'algorithms'
|
3
|
-
include
|
3
|
+
include Containers
|
4
4
|
|
5
5
|
require 'rubygems'
|
6
6
|
require 'rbench'
|
7
7
|
|
8
|
-
RBench.run(
|
8
|
+
RBench.run(2) do
|
9
9
|
trees = %w(hash rbtree splaytree)
|
10
10
|
trees.each { |tree| self.send(:column, tree.intern) }
|
11
11
|
|
12
|
-
rbtree =
|
13
|
-
splaytree =
|
12
|
+
rbtree = RBTreeMap.new
|
13
|
+
splaytree = SplayTreeMap.new
|
14
14
|
hash = Hash.new
|
15
15
|
|
16
|
-
random_array = Array.new(
|
17
|
-
num = 1000
|
16
|
+
random_array = Array.new(300000) { |i| rand(i) }
|
18
17
|
|
19
18
|
report "Insertion" do
|
20
19
|
rbtree { random_array.each_with_index { |x,index| rbtree[index] = x } }
|
@@ -22,15 +21,31 @@ RBench.run(10) do
|
|
22
21
|
hash { random_array.each_with_index { |x,index| hash[index] = x } }
|
23
22
|
end
|
24
23
|
|
25
|
-
report "has_key?" do
|
26
|
-
rbtree {
|
27
|
-
splaytree {
|
28
|
-
hash {
|
24
|
+
report "has_key? (linear order)" do
|
25
|
+
rbtree { random_array.each { |n| rbtree.has_key?(n) } }
|
26
|
+
splaytree { random_array.each { |n| splaytree.has_key?(n) } }
|
27
|
+
hash { random_array.each { |n| hash.has_key?(n) } }
|
29
28
|
end
|
30
29
|
|
31
30
|
report "Lookup in sorted order" do
|
32
31
|
rbtree { rbtree.each { |k, v| k } }
|
33
32
|
splaytree { splaytree.each { |k, v| k } }
|
34
33
|
hash { hash.sort.each { |k, v| k } }
|
34
|
+
|
35
|
+
# a1, a2, a3 = [], [], []
|
36
|
+
# rbtree.each { |k, v| a1 << k }
|
37
|
+
# splaytree.each { |k, v| a2 << k }
|
38
|
+
# hash.sort.each { |k, v| a3 << k }
|
39
|
+
#
|
40
|
+
# puts "Lookup correct" if a1 == a2 && a1 == a3
|
35
41
|
end
|
42
|
+
|
43
|
+
report "Random lookups in a smaller subset" do
|
44
|
+
select_subset = random_array[0..random_array.size/20] # 5%
|
45
|
+
size = select_subset.size
|
46
|
+
rbtree { 10000.times { rbtree[ select_subset[rand(size)] ] } }
|
47
|
+
splaytree { 10000.times { splaytree[ select_subset[rand(size)] ] } }
|
48
|
+
hash { 10000.times { hash[ select_subset[rand(size)] ] } }
|
49
|
+
end
|
50
|
+
|
36
51
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
|
3
|
+
long min_three(long a, long b, long c) {
|
4
|
+
long min = a;
|
5
|
+
if (b < min)
|
6
|
+
min = b;
|
7
|
+
if( c < min)
|
8
|
+
min = c;
|
9
|
+
return min;
|
10
|
+
}
|
11
|
+
|
12
|
+
long levenshtein_distance(VALUE str1, VALUE str2) {
|
13
|
+
long i, j, s1_len, s2_len, *d;
|
14
|
+
char * s = RSTRING_PTR(str1);
|
15
|
+
char * t = RSTRING_PTR(str2);
|
16
|
+
s1_len = RSTRING_LEN(str1);
|
17
|
+
s2_len = RSTRING_LEN(str2);
|
18
|
+
|
19
|
+
if (s1_len == 0) {
|
20
|
+
return s2_len;
|
21
|
+
} else if (s2_len == 0) {
|
22
|
+
return s1_len;
|
23
|
+
}
|
24
|
+
|
25
|
+
// We need one extra col and row for the matrix for starting values
|
26
|
+
s1_len++;
|
27
|
+
s2_len++;
|
28
|
+
|
29
|
+
d = xmalloc(sizeof(typeof(d)) * s1_len * s2_len);
|
30
|
+
|
31
|
+
for (i = 0; i < s1_len; i++) {
|
32
|
+
d[i] = i; // d[i, 0] = i
|
33
|
+
}
|
34
|
+
for (j = 0; j < s2_len; j++) {
|
35
|
+
d[j*s1_len] = j; // d[0, j] = j
|
36
|
+
}
|
37
|
+
|
38
|
+
for (i = 1; i < s1_len; i++) {
|
39
|
+
for (j = 1; j < s2_len; j++) {
|
40
|
+
if (s[i-1] == t[j-1]) {
|
41
|
+
d[j * s1_len + i] = d[(j-1) * s1_len + (i-1)];
|
42
|
+
} else {
|
43
|
+
d[j * s1_len + i] = 1 + min_three(
|
44
|
+
d[j * s1_len + (i-1)],
|
45
|
+
d[(j-1) * s1_len + i],
|
46
|
+
d[(j-1) * s1_len + (i-1)]
|
47
|
+
);
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
i = d[s1_len * s2_len -1];
|
52
|
+
xfree(d);
|
53
|
+
return i;
|
54
|
+
}
|
55
|
+
|
56
|
+
static VALUE lev_dist(VALUE self, VALUE str1, VALUE str2) {
|
57
|
+
return LONG2FIX(levenshtein_distance( str1, str2 ));
|
58
|
+
}
|
59
|
+
|
60
|
+
static VALUE mAlgorithms;
|
61
|
+
static VALUE mString;
|
62
|
+
|
63
|
+
void Init_CString() {
|
64
|
+
mAlgorithms = rb_define_module("Algorithms");
|
65
|
+
mString = rb_define_module_under(mAlgorithms, "String");
|
66
|
+
rb_define_singleton_method(mString, "levenshtein_dist", lev_dist, 2);
|
67
|
+
}
|
68
|
+
|