详情说明可以参考其他文章,我这里是对康托展开 和 逆康托展开的JavaScript实现。
代码:
/*全排列散列 - (康托展开 和 逆康托展开) 康托展开式:X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! * 例如 * 1,2,3 规定为0 * 1,3,2 规定为1 * 2,1,3 规定为2 * 2,3,1 规定为3 * 3,1,2 规定为4 * 3,2,1 规定为5 * */ // 求阶乘 function fac( x) { let ans = 1; for (let i = 2; i <= x; i++) { ans *= i; } return ans; } //康托展开:对一个 a 的全排列,返回一个整数代表它在所有排列中的排名 function cantor(a) { const n=a.length; let ans=0; for(let i = 0; i < n; i++) { let temp = 0; for (let j = i + 1; j < n; j++) { if (a[j] < a[i]) temp++; } ans += temp * fac(n - i - 1); } return ans; } //逆康托展开 function decantor( x, oa) { const a=[].concat(oa).sort(function (n,m) { return n-m; }) const na=[] const n=a.length; let temp; let used=[]; let i,j; for(i=0;i<n;i++){ temp= (x/fac(n-i-1))>>0 for( j=0;j<n;j++){ if(!used[j]){ if(temp===0)break; --temp; } } na[i]=a[j]; used[j]=true; x=x%fac(n-i-1); } return na; }
测试:
//测试 const arr1=[5,2,3,4] for(let i=0;i<fac(arr1.length);i++){ const arr=decantor(i,arr1); console.log(cantor(arr)) console.log(arr) } //结果 "C:\Program Files\nodejs\node.exe" D:\test\Cantor.js 0 [ 2, 3, 4, 5 ] 1 [ 2, 3, 5, 4 ] 2 [ 2, 4, 3, 5 ] 3 [ 2, 4, 5, 3 ] 4 [ 2, 5, 3, 4 ] 5 [ 2, 5, 4, 3 ] 6 [ 3, 2, 4, 5 ] 7 [ 3, 2, 5, 4 ] 8 [ 3, 4, 2, 5 ] 9 [ 3, 4, 5, 2 ] 10 [ 3, 5, 2, 4 ] 11 [ 3, 5, 4, 2 ] 12 [ 4, 2, 3, 5 ] 13 [ 4, 2, 5, 3 ] 14 [ 4, 3, 2, 5 ] 15 [ 4, 3, 5, 2 ] 16 [ 4, 5, 2, 3 ] 17 [ 4, 5, 3, 2 ] 18 [ 5, 2, 3, 4 ] 19 [ 5, 2, 4, 3 ] 20 [ 5, 3, 2, 4 ] 21 [ 5, 3, 4, 2 ] 22 [ 5, 4, 2, 3 ] 23 [ 5, 4, 3, 2 ] Process finished with exit code 0
标签:展开,let,规定,+...+,逆康托,康托 来源: https://www.cnblogs.com/caoke/p/10954666.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。