无分隔符字典问题
2015-11-26 10:46
776 查看
#include <iostream> #include <fstream> #include <vector> #include <set> using namespace std; int *ak; int lk; int n, k; int best = 0; //最大无分隔符字典元素个数 vector<int> L; //将所有的长度为k的数字字符串存到集合L中 set<int> S; //当前字典中的字符串存储在集合s中 //将下标为L[]中下标为i的字符串存入集合s void insert(int i) { S.insert(L[i]); } //将下标为L[]中下标为i的字符串存入集合s void erase(int i) { S.erase(L[i]); } //将ak[]中起点为i-1,长度为k-1数字串转换为十进制数字 int digi(int i) { int ii = k + i - 2; int x = ak[ii--]; for(int j=0; j<k-1; j++) { x *= 10; x += ak[ii]; ii--; } return x; } //判断字符串a和第b个字符串是否互不为前缀 bool pref(int a, int b) { int bb = L[b]; int x = a; int y = bb/n; //去掉最高位,得到低k-1位 for(int i=0; i<k-1; i++) //ak[0, k-2]存放x的低k-1位,ak[k-1, k-1 + (k-2)]存放y { ak[k-i-2] = x % n; x /= n; ak[2*k-i-3] = y % n; y /= n; } for(i=1; i<k; i++) //相当于依次判断a2a3..akb1, a3a4..b1b2, akb1..bk-1是否已存在于S中,本程序中下标从0开始 if(S.count(digi(i)) > 0) //如果已存在于S中 return true; x = bb; y = a/n; for(i=0; i<k-1; i++) { ak[k-i-2] = x % n; x /= n; ak[2*k-i-3] = y % n; y /= n; } for(i=1; i<k; i++) if(S.count(digi(i)) > 0) return true; return false; } //判断当前下标为b的字符串是否可以加入字典 //将字符串a1a2..ak看作k位十进制数 bool oka(int b) { int bb = L[b]; set<int>::iterator it; //定义迭代器 it = S.begin(); while(it != S.end()) { int a = *it; if(pref(a, bb)) //如果a,b其中一个是另一个的前缀 return false; it++; } return true; } //得到总元素个数为n,长度为m的全排列 void Perm(int list[], int dep, int m, int n) { if(dep>m) { int x = 0; for(int i=1; i<=m; i++) x = x*10 + list[i]; //转换为十进制数字 L.push_back(x); //将所有的数字字符串存到集合L中 } else for(int j=1;j<=n;j++) { swap(list[dep], list[j]); Perm(list, dep+1, m, n); swap(list[dep], list[j]); } } void backtrack(int dep) { if(dep >= lk) { if(S.size() > best) best = S.size(); return; } if(oka(dep)) { insert(dep); backtrack(dep+1); erase(dep); } backtrack(dep+1); } int main() { ifstream fin("无分隔符字典.txt"); cout << "输入正整数n:"; fin >> n; cout << n; cout << "\n输入正整数k:"; fin >> k; cout << k; ak = new int[2*k]; lk = n; for(int i=1; i<k; i++) //k个字符中,每一个字符都有n种选择,n^k表示所有由k个字符组成的字符串种数 lk *= n; lk--; int *x = new int[n+1]; for(i=1; i<=n; i++) x[i] = i; Perm(x, 1, k, n); //将长度为k的全排列存入集合L中 backtrack(0); cout << "\n最大无分隔符字典元素个数为:" << best; cout << endl; cout << endl; fin.close(); return 0; }
相关文章推荐
- android卸载或者程序更新,SharedPrefefences文件会删除吗
- Python机器学习——如何shuffle一个数据集(ndarray类型)
- 图文讲解如何搭建Apache服务器
- iOS 打包上线_报错All object files and libraries for bitcode...
- Nginx安装部署
- cocospod在升级到xcode出现的问题及解决
- Kali linux渗透测试的艺术 思维导图
- Java_Html_杂七杂八_路径中有/和无/的区别,../和./的区别
- iisreset远程重启IIS服务提示没有注册类
- zoj Exchange Cards 2734
- 华为OJ基础篇-求小球落地5次后所经历的路程和第5次反弹的高度
- 从《LOL》谈游戏中的随机动作优化
- 该行已经属于另一个表的解决方法
- Haxe: class, object, new and constructor
- 和用户与组相关的命令
- jdk使用问题汇总
- 15、手把手教你Extjs5(十五)各种Grid列的自定义渲染
- ArrayList和LinkedList的区别
- Oracle查询用户所有表
- 为什么Actor模型是高并发事务的终极解决方案?