怎样高效解决如下“寻找最大子块”的算法问题(已解决,代码已出,见答案区本人自答)( 二 )
例如对于上例取mincol = 3, minrow=2,则深度遍历FP-tree中以a为根节点的分支只有两个节点进行了size计算与比较。嫁接后以b为根节点的分支中也仅有一个节点满足要求,进行了size计算与比较。最终的maxsize为12,colset为{a,b,c}, rowset为{1,5,6,8}。
========================================================================以上程序的复杂度最坏为n^2*m。平均下来远达不到。事实上我的同学已经帮我想出解决方案啦!!!平均时间复杂度为n^2*m,空间复杂度有点高。最重要的这种方法可以从2维扩展到3维!现在还是先说对于2维的处理。感谢我的同学!!========================================================================(这是初版的思路,其实Hash表没必要,一个大的数组就行了。当然要Hash表也不影响结果正确性,只是稍稍慢了一点点。)思路:把每一行和其他行按位与,按位与的值构成节点插入到Hash表中,同时需要调整其他节点的块中1的个数。如果按位与的值完全覆盖了已经在Hash表中节点的值,那么已经在Hash表中的节点count值自动加上的rown,同时注意不能有重复的行被加入。直接上代码:这份代码是对的,但是还可以进一步改进,这里就贴这个了。改进的地方在代码里hashInsert()注释说了。测试数据在后面。#include \u0026lt;stdio.h\u0026gt;#include \u0026lt;stdlib.h\u0026gt;#include \u0026lt;time.h\u0026gt;#include \u0026lt;memory.h\u0026gt;#define max 127// 一个节点代表一个子矩阵struct node{ int val; // 按位与后的值 int count; // 当前块中1的个数 int* rows; // 行数 int rown; // 行号 int* cols; // 列号 int coln; // 列数 struct node* next;//哈希表同一个hash值中的下一个};struct hashTable{ struct node* list; // Hash表 struct node* topNode; // 当前块中1的个数最多的节点};struct node* hashFind(const struct hashTable* table, const struct node* iterator);void hashInsert(struct hashTable* table, struct node* iterator);void colCal(struct node* iterator, int m);void maxHash(const struct hashTable* table);int main(){ FILE* fp = fopen("d://data.txt","r"); int n,m; fscanf(fp,"%d%d",\u0026amp;n,\u0026amp;m); int re; memset(re,0,sizeof(re)); for(int i=0; i\u0026lt;n; i++) for(int j=0; j\u0026lt;m; j++) { int temp; fscanf(fp,"%d",\u0026amp;temp); re += temp \u0026lt;\u0026lt; (m-j-1); } struct hashTable* table = (struct hashTable*) malloc(sizeof(struct hashTable)); memset(table-\u0026gt;list,0,sizeof(table-\u0026gt;list)); table-\u0026gt;topNode = NULL; for(int i=0; i\u0026lt;n; i++) for(int j=i; j\u0026lt;n; j++) { struct node* temp = (struct node*) malloc(sizeof(struct node)); temp-\u0026gt;val = re \u0026amp; re; temp-\u0026gt;rown = 0; temp-\u0026gt;coln = 0; temp-\u0026gt;cols = (int*) malloc(sizeof(int)*m); temp-\u0026gt;rows = (int*) malloc(sizeof(int)*n); temp-\u0026gt;rows = i; if(i!=j) temp-\u0026gt;rows = j; temp-\u0026gt;next = NULL; colCal(temp,m); temp-\u0026gt;count = temp-\u0026gt;coln * temp-\u0026gt;rown; hashInsert(table,temp); } maxHash(table); return 0;}void maxHash(const struct hashTable* table){ struct node* temp = table-\u0026gt;topNode; int val = temp-\u0026gt;val; printf("Size:%d\",temp-\u0026gt;rown*temp-\u0026gt;coln); printf("Rows:"); for(int i=0; i\u0026lt;temp-\u0026gt;rown; i++) printf("%d ",temp-\u0026gt;rows+1); printf("\Cols:"); for(int i=0; i\u0026lt;temp-\u0026gt;coln; i++) printf("%d ",temp-\u0026gt;cols+1); return;}void colCal(struct node* iterator, int m){ iterator-\u0026gt;coln = 0; int val = iterator-\u0026gt;val; for(int i=0; i\u0026lt;m \u0026amp;\u0026amp; val\u0026gt;0; i++) { if(val \u0026amp; 1) iterator-\u0026gt;cols = m-i-1; val \u0026gt;\u0026gt;= 1; }}struct node* hashFind(const struct hashTable* table, const struct node* iterator){ struct node* temp = table-\u0026gt;list; while(temp != NULL \u0026amp;\u0026amp; temp-\u0026gt;val != iterator-\u0026gt;val) temp = temp-\u0026gt;next; return temp;}void hashInsert(struct hashTable* table, struct node* iterator){ struct node* temp; for(int k=0; k\u0026lt;max; k++)\t//改进:这个for循环不需要,原因在于下面几行那个注释的判断不需要。 { temp = table-\u0026gt;list; if(temp == NULL) continue; while(temp != NULL) { if((temp-\u0026gt;val \u0026amp; iterator-\u0026gt;val) == temp-\u0026gt;val)\t//这部分完全没有必要,也就是整个for循环是不需要的!这部分只要(iterator-\u0026gt;val == temp-\u0026gt;val)就行了,那么不用for循环遍历表,直接取table-\u0026gt;list就行了。 { for(int i=0; i\u0026lt;iterator-\u0026gt;rown; i++) { int flag = 1; for(int j=0; j\u0026lt;temp-\u0026gt;rown; j++) { if(temp-\u0026gt;rows == iterator-\u0026gt;rows) { flag = 0; break; } } if(flag){ temp-\u0026gt;rows = iterator-\u0026gt;rows; temp-\u0026gt;count += temp-\u0026gt;coln; } } if(table-\u0026gt;topNode == NULL || temp-\u0026gt;count \u0026gt; table-\u0026gt;topNode-\u0026gt;count) table-\u0026gt;topNode = temp; } temp = temp-\u0026gt;next; } } if(!hashFind(table,iterator)) { temp = table-\u0026gt;list; if(temp == NULL) table-\u0026gt;list = iterator; else{ while(temp-\u0026gt;next != NULL) temp = temp-\u0026gt;next; temp-\u0026gt;next = iterator; } if(table-\u0026gt;topNode == NULL || iterator-\u0026gt;count \u0026gt; table-\u0026gt;topNode-\u0026gt;count) table-\u0026gt;topNode = iterator; } else free(iterator); return;}
推荐阅读
- 聪明人养花,这3种“花”怎样也要养一盆,每年能省不少医药费
- 蟹爪兰叶子软塌,难复花,“根源”在这里,解决后开花一茬接一茬
- 贵州在建骨干水源工程达到465座有效解决工程性区域性缺水问题
- 长春社区开设助老餐厅探索解决老人“吃饭难”
- 互联网怎样解决“家政服务上门速度慢”的问题
- 怎样看待从1月8号起,QQ钱包开始提现收费
- 银行it人怎样转型
- 汽车|冬天怎样让车内温度快速升高?座椅加热的最佳使用方式二,外循环的作用总结
- 怎样进入通信行业
- 怎样评价扶他柠檬茶的小说《云养汉》的结尾
