Merge pull request #3 from wangzheng0822/master

update
This commit is contained in:
Qiyuan Jiao 2019-03-17 19:59:13 +08:00 committed by GitHub
commit 8ba56f1652
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 901 additions and 44 deletions

View File

@ -1,4 +1,5 @@
# 数据结构和算法必知必会的50个代码实现 # 数据结构和算法必知必会的50个代码实现
## (关注“小争哥”公众号,获取我的更多技术、非技术分享)
## 数组 ## 数组
* 实现一个支持动态扩容的数组 * 实现一个支持动态扩容的数组

View File

@ -11,7 +11,7 @@
void dlist_init(stDlistHead *dlist) void dlist_init(stDlistHead *dlist) //链表初始化
{ {
dlist->size = 0; dlist->size = 0;
dlist->head = NULL; dlist->head = NULL;
@ -19,7 +19,7 @@ void dlist_init(stDlistHead *dlist)
return; return;
} }
void dlist_destory(stDlistHead *dlist) void dlist_destory(stDlistHead *dlist) //删除链表
{ {
stDlistNode *pNode = NULL; stDlistNode *pNode = NULL;
@ -36,11 +36,11 @@ void dlist_destory(stDlistHead *dlist)
return; return;
} }
int dlist_insert_head(stDlistHead *dlist,stDlistNode *pNode,int data) int dlist_insert_head(stDlistHead *dlist,stDlistNode *pNode,int data) //插入头结点,操作的链表,操作的节点,数据
{ {
if(pNode == NULL) if(pNode == NULL) //当只传递一个数据时
{ {
pNode = (stDlistNode *)malloc(sizeof(stDlistNode)); pNode = (stDlistNode *)malloc(sizeof(stDlistNode)); //新建节点为节点分配空间malloc可能需要#include<malloc.h>
if (pNode == NULL) if (pNode == NULL)
{ {
return -1; return -1;
@ -51,23 +51,23 @@ int dlist_insert_head(stDlistHead *dlist,stDlistNode *pNode,int data)
pNode->prev = NULL; pNode->prev = NULL;
pNode->next = NULL; pNode->next = NULL;
if (dlist->size == 0) if (dlist->size == 0) //如果链表长度为0即链表当前无节点
{ {
dlist->head = pNode; dlist->head = pNode;
dlist->tail = pNode; dlist->tail = pNode;
} }
else else //如果链表已有节点,则令新插入节点为头节点
{ {
pNode->next = dlist->head; pNode->next = dlist->head;
dlist->head->prev = pNode; dlist->head->prev = pNode;
dlist->head = pNode; dlist->head = pNode;
} }
dlist->size++; dlist->size++; //每成功调用一次,链表长度+1
return 0; return 0;
} }
stDlistNode * dlist_remove_tail(stDlistHead *dlist) stDlistNode * dlist_remove_tail(stDlistHead *dlist) //删除尾部节点,并返回删除节点
{ {
stDlistNode *pNode = NULL; stDlistNode *pNode = NULL;
@ -91,7 +91,7 @@ stDlistNode * dlist_remove_tail(stDlistHead *dlist)
return pNode; return pNode;
} }
void dlist_remove_node(stDlistHead * dlist,stDlistNode *pNode) void dlist_remove_node(stDlistHead * dlist,stDlistNode *pNode) //删除指定节点
{ {
if ((dlist == NULL)||(pNode == NULL)) if ((dlist == NULL)||(pNode == NULL))
{ {
@ -119,12 +119,12 @@ void dlist_remove_node(stDlistHead * dlist,stDlistNode *pNode)
if (dlist->size == 0) if (dlist->size == 0)
{ {
memset(dlist,0,sizeof(stDlistHead)); memset(dlist,0,sizeof(stDlistHead)); //将dlist占用内存块的所有值置为0也就是清空head,tail指针内容
} }
return; return;
} }
stDlistNode * dlist_search(stDlistHead * dlist,int data) stDlistNode * dlist_search(stDlistHead * dlist,int data) //根据值搜索节点,并返回
{ {
stDlistNode *pNode = dlist->head; stDlistNode *pNode = dlist->head;
while(pNode != NULL) while(pNode != NULL)
@ -139,30 +139,30 @@ stDlistNode * dlist_search(stDlistHead * dlist,int data)
return NULL; return NULL;
} }
void dlist_dump(stDlistHead *dlist) void dlist_dump(stDlistHead *dlist) //显示链表中的数据
{ {
int no = 0; int no = 0;
stDlistNode *pNode = dlist->head; stDlistNode *pNode = dlist->head;
while(pNode != NULL) while(pNode != NULL)
{ {
printf("\r\n [%d] = %d",no++,pNode->data); printf("\r\n [%d] = %d",no++,pNode->data);
pNode = pNode->next; pNode = pNode->next; //将pNode的下一个节点赋值给pNode推进循环
} }
return; return;
} }
void Lru_dlist(stDlistHead *dlist,int data) void Lru_dlist(stDlistHead *dlist,int data) //LRU最近最少使用缓存淘汰算法
{ {
stDlistNode *pNode = NULL; stDlistNode *pNode = NULL;
pNode = dlist_search(dlist,data); pNode = dlist_search(dlist,data);
if (pNode != NULL) if (pNode != NULL) //如果在链表中找到这个值,则删除储存这个值的节点,之后吧这个节点放在头部
{ {
dlist_remove_node(dlist,pNode); dlist_remove_node(dlist,pNode);
} }
else if(dlist->size >= 4) else if(dlist->size >= 4) //没在链表中找到且链表长度大于4则从链表中删除尾部节点将新数据放在头部
{ {
pNode = dlist_remove_tail(dlist); pNode = dlist_remove_tail(dlist);

View File

@ -7,17 +7,17 @@
************************************************************************/ ************************************************************************/
#include<stdio.h> #include<stdio.h>
typedef struct DlistNode typedef struct DlistNode //双向链表中每一个节点
{ {
struct DlistNode *prev; struct DlistNode *prev; //节点前项指针
struct DlistNode *next; struct DlistNode *next; //节点后项指针
int data; int data; //数据
}stDlistNode; }stDlistNode;
typedef struct Dlisthead typedef struct Dlisthead //定义链表总体
{ {
int size; int size; //链表长度
stDlistNode *head; stDlistNode *head; //头指针
stDlistNode *tail; stDlistNode *tail; //尾部指针
}stDlistHead; }stDlistHead;

View File

@ -0,0 +1,268 @@
#include <iostream>
using namespace std;
typedef int DataType;
struct tree_node
{
DataType data;
tree_node* left=NULL;
tree_node* right=NULL;
};
class binary_search_tree{
private:
tree_node* root;
int num;
public:
binary_search_tree() :num(0)
{
root = new tree_node;
root->left = NULL;
root->right = NULL;
}
bool find(DataType it,tree_node* root)
{
if (NULL == root)return false;
if (it == root->data) {
return true;
}
else if (it > root->data)
{
return find(it, root->right);
}
else
{
return find(it, root->left);
}
}
bool find_data(DataType it)
{
return find(it, root);
/*
tree_node* p = root;
while (p != NULL)
{
if (it < p->data)p = p->left;
else if (it>p->data)p = p->right;
else return true;
}
return false;
*/
}
void insert_data(DataType it)
{
if (0==num)
{
root->data = it;
num++;
return;
}
tree_node* p = root;
while (p != NULL)
{
if (it < p->data)
{
if (NULL == p->left)
{
p->left = new tree_node;
p->left->data = it;
num++;
return;
}
p = p->left;
}
else
{
if (NULL == p->right)
{
p->right = new tree_node;
p->right->data = it;
num++;
return;
}
p = p->right;
}
}
}
void delet(DataType it)
{
if (NULL == root)return;
tree_node* p = root;
tree_node* pp = NULL;//pp记录的是p的父节点
while (p != NULL&&p->data != it)
{
pp = p;
if (it > p->data)p = p->right;
else
p = p->left;
}
if (p == NULL)return;//没有找到
//删除的节点有两个子节点
if (p->left != NULL&&p->right != NULL)
{
tree_node* minP = p->right;
tree_node* minPP = p;//记录P的父节点
while (minP->left != NULL)//寻找右子树最小节点
{
minPP = minP;
minP = minP->left;
}
p->data = minP->data;//将minP替换到p中
//将p换到叶节点上使用叶节点方法进行删除
p = minP;
pp = minPP;
}
//删除节点是叶节点或者是仅有一个节点
tree_node* child;
if (p->left != NULL) child = p->left;
else if (p->right != NULL) child = p->right;
else child = NULL;
if (NULL == pp) root = child;//删除的是根节点
else if (p == pp->left)pp->left = child;
else pp->right = child;
}
DataType get_max()
{
if (NULL == root)return NULL;
tree_node* tmp=root;
while (tmp->right != NULL)
{
tmp = tmp->right;
}
return tmp->data;
}
DataType get_min()
{
if (NULL == root)return NULL;
tree_node* tmp=root;
while (tmp->left != NULL)
{
tmp = tmp->left;
}
return tmp->data;
}
DataType get_prenode(DataType it)
{
if (NULL == root)return NULL;
if (it == root->data) return NULL;
tree_node* p=root;
tree_node* pp=NULL;
while ((p->data != it)&&(p!=NULL))
{
pp = p;
if (p->data < it)
{
p=p->right;
}
else
{
p = p->left;
}
}
return ((NULL==p)?NULL:pp->data);
}
DataType get_postnode(DataType it)
{
if (NULL == root)return -1;
tree_node* p = root;
while ((p->data != it) && (p != NULL))
{
if (p->data < it)
{
p = p->left;
}
else
{
p = p->right;
}
}
if (NULL == p)
{
return -1;
}
else if (p->left!=NULL)
{
return p->left->data;
}
else if (p->right!=-NULL)
{
return p->right->data;
}
else
{
return NULL;
}
}
void mid_order(tree_node* rt)
{
if (NULL == rt)return;
mid_order(rt->left);
cout << rt->data;
mid_order(rt->right);
}
void order()
{
if (NULL == root)return;
return mid_order(root);
}
int get_high(tree_node* rt)
{
int lhigh = 0;
int rhigh = 0;
if (NULL == rt)return 0;
lhigh = get_high(rt->left);
rhigh = get_high(rt->right);
return ((lhigh > rhigh) ? (lhigh + 1) : (rhigh + 1));
}
int high()
{
if (NULL == root) return 1;
return get_high(root);
}
};
int main()
{
binary_search_tree my_tree;
my_tree.insert_data(5);
my_tree.insert_data(4);
my_tree.insert_data(6);
my_tree.insert_data(10);
my_tree.insert_data(3);
my_tree.insert_data(8);
my_tree.insert_data(1);
if (my_tree.find_data(3))
{
cout << "找到了数字3" << endl;
}
else
{
cout << "没有找到数字3" << endl;
}
my_tree.delet(4);
cout << "Max" << my_tree.get_max() << endl;
cout << "Min" << my_tree.get_min() << endl;
cout << "pre node of 5 is " <<my_tree.get_prenode(5) <<endl;
cout << "post node of 5 is " << my_tree.get_postnode(5) << endl;
my_tree.order();
cout << "high of tree is " << my_tree.high() << endl;
return 0;
}

148
go/20_lru/lru_cache.go Normal file
View File

@ -0,0 +1,148 @@
package lru_cache
const (
hostbit = uint64(^uint(0)) == ^uint64(0)
LENGTH = 100
)
type lruNode struct {
prev *lruNode
next *lruNode
key int // lru key
value int // lru value
hnext *lruNode // 拉链
}
type LRUCache struct {
node []lruNode // hash list
head *lruNode // lru head node
tail *lruNode // lru tail node
capacity int //
used int //
}
func Constructor(capacity int) LRUCache {
return LRUCache{
node: make([]lruNode, LENGTH),
head: nil,
tail: nil,
capacity: capacity,
used: 0,
}
}
func (this *LRUCache) Get(key int) int {
if this.tail == nil {
return -1
}
if tmp := this.searchNode(key); tmp != nil {
this.moveToTail(tmp)
return tmp.value
}
return -1
}
func (this *LRUCache) Put(key int, value int) {
// 1. 首次插入数据
// 2. 插入数据不在 LRU 中
// 3. 插入数据在 LRU 中
// 4. 插入数据不在 LRU 中, 并且 LRU 已满
if tmp := this.searchNode(key); tmp != nil {
tmp.value = value
this.moveToTail(tmp)
return
}
this.addNode(key, value)
if this.used > this.capacity {
this.delNode()
}
}
func (this *LRUCache) addNode(key int, value int) {
newNode := &lruNode{
key: key,
value: value,
}
tmp := &this.node[hash(key)]
newNode.hnext = tmp.hnext
tmp.hnext = newNode
this.used++
if this.tail == nil {
this.tail, this.head = newNode, newNode
return
}
this.tail.next = newNode
newNode.prev = this.tail
this.tail = newNode
}
func (this *LRUCache) delNode() {
if this.head == nil {
return
}
prev := &this.node[hash(this.head.key)]
tmp := prev.hnext
for tmp != nil && tmp.key != this.head.key {
prev = tmp
tmp = tmp.hnext
}
if tmp == nil {
return
}
prev.hnext = tmp.hnext
this.head = this.head.next
this.head.prev = nil
this.used--
}
func (this *LRUCache) searchNode(key int) *lruNode {
if this.tail == nil {
return nil
}
// 查找
tmp := this.node[hash(key)].hnext
for tmp != nil {
if tmp.key == key {
return tmp
}
tmp = tmp.hnext
}
return nil
}
func (this *LRUCache) moveToTail(node *lruNode) {
if this.tail == node {
return
}
if this.head == node {
this.head = node.next
this.head.prev = nil
} else {
node.next.prev = node.prev
node.prev.next = node.next
}
node.next = nil
this.tail.next = node
node.prev = this.tail
this.tail = node
}
func hash(key int) int {
if hostbit {
return (key ^ (key >> 32)) & (LENGTH - 1)
}
return (key ^ (key >> 16)) & (LENGTH - 1)
}

View File

@ -0,0 +1,67 @@
package lru_cache
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func Test_Hostbit(t *testing.T) {
fmt.Println(hostbit)
}
func Test_LRU(t *testing.T) {
lru := Constructor(2)
lru.Put(1, 1)
lru.Put(2, 2)
assert.Equal(t, lru.Get(1), 1) // returns 1
lru.Put(3, 3) // evicts key 2
assert.Equal(t, lru.Get(2), -1) // returns -1 (not found)
lru.Put(4, 4) // evicts key 1
assert.Equal(t, lru.Get(1), -1) // returns -1 (not found)
assert.Equal(t, lru.Get(3), 3) // returns 3
assert.Equal(t, lru.Get(4), 4) // returns 4
}
func Test_LRU_PutGet(t *testing.T) {
lru := Constructor(1)
lru.Put(1, 2)
assert.Equal(t, lru.Get(1), 2) // returns 2
}
func Test_LRU_PutGetPutGetGet(t *testing.T) {
lru := Constructor(1)
lru.Put(2, 1)
assert.Equal(t, lru.Get(2), 1) // returns 1
lru.Put(3, 2)
assert.Equal(t, lru.Get(2), -1) // returns -1
assert.Equal(t, lru.Get(3), 2) // returns 2
}
func Test_LRU_PPGPPG(t *testing.T) {
lru := Constructor(2)
lru.Put(2, 1)
lru.Put(2, 2)
assert.Equal(t, lru.Get(2), 2) // returns 2
lru.Put(1, 4)
lru.Put(4, 1)
assert.Equal(t, lru.Get(2), -1) // returns -1
assert.Equal(t, lru.Get(3), -1) // returns -1
}
func Test_LRU_PPGPPG_2(t *testing.T) {
lru := Constructor(2)
lru.Put(2, 1)
lru.Put(2, 2)
assert.Equal(t, lru.Get(2), 2) // returns 2
lru.Put(1, 1)
lru.Put(4, 1)
assert.Equal(t, lru.Get(2), -1) // returns -1
assert.Equal(t, lru.Get(3), -1) // returns -1
}

View File

@ -0,0 +1,51 @@
package sort;
/**
* @author wangjunwei87
* @since 2019-03-10
*/
public class KthSmallest {
public static int kthSmallest(int[] arr, int k) {
if (arr == null || arr.length < k) {
return -1;
}
int partition = partition(arr, 0, arr.length - 1);
while (partition + 1 != k) {
if (partition + 1 < k) {
partition = partition(arr, partition + 1, arr.length - 1);
} else {
partition = partition(arr, 0, partition - 1);
}
}
return arr[partition];
}
private static int partition(int[] arr, int p, int r) {
int pivot = arr[r];
int i = p;
for (int j = p; j <= r - 1; j++) {
if (arr[j] < pivot) {
swap(arr, i, j);
i++;
}
}
swap(arr, i, r);
return i;
}
private static void swap(int[] arr, int i, int j) {
if (i == j) {
return;
}
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}

View File

@ -0,0 +1,54 @@
function lsDist(str1, str2) {
var n = str1.length;
var m = str2.length;
var memo = new Array(n);
for(let i = 0; i < n; i++) {
memo[i] = new Array(m);
if (str1[i] === str2[0]) {
memo[i][0] = i - 0;
} else if(i === 0) {
memo[i][0] = 1;
} else {
memo[i][0] = memo[i - 1][0] + 1;
}
}
for(let j = 0; j < m; j++) {
if(str1[0] === str2[j]) {
memo[0][j] = j - 0;
} else if(j === 0) {
memo[0][j] = 1;
} else {
memo[0][j] = memo[0][j - 1] + 1;
}
}
for(let i = 1; i < n; i++) {
for(let j = 1; j < m; j++) {
if(str1[i] === str2[j]) {
memo[i][j] = Math.min(memo[i - 1][j] + 1, memo[i][j - 1] + 1, memo[i - 1][j - 1 ]);
} else {
memo[i][j] = Math.min(memo[i - 1][j] + 1, memo[i][j - 1] + 1, memo[i - 1][j - 1 ] + 1);
}
}
}
console.log(memo);
return memo[n - 1][m - 1];
}
var s = "mitcmu";
var t = "mtacnu";
console.log( lsDist(s, t) );
var s = "kitten";
var t = "sitting";
console.log( lsDist(s, t) );
var s = "flaw";
var t = "lawn";
console.log( lsDist(s, t) );

View File

@ -86,7 +86,11 @@ function squareRoot($number)
function getDecimalPlaces($number) function getDecimalPlaces($number)
{ {
$temp = explode('.', $number); $temp = explode('.', $number);
return strlen($temp[1]); if (isset($temp[1])) {
return strlen($temp[1]);
}
return 0;
} }
// 测试二分查找给定值 // 测试二分查找给定值

152
php/24_tree/Tree.php Normal file
View File

@ -0,0 +1,152 @@
<?php
namespace Algo_24;
class Tree
{
/**
* 树的根节点
* @var [type]
*/
public $head = null;
/**
* [__construct description]
* @param TreeNode|null $head [description]
*/
public function __construct($headData = null)
{
if ($headData != null) {
$this->head = new TreeNode($headData);
}
}
/**
* 查找数据
* @param [type] $data [数据]
* @return [type] [description]
*/
public function find($data)
{
if ($this->head == null) {
return null;
}
$node = $this->head;
while ($node != null) {
if ($node->data == $data) {
return $node;
} elseif ($data > $node->data) {
$node = $node->right;
} else {
$node = $node->left;
}
}
return null;
}
/**
* 插入数据
* @param [type] $data [数据]
* @return [type] [description]
*/
public function insert($data)
{
if ($this->head == null) {
$this->head = new TreeNode($data);
return true;
}
$node = $this->head;
while ($node != null) {
if ($data > $node->data) {
if ($node->right == null) {
$node->right = new TreeNode($data);
return true;
}
$node = $node->right;
} else {
if ($node->left == null) {
$node->left = new TreeNode($data);
return true;
}
$node = $node->left;
}
}
}
/**
* 删除节点
* @param [type] $data [节点]
* @return [type] [description]
*/
public function delete($data)
{
// 找到需要删除节点
$node = $this->head;
$pnode = null;
while ($node != null) {
if ($node->data == $data) {
break;
} elseif ($data > $node->data) {
$pnode = $node;
$node = $node->right;
} else {
$pnode = $node;
$node = $node->left;
}
}
if ($node == null) {
return false;
}
// 要删除的节点有两个子节点
// 查找右子树中最小节点
if ($node->left != null && $node->right != null) {
$minPP = $node;
$minP = $node->right;
while ($minP->left != null) {
$minPP = $minP;
$minP = $minP->left;
}
$node->data = $minP->data;
$node = $minP;
// 删除掉右子树中的最小节点
$minPP->left = null;
}
if ($node->left != null) {
$child = $node->left;
} elseif ($node->right != null) {
$child = $node->right;
} else {
$child = null;
}
if ($pnode == null) {
// 删除的是根节点
$node = $child;
} elseif ($pnode->left == $node) {
$pnode->left = $child;
} else {
$pnode->right = $child;
}
}
/**
* 前序遍历
* @return [type] [description]
*/
public function preOrder($node)
{
if ($node == null) {
return ;
}
echo $node->data . '->';
$this->preOrder($node->left);
$this->preOrder($node->right);
}
}

36
php/24_tree/TreeNode.php Normal file
View File

@ -0,0 +1,36 @@
<?php
namespace Algo_24;
class TreeNode
{
/**
* 节点中的数据
* @var [type]
*/
public $data;
/**
* 左节点
* @var [type]
*/
public $left;
/**
* 右节点
* @var [type]
*/
public $right;
/**
* [__construct description]
* @param [type] $data [description]
*/
public function __construct($data = null)
{
$this->data = $data;
$this->left = null;
$this->right = null;
}
}

25
php/24_tree/main.php Normal file
View File

@ -0,0 +1,25 @@
<?php
namespace Algo_24;
require_once '../vendor/autoload.php';
$tree = new Tree();
$tree->insert(20);
$tree->insert(30);
$tree->insert(10);
$tree->insert(21);
$tree->insert(22);
$tree->preOrder($tree->head);
echo PHP_EOL;
var_dump($tree->find(30));
echo PHP_EOL;
$tree->delete(30);
$tree->preOrder($tree->head);
echo PHP_EOL;

View File

@ -8,7 +8,8 @@
"Algo_06\\": "06_linkedlist/", "Algo_06\\": "06_linkedlist/",
"Algo_07\\": "07_linkedlist/", "Algo_07\\": "07_linkedlist/",
"Algo_08\\": "08_stack/", "Algo_08\\": "08_stack/",
"Algo_09\\": "09_queue/" "Algo_09\\": "09_queue/",
"Algo_24\\": "24_tree/"
} }
} }
} }

View File

@ -83,7 +83,7 @@ class SinglyLinkedList:
current = current._next current = current._next
if not current: # node not in the list if not current: # node not in the list
return return
current._next = None current._next = node._next
def delete_by_value(self, value: int): def delete_by_value(self, value: int):
if not self._head or not value: if not self._head or not value:

View File

@ -21,11 +21,7 @@ class ArrayQueue:
return False return False
else: else:
for i in range(0, self._tail - self._head): for i in range(0, self._tail - self._head):
<<<<<<< HEAD
self._data[i] = self._items[i + self._head]
=======
self._items[i] = self._items[i + self._head] self._items[i] = self._items[i + self._head]
>>>>>>> upstream/master
self._tail = self._tail - self._head self._tail = self._tail - self._head
self._head = 0 self._head = 0
@ -38,6 +34,8 @@ class ArrayQueue:
item = self._items[self._head] item = self._items[self._head]
self._head += 1 self._head += 1
return item return item
else:
return None
def __repr__(self) -> str: def __repr__(self) -> str:
return " ".join(item for item in self._items[self._head : self._tail]) return " ".join(item for item in self._items[self._head : self._tail])

View File

@ -0,0 +1,22 @@
"""
Author: dreamkong
"""
from typing import List
def bsearch(nums: List[int], target: int) -> int:
return bsearch_internally(nums, 0, len(nums)-1, target)
def bsearch_internally(nums: List[int], low: int, high: int, target: int) -> int:
if low > high:
return -1
mid = low+int((high-low) >> 2)
if nums[mid] == target:
return mid
elif nums[mid] < target:
return bsearch_internally(nums, mid+1, high, target)
else:
return bsearch_internally(nums, low, mid-1, target)

View File

@ -4,13 +4,29 @@
def levenshtein_dp(s: str, t: str) -> int: def levenshtein_dp(s: str, t: str) -> int:
m, n = len(s), len(t) m, n = len(s), len(t)
table = [[0] * (n + 1) for _ in range(m + 1)] table = [[0] * (n) for _ in range(m)]
table[0] = [j for j in range(m + 1)]
for i in range(m + 1): for i in range(n):
table[i][0] = i if s[0] == t[i]:
for i in range(1, m + 1): table[0][i] = i - 0
for j in range(1, n + 1): elif i != 0:
table[i][j] = min(1 + table[i - 1][j], 1 + table[i][j - 1], int(s[i - 1] != t[j - 1]) + table[i - 1][j - 1]) table[0][i] = table[0][i - 1] + 1
else:
table[0][i] = 1
for i in range(m):
if s[i] == t[0]:
table[i][0] = i - 0
elif i != 0:
table[i][0] = table[i - 1][0] + 1
else:
table[i][0] = 1
for i in range(1, m):
for j in range(1, n):
table[i][j] = min(1 + table[i - 1][j], 1 + table[i][j - 1], int(s[i] != t[j]) + table[i - 1][j - 1])
print(table)
return table[-1][-1] return table[-1][-1]
@ -29,3 +45,15 @@ if __name__ == "__main__":
print(levenshtein_dp(s, t)) print(levenshtein_dp(s, t))
print(common_substring_dp(s, t)) print(common_substring_dp(s, t))
s = "kitten"
t = "sitting"
print(levenshtein_dp(s, t))
print(common_substring_dp(s, t))
s = "flaw"
t = "lawn"
print(levenshtein_dp(s, t))
print(common_substring_dp(s, t))

View File

@ -14,8 +14,10 @@ struct StackBasedOnLinkedList<Element>: Stack {
var size: Int { var size: Int {
var count = 0 var count = 0
while head.next != nil { var cur = head.next
while cur != nil {
count += 1 count += 1
cur = cur?.next
} }
return count return count
} }