算法-转

常见算法是js实现汇总

/*去重*/

<script>

function delRepeat(arr){

var newArray=new Array();

var len=arr.length;

for(var i=0;i<len;i++){

for(var j=i+1;j<len;j++)

{

if(arr[i]==arr[j])

{

++i;

}

}

newArray.push(arr[i]);

}

return newArray;

}

var arr=new Array("red","red","1","5","2");

alert(delRepeat(arr));

</script>

/*二分法*/

又称为折半查找算法,但是有缺陷就是要求数字是预先排序好的

function binary(items,value){

var startIndex=0,

stopIndex=items.length-1,

midlleIndex=(startIndex+stopIndex)>>>1;

while(items[middleIndex]!=value && startIndex<stopIndex){

if(items[middleIndex]>value){

stopIndex=middleIndex-1;

}else{

startIndex=middleIndex+1;

}

middleIndex=(startIndex+stopIndex)>>>1;

}

return items[middleIndex]!=value ? false:true;

}

/*十六进制颜色值的随机生成*/

function randomColor(){

var arrHex=["0","2","3","4","5","6","7","8","9","a","b","c","d"],

strHex="#",

index;

for(var i=0;i<6;i++){

index=Math.round(Math.random()*15);

strHex+=arrHex[index];

}

return strHex;

}

/*一个求字符串长度的方法*/

function GetBytes(str){

var len=str.length,

bytes=len;

for(var i=0;i<len;i++){

if(str.CharCodeAt>255){

bytes++;

}

}

return bytes;

}

/*插入排序*/

所谓的插入排序,就是将序列中的第一个元素看成一个有序的子序列,然后不段向后比较交换比较交换。

---------------------------------华丽丽的分割线-------------------------------------

function insertSort(arr){

var key;

for(var j = 1; j < arr.length ; j++){

//排好序的

var i = j - 1;

key = arr[j];

while(i >= 0 && arr[i] > key){

arr[i + 1] = arr[i];

i --;

}

arr[i + 1] = key;

}

return arr;

}

/*希尔排序*/

希尔排序,也称递减增量排序算法具体描述:http://zh.wikipedia.org/zh/%E5%B8%8C%E5%B0%94%E6%8E%92%E5%BA%8F

其实说到底也是插入排序的变种

function shellSort(array){

var stepArr = [1750, 701, 301, 132, 57, 23, 10, 4, 1]; // reverse()在维基上看到这个最优的步长较小数组

var i = 0;

var stepArrLength = stepArr.length;

var len = array.length;

var len2 =  parseInt(len/2);

for(;i < stepArrLength; i++){

if(stepArr[i] > len2){

continue;

}

stepSort(stepArr[i]);

}

// 排序一个步长

function stepSort(step){

//console.log(step) 使用的步长统计

var i = 0, j = 0, f, tem, key;

var stepLen = len%step > 0 ?  parseInt(len/step) + 1 : len/step;

for(;i < step; i++){// 依次循环列

for(j=1;/*j < stepLen && */step * j + i < len; j++){//依次循环每列的每行

tem = f = step * j + i;

key = array[f];

while((tem-=step) >= 0){// 依次向上查找

if(array[tem] > key){

array[tem+step] = array[tem];

}else{

break;

}

}

array[tem + step ] = key;

}

}

}

return array;

}

/*快速排序*/

其实说到底快速排序算法就系对冒泡排序的一种改进,采用的就是算法理论中的分治递归的思想,说得明白点,它的做法就是:通过一趟排序将待排序的纪录分割成两部分,其中一部分的纪录值比另外一部分的纪录值要小,就可以继续分别对这两部分纪录进行排序;不段的递归实施上面两个操作,从而实现纪录值的排序。

这么说可能不是很清晰,直接上代码:

<script>

function sort(arr){

return quickSort(arr,0,arr.length-1);

function quickSort(arr,l,r){

if(l<r){

var mid=arr[parseInt((l+r)/2)],i=l-1,j=r+1;

while(true){

//大的放到右边,小的放到左边, i与j均为游标

while(arr[++i]<mid);

while(arr[--j]>mid);

if(i>=j)break;//判断条件

var temp = arr[i];

arr[i]=arr[j];

arr[j]=temp;

}

quickSort(arr,l,i-1);

quickSort(arr,j+1,r);

}

return arr;

}

}

function main(){

var list=new Array(49,38,65,97,76,13,27);

document.write(sort(list).valueOf());

}

main();

</script>

原理图:

/*冒泡法*/

function bullSort(array){

var temp;

for(var i=0;i<array.length;i++){

for(var j=array.length-1;j>i;j--){

if(array[j]<array[j-1]){

temp = array[j];

array[j]=array[j-1];

array[j-1]=temp;

}

}

}

return array;

}

/*js递归实现方案*/

递归函数是在一个函数通过调用自身的情况下去解决的:

方式如下:

function factorial(num){

if(num<=1){

return 1;

}else{

return num*factorial(num-1);

}

}

但是这在js里面可能会出现错误:

var anotherFactorial = factorial;

factorial=null;

alert(anoterFactorial(4));

因为在调用anoterFactorial时内部的factorial已经不存在了。

解决方法是通过arguments.callee来解决。

如下:

function factorial(num){

if(num<=1){

return 1;

}else{

return num*arguments.callee(num-1);

}

var anotherFactorial = factorial;

factorial = null;

alert(anotherFactorial(4));

成功!!!!

}

/**js模拟多线程**/

<html><head><title>emu -- 用command模式模拟多线程</title></head><body>

<SCRIPT LANGUAGE="JavaScript">

<!--

if (Array.prototype.shift==null)

Array.prototype.shift = function (){

var rs = this[0];

for (var i=1;i<this.length;i++) this[i-1]=this[i]

this.length=this.length-1

return rs;

}

if (Array.prototype.push==null)

Array.prototype.push = function (){

for (var i=0;i<arguments.length;i++) this[this.length]=arguments[i];

return this.length;

}

var commandList = [];

var nAction = 0;//控制每次运行多少个动作

var functionConstructor = function(){}.constructor;

function executeCommands(){

for (var i=0;i<nAction;i++)

if (commandList.length>0){

var command = commandList.shift();

if (command.constructor == functionConstructor)

if (command.scheduleTime == null || new Date()-command.scheduleTime>0)

command();

else

commandList.push(command);

}

}

function startNewTask(){

var resultTemp = document.getElementById("sampleResult").cloneNode(true);

with (resultTemp){

id="";style.display="block";style.color=(Math.floor(Math.random()* (1<<23)).toString(16)+"00000").substring(0,6);

}

document.body.insertBefore(resultTemp,document.body.lastChild);

commandList.push(function(){simThread(resultTemp,1);});

nAction++;

}

function  simThread(temp,n){

if (temp.stop) n--;

else temp.innerHTML = temp.innerHTML - (-n);

if (n<1000)

commandList.push(function(){simThread(temp,++n)});

else{

var command = function(){document.body.removeChild(temp);;nAction--;};

command.scheduleTime = new Date()-(-2000);

commandList.push(command);

}

}

window.onload = function(){setInterval("executeCommands()",1);}

//-->

</SCRIPT>

<button onClick="startNewTask()">开始新线程</button>

<BR><BR>

<div id=sampleResult onMouseOver="this.stop=true" onMouseOut="this.stop=false" >0</div>

</body>

</html>

/*选择法排序*/

选择法主要有三种:

《1》简单的选择排序:简单的前后交互。

/*简单选择法排序*/

其实基本的思想就是从待排序的数组中选择最小或者最大的,放在起始位置,然后从剩下的数组中选择最小或者最大的排在这公司数的后面。

http://zh.wikipedia.org/wiki/%E9%80%89%E6%8B%A9%E6%8E%92%E5%BA%8F

function selectionSort(data)

{

var i, j, min, temp , count=data.length;

for(i = 0; i < count - 1; i++) {

/* find the minimum */

min = i;

for (j = i+1; j < count; j++)

{    if (data[j] < data[min])

{ min = j;}

}

/* swap data[i] and data[min] */

temp = data[i];

data[i] = data[min];

data[min] = temp;

}

return data;

}

《2》树型排序:又称锦标赛排序,首先对n个元素进行两两比较,然后在其中[n/2]个较小者再进行两两比较如此重复直至选出最小的关键字的纪录为止。(可用完全二差树表示)。缺点:辅助空间需求过大,和“最大值”进行多余比较

《3》堆排序:(不适用于纪录数较少的文件)

堆排序算法的过程如下:

1)得到当前序列的最小(大)的元素

2)把这个元素和最后一个元素进行交换,这样当前的最小(大)的元素就放在了序列的最后,而原先的最后一个元素放到了序列的最前面

3)的交换可能会破坏堆序列的性质(注意此时的序列是除去已经放在最后面的元素),因此需要对序列进行调整,使之满足于上面堆的性质.

重复上面的过程,直到序列调整完毕为止.

js实现:

<script>

/**

* 堆排序

* @param items 数组

* @return 排序后的数组

*/

function heapSort(items)

{

items = array2heap(items); //将数组转化为堆

for(var i = items.length - 1; i >= 0; i--)

{

items = swap(items, 0, i); //将根和位置i的数据交换(用于将最大值放在最后面)

items = moveDown(items, 0, i - 1); //数据交换后恢复堆的属性

}

return items;

}

/**

* 将数组转换为堆

* @param items 数组

* @return 堆

*/

function array2heap(items)

{

for(var i = Math.ceil(items.length / 2) - 1; i >= 0; i--)

{

items = moveDown(items, i, items.length - 1); //转换为堆属性

}

return items;

}

/**

* 转换为堆

* @param items 数组

* @param first 第一个元素

* @param last 最后一个元素

* @return 堆

*/

function moveDown(items, first, last)

{

var largest = 2 * first + 1;

while(largest <= last)

{

if(largest < last && items[largest] < items[largest + 1])

{

largest++;

}

if(items[first] < items[largest])

{

items = swap(items, first, largest); // 交换数据

first = largest;   //往下移

largest = 2 * first + 1;

}

else

{

largest = last + 1; //跳出循环

}

}

return items;

}

/**

* 交换数据

* @param items 数组

* @param index1 索引1

* @param index2 索引2

* @return 数据交换后的数组

*/

function swap(items, index1, index2)

{

var tmp = items[index1];

items[index1] = items[index2];

items[index2] = tmp;

return items;

}

var a = [345,44,6,454,10,154,3,12,11,4,78,9,0,47,88,9453,4,65,1,5];

document.write(heapSort(a));

</script>

所谓归并就是将两个或者两个以上的有序表合成一个新的有序表。

递归形式的算法在形式上较为简洁但实用性较差,与快速排序和堆排序相比,归并排序的最大特点是,它是一种稳定的排序方法。

js实现归并:

<script>

function MemeryArray(Arr,n, Brr, m)

{      var i, j, k;

var Crr=new Array();

i = j = k = 0;

while (i < n && j < m)

{

if (Arr[i] < Brr[j])

Crr[k++] = Arr[i++];

else

Crr[k++] = Brr[j++];

}

while (i < n)

Crr[k++] = Arr[i++];

while (j < m)

Crr[k++] = Brr[j++];

return Crr;

}

var Arr=new Array(45,36,89,75,65);

var Brr=new Array(48,76,59,49,25);

alert(MemeryArray(Arr , Arr.length , Brr , Brr.length));

</script>

归并排序待续,先睡了:

----------------------------------------------华丽丽的分割线-------------------------------------------------------------------------

归并排序:

<script>

//将有二个有序数列a[first...mid]和a[mid...last]合并。

function mergearray(Arr,first,mid,last,tempArr)

{

var i = first, j = mid + 1;

var m = mid,   n = last;

var k = 0;

while (i <= m && j <= n)

{

if (Arr[i] < Arr[j])

tempArr[k++] = Arr[i++];

else

tempArr[k++] = Arr[j++];

}

while (i <= m)

tempArr[k++] = Arr[i++];

while (j <= n)

tempArr[k++] = Arr[j++];

for (i = 0; i < k; i++)

Arr[first + i] = tempArr[i];

}

function mergesort(Arr,first,last)

{

var tempArr=new Array();

if (first < last)

{

var mid = (first + last)>>>1;

mergesort(Arr, first, mid, tempArr);    //左边有序

mergesort(Arr, mid + 1, last, tempArr);  //右边有序

mergearray(Arr, first, mid, last, tempArr);  //再将二个有序数列合并

}

return  Arr;

}

var Arr=new Array(1,65,45,98,56,78);

alert(mergesort(Arr,0,Arr.length-1));

</script>

/*比较两个字符串的相似性-Levenshtein算法简介*/

问题与描述:

近似字符串匹配问题

说明:设给定样本,对于任意文本串,样本P在文本T中的K-近似匹配(K-approximate match)是指P在T中包含最多K个差异的匹配,这里的差别指:

(1)修改:P与T中对应的字符不同
(2)删除:T中含有一个未出现在P中的字符
(3)插入:T中不包含出现在P中的一个字符

(也就是编辑距离问题)

例如: 
T: a p r o x i o m a l l y   
P: a p p r o x i m a t l y
经过 1:插入  2:删除 3:修改
那么 就是一个3-近似问题

事实上,两个字符串可能有不得出不同的差别数量,所以K-近似匹配要求:
(1)差别数最多为K个
(2)差别数为所有匹配方式下最少的称为编辑距离
(字符串T到P最少的差别数称为T和P的编辑距离)

试验要求:
(1)利用动态规划方法给出两个字符串编辑距离的算法
(2)分析复杂度
(3)考虑其它方法



Levenshtein Distance 来文史特距离

goodzzp

 LD也叫edit distance,它用来表示2个字符串的相似度,不同于Hamming Distance,它可以用来比较2个长度不同的字符串。LD定义为需要最少多少步基本操作才能让2个字符串相等,基本操作包含3个:
 1,插入;
 2,删除;
 3,替换;
 比如,kiteen和sitting之间的距离可以这么计算:
 1,kitten – > sitten, 替换k为s;
 2,sitten – > sittin, 替换e为i;
 3,sittin – > sitting, 增加g;
 所以,其LD为3;
 计算LD的算法表示为:
 int LevenshteinDistance(char str1[1..lenStr1], char str2[1..lenStr2])
 // d is a table with lenStr1+1 rows and lenStr2+1 columns
 declare int d[0..lenStr1, 0..lenStr2]
 // i and j are used to iterate over str1 and str2
 declare int i, j, cost

 for i from 0 to lenStr1
  d[i, 0] := i
 for j from 0 to lenStr2
  d[0, j] := j

 for i from 1 to lenStr1
  for j from 1 to lenStr2
   if str1[i] = str2[j] then cost := 0
         else cost := 1
   d[i, j] := minimum(
         d[i-1, j ] + 1,  // deletion
         d[i , j-1] + 1,  // insertion
         d[i-1, j-1] + cost // substitution
        )

 return d[lenStr1, lenStr2];
 这个算法其实就是一个矩阵的计算:
   k i t t e n
  0 1 2 3 4 5 6
 s 1 1 2 3 4 5 6
 i 2 2 1 2 3 4 5
 t 3 3 2 1 2 3 4
 t 4 4 3 2 1 2 3 
 i 5 5 4 3 2 2 3
 n 6 6 5 4 3 3 2
 g 7 7 6 5 4 4 3
 首先给定第一行和第一列,然后,每个值d[i,j]这样计算:d[i,j] = min(d[i-1,j]+ 1,d[i,j-1] +1,d[i-1,j-1]+(str1[i] == str2[j]?0:1));
 最后一行,最后一列的那个值就是LD的结果。
 LD(str1,str2) <= max(str1.len,str2.len);

  有人提出了Levenshtein automaton(Levenshtein自动机)来计算和某个字符串距离小于某个值的集合。这样能够加快近似字符串的计算过程。见文献:Klaus U. Schulz, Stoyan Mihov, Fast String Correction with Levenshtein-Automata. International Journal of Document Analysis and Recognition, 5(1):67--85, 2002.

A Guided Tour to Approximate String Matching GONZALO NAVARRO
 这篇文章里面对这个方面(字符串相似)进行了很多描述。其中,包含了动态规划法计算Edit distance的方法。

-------------------------------------------华丽丽的分割线-------------------------------------------------------------------------

js实现:

<script>

//求两个字符串的相似度,返回差别字符数,Levenshtein Distance算法实现

function Levenshtein_Distance(s,t){

 var n=s.length;// length of s

 var m=t.length;// length of t

 var d=[];// matrix

 var i;// iterates through s

 var j;// iterates through t

 var s_i;// ith character of s

 var t_j;// jth character of t

 var cost;// cost

 // Step 1

 if (n == 0) return m;

 if (m == 0) return n;

 // Step 2

 for (i = 0; i <= n; i++) {

  d[i]=[];

  d[i][0] = i;

 }

 for (j = 0; j <= m; j++) {

  d[0][j] = j;

 }

 // Step 3

 for (i = 1; i <= n; i++) {

  s_i = s.charAt (i - 1);

  // Step 4

  for (j = 1; j <= m; j++) {

   t_j = t.charAt (j - 1);

   // Step 5

   if (s_i == t_j) {

    cost = 0;

   }else{

    cost = 1;

   }

   // Step 6

   d[i][j] = Minimum (d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1] + cost);

  }

 }

 // Step 7

 return d[n][m];

}

//求两个字符串的相似度,返回相似度百分比

function Levenshtein_Distance_Percent(s,t){

 var l=s.length>t.length?s.length:t.length;

 var d=Levenshtein_Distance(s,t);

 return (1-d/l).toFixed(4);

}

//求三个数字中的最小值

function Minimum(a,b,c){

 return a<b?(a<c?a:c):(b<c?b:c);

}

var str1="ddsddf",str2="xdsfsx";

alert(Levenshtein_Distance_Percent(str1,str2));

</script>

时间: 2024-10-17 22:44:01

算法-转的相关文章

经典排序算法 - 冒泡排序Bubble sort

 原文出自于 http://www.cnblogs.com/kkun/archive/2011/11/23/bubble_sort.html 经典排序算法 - 冒泡排序Bubble sort 原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换, 这样一趟过去后,最大或最小的数字被交换到了最后一位, 然后再从头开始进行两两比较交换,直到倒数第二位时结束,其余类似看例子 例子为从小到大排序, 原始待排序数组| 6 | 2 | 4 | 1 | 5 | 9 | 第一趟排序(外循环) 第

转载:DenseNet算法详解

原文连接:http://blog.csdn.net/u014380165/article/details/75142664 参考连接:http://blog.csdn.net/u012938704/article/details/53468483 本文这里仅当学习笔记使用,具体细节建议前往原文细度. 论文:Densely Connected Convolutional Networks 论文链接:https://arxiv.org/pdf/1608.06993.pdf 代码的github链接:h

基于位置信息的聚类算法介绍及模型选择

百度百科 聚类:将物理或抽象对象的集合分成由类似的对象组成的多个类的过程被称为聚类.由聚类所生成的簇是一组数据对象的集合,这些对象与同一个簇中的对象彼此相似,与其他簇中的对象相异."物以类聚,人以群分",在自然科学和社会科学中,存在着大量的分类问题.聚类分析又称群分析,它是研究(样品或指标)分类问题的一种统计分析方法.聚类分析起源于分类学,但是聚类不等于分类.聚类与分类的不同在于,聚类所要求划分的类是未知的. 分类和聚类算法一直以来都是数据挖掘,机器学习领域的热门课题,因此产生了众多的

密码算法详解——AES

0 AES简介 美国国家标准技术研究所在2001年发布了高级加密标准(AES).AES是一个对称分组密码算法,旨在取代DES成为广泛使用的标准. 根据使用的密码长度,AES最常见的有3种方案,用以适应不同的场景要求,分别是AES-128.AES-192和AES-256.本文主要对AES-128进行介绍,另外两种的思路基本一样,只是轮数会适当增加. 1 算法流程 AES加解密的流程图如下: AES加密过程涉及到4种操作:字节替代(SubBytes).行移位(ShiftRows).列混淆(MixCo

矩阵乘法的Strassen算法详解

题目描述 请编程实现矩阵乘法,并考虑当矩阵规模较大时的优化方法. 思路分析 根据wikipedia上的介绍:两个矩阵的乘法仅当第一个矩阵B的列数和另一个矩阵A的行数相等时才能定义.如A是m×n矩阵和B是n×p矩阵,它们的乘积AB是一个m×p矩阵,它的一个元素其中 1 ≤ i ≤ m, 1 ≤ j ≤ p. 值得一提的是,矩阵乘法满足结合律和分配率,但并不满足交换律,如下图所示的这个例子,两个矩阵交换相乘后,结果变了: 下面咱们来具体解决这个矩阵相乘的问题. 解法一.暴力解法 其实,通过前面的分析

关于SVM数学细节逻辑的个人理解(三) :SMO算法理解

第三部分:SMO算法的个人理解 接下来的这部分我觉得是最难理解的?而且计算也是最难得,就是SMO算法. SMO算法就是帮助我们求解: s.t.   这个优化问题的. 虽然这个优化问题只剩下了α这一个变量,但是别忘了α是一个向量,有m个αi等着我们去优化,所以还是很麻烦,所以大神提出了SMO算法来解决这个优化问题. 关于SMO最好的资料还是论文<Sequential Minimal Optimization A Fast Algorithm for Training Support Vector

基于Spark MLlib平台的协同过滤算法---电影推荐系统

基于Spark MLlib平台的协同过滤算法---电影推荐系统 又好一阵子没有写文章了,阿弥陀佛...最近项目中要做理财推荐,所以,回过头来回顾一下协同过滤算法在推荐系统中的应用. 说到推荐系统,大家可能立马会想到协同过滤算法.本文基于Spark MLlib平台实现一个向用户推荐电影的简单应用.其中,主要包括三部分内容: 协同过滤算法概述 基于模型的协同过滤应用---电影推荐 实时推荐架构分析     一.协同过滤算法概述 本人对算法的研究,目前还不是很深入,这里简单的介绍下其工作原理. 通常,

算法 希尔排序

希尔排序 Shell Sort 介绍: 希尔排序(Shell Sort)也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本. 该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个"增量"的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序.因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率比直接插入排序有较大提高. 执行流程: 首先

算法 排序NB二人组 堆排序 归并排序

参考博客:基于python的七种经典排序算法     常用排序算法总结(一) 序前传 - 树与二叉树 树是一种很常见的非线性的数据结构,称为树形结构,简称树.所谓数据结构就是一组数据的集合连同它们的储存关系和对它们的操作方法.树形结构就像自然界的一颗树的构造一样,有一个根和若干个树枝和树叶.根或主干是第一层的,从主干长出的分枝是第二层的,一层一层直到最后,末端的没有分支的结点叫做叶子,所以树形结构是一个层次结构.在<数据结构>中,则用人类的血统关系来命名,一个结点的分枝叫做该结点的"

【机器学习实战】第2章 K-近邻算法(k-NearestNeighbor,KNN)

第2章 k-近邻算法 <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=default"></script> KNN 概述 k-近邻(kNN, k-NearestNeighbor)算法主要是用来进行分类的. KNN 场景 电影可以按照题材分类,那么如何区分 动作片 和 爱情片 呢? 动作片:打斗次数更多 爱情片