algorithms 0.2.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://travis-ci.org/kanwei/algorithms.png)](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
|
+
|