`

配对序列生成算法实现与分析

阅读更多

配对算法实现与分析

这个也是做连连看时所写的算法,为了保持通用原则,这里一律采用数组实现

基本思路:

1.       先将所有元素填充到数组里,并把出现次数放到eCount[]里、最后出现的地址放到

lastAddr[]中。

2.       查看eCount[]此时数组里的各种元素出现的次数有双有单。

3.       找出两个eCount[x1],eCount[x2]为单的元素的lastAddr[x1]lastAddr[x2],并设置 data[lastAddr[x1]]=data[lastAddr[x2]]

4.       这就完成了双去单。

/**

     * 产生范围在[start,end]区间的配对的序列, 填充到int[arrayRows>0][arrayCloums>0]的数组中,

     * 最后返回这个数组

     * 完美版,适用于任何情况

     *

     * @param start

     *            起始整数

     * @param end

     *            终点整数

     * @param arrayRows

     *            数组行数

     * @param arrayColums

     *            数组列数

     * @return 如果参数中数组行列值小于等于零或者数组大小为奇数,则返回null,否则

     *         返回已经填充了配对数的数组int[arrayRows][arrayCloums]

     */

    public static int[][] partnerUP(int start, int end, int arrayRows,

           int arrayColums) {

 

       if (arrayColums <= 0 || arrayRows <= 0

              || (arrayColums * arrayRows) % 2 != 0) {

           return null;

       }

       int[] eCount;// 元素计数器

       int[] lastAddr;// 元素最后出现的地址

       int[][] data = new int[arrayRows][arrayColums];// 保存配对序列数组

       int arraySize = arrayRows * arrayColums;// 数组大小

       int maxPartners = arraySize / 2;// 数组中可能出现的最大对数

      

       // start恒置为小的数,end为大的数

       if (end - start < 0) {

           int tmp = end;

           end = start;

           start = tmp;

       }

       // 填充范围,大于0

       int fillArea = Math.abs(end - start) + 1;

       // 填充范围是否大于最大配对数,如果是的,则只需maxPartens个填充因子就可以了

       boolean isOverPartner=(fillArea - maxPartners)>0? true:false;

       int[]fillElemts=new int[0];

       if (isOverPartner) {

           //定义maxPartners个格子用来装随机从fillArea中取出的填充因子

           fillElemts=new int[maxPartners];

           for(int i=0;i<fillElemts.length;i++){

              fillElemts[i]=start+(int)(Math.random()*fillArea);

           }

           //数组地址范围,计数器、最后地址数组地址范围

           fillArea=maxPartners;

           eCount = new int[fillArea];

           lastAddr = new int[fillArea];

       }else{

           eCount = new int[fillArea];

           lastAddr = new int[fillArea];

       }

       // 填充data[][]

       for (int i = 0; i < arraySize; i++) {

           // 随机产生一张图片索引

           int index = start + (int) (Math.random() * fillArea);

           // 对应索引计数+1

           eCount[index - start] += 1;

           if(isOverPartner){

              //选取抽取出来的元素

              data[i / arrayColums][i % arrayColums]=fillElemts[index-start];

           }else{

              // 将图片名称放入Data

               data[i / arrayColums][i % arrayColums] = index;

           }

           // 将最后出现的地址赋给addrCount[index]保存

           lastAddr[index - start] = i;

 

       }

       // 图素配对开始(去单操作)

       // 从计数数组的最有一个元素开始

       int i = eCount.length - 1;

       // 出现的元素中数量为奇数的元素个数

       int pCount = 0;

       while (i > -1) {

           if (eCount[i--] % 2 == 1) {

              pCount += 1;

           }

       }

       // 如果确实存在奇数个元素

       while (pCount > 0) {

           for (int j = 0; j < eCount.length - 1; j++) {

              for (int k = 1; k < eCount.length; k++) {

                  if (eCount[j] % 2 == 1) {

                     if (eCount[k] % 2 == 1) {

                         // 计数器为奇数的图素地址交换(根据最后图素保存的地址进行交换操作)

                         data[lastAddr[j] / arrayColums][lastAddr[j]

                                % arrayColums] = data[lastAddr[k]

                                / arrayColums][lastAddr[k] % arrayColums];

                         eCount[j] -= 1;

                         eCount[k] += 1;

                         pCount -= 2;//去掉两个奇数素

 

                     }

                  }

              }

           }

       }// 图素配对结束

       return data;

    }

测试结果:

Xx代表方括号里的的数字

LLKTookit.partnerUP(x,x,4,4)

===========[1,15]

8,14,15,14,

10,8,2,1,

15,2,1,10,

14,8,14,8,

==============[-115]

-1,12,6,12,

3,6,6,6,

13,-1,6,15,

15,13,6,3,

==============[-1,-15]

-6,-5,-6,-6,

-9,-6,-6,-1,

-7,-9,-5,-7,

-15,-1,-6,-15,

=============[0,0]

0,0,0,0,

0,0,0,0,

0,0,0,0,

0,0,0,0,

=============[1,1]

1,1,1,1,

1,1,1,1,

1,1,1,1,

1,1,1,1,

==============[-1,-1]

-1,-1,-1,-1,

-1,-1,-1,-1,

-1,-1,-1,-1,

-1,-1,-1,-1,

分析:从代码上看,写得比较繁杂,从运行结果来看,该函数实现的还不错。

总结:这个方法的实现经历最初的内嵌版本,再是分离出来后的不完美版(有兴趣的可以看看,在下面),知道今天改的自认为完美版,一路走来都意味着一次次的进步,和对完美的追求,今天写的这个配对算法和之前写的连线算法一起,作为我暑假连连看游戏制作的最终收获,我觉得,虽然不丰厚,但至少很值得。

 

不完美版代码,在注释中有 “为什么不完美的解释”

以下是word文档

 

分享到:
评论

相关推荐

    数据结构与算法分析

    书的内容包括表、栈、队列、树、散列表、优先队列、排序、不相交集算法、图论算法、算法分析、算法设计、摊还分析、查找树算法、k-d树和配对堆等。本书适合作为计算机相关专业本科生的数据结构课程和研究生算法分析...

    数据结构与算法分析第二版 ---C语言描述(附加答案)

    不相交集ADT8.1 等价关系8.2 动态等价性问题8.3 基本数据结构8.4 灵巧求并算法8.5 路径压缩8.6 按秩求并和路径压缩的最坏情形8.6.1 Union/Find算法分析8.7 一个应用总结练习参考文献第9章 图论算法9.1 若干定义9.1.1...

    数据结构与算法分析_Java语言描述(第2版)

    《数据结构与算法分析:Java语言描述(第2版)》是国外数据结构与算法分析方面的经典教材,使用卓越的Java编程语言作为实现工具讨论了数据结构(组织大量数据的方法)和算法分析(对算法运行时间的估计)。...

    数据结构与算法分析Java语言描述(第二版)

    算法分析2.1 数学基础2.2 模型2.3 要分析的问题2.4 运行时间计算2.4.1 一个简单的例子2.4.2 一般法则2.4.3 最大子序列和问题的求解2.4.4 运行时间中的对数2.4.5 检验你的分析2.4.6 分析结果的准确性小结练习参考文献...

    数据结构与算法分析_Java语言描述(第2版)]

    Java语言描述(第2版)》是国外数据结构与算法分析方面的经典教材,使用卓越的Java编程语言作为实现工具讨论了数据结构(组织大量数据的方法)和算法分析(对算法运行时间的估计)。随着计算机速度的不断增加和功能...

    数据结构与算法分析 Java语言描述第2版

    内容简介《数据结构与算法分析:Java语言描述(第2版)》是国外数据结构与算法分析方面的经典教材,使用卓越的Java编程语言作为实现工具讨论了数据结构(组织大量数据的方法)和算法分析(对算法运行时间的估计)。...

    数据结构与算法分析_Java_语言描述

    参考文献 第2章 算法分析 2.1 数学基础 2.2 模型 2.3 要分析的问题 2.4 运行时间计算 2.4.1 一个简单的例子 2.4.2 一般法则 2.4.3 最大子序列和问题的解 2.4.4 运行时间中的对数 2.4.5 检验你的分析 ...

    数据结构与算法分析C描述第三版

    Mark Allen Weiss,1987年在普林斯顿大学获得计算机科学博士学位,师从著名算法大师Robert Sedgewick,现任美国佛罗里达国际大学计算与信息科学学院教授。他曾经担任全美AP(Advanced Placement)考试计算机学科委员...

    OLGA:计算CDR3氨基酸和核苷酸序列的生成概率

    该软件实现了讨论的动态编程算法,以计算氨基酸和框内核苷酸 CDR3 序列的生成概率。 由于自适应库的研究人员需要掌握全部技术编码技能,因此本README和软件的目标是,对于具有任何编程背景的研究人员都应尽可能地...

    数据结构与算法分析-Java语言描述(第2版)_2_2

    2.4 运行时间计算 2.4.1 一个简单的例子 2.4.2 一般法则 2.4.3 最大子序列和问题的求解 2.4.4 运行时间中的对数 2.4.5 检验你的分析 2.4.6 分析结果的准确性 小结 练习 参考文献第3章 表、栈和队列...

    数据结构与算法分析-Java语言描述(第2版)_1_2

    2.4 运行时间计算 2.4.1 一个简单的例子 2.4.2 一般法则 2.4.3 最大子序列和问题的求解 2.4.4 运行时间中的对数 2.4.5 检验你的分析 2.4.6 分析结果的准确性 小结 练习 参考文献第3章 表、栈和队列...

    本工程是21个项目玩转深度学习-基于TensorFlow的实践详解的配套代码

    CycleGAN与非配对图像转换 RNN基本结构与Char RNN文本生成 序列分类问题详解 词的向量表示:word2vec与词嵌入 在TensorFlow中进行时间序列预测 神经网络机器翻译技术 看图说话:将图像转换为文字 强化学习入门之Q ...

    数据结构实验报告

    数据结构实验报告 第一次实验 1、请编写26个字母按特定的字母值插入或者删除的完整程序,可自行选用顺序存储或者链表存储。 2、创建一个链表。 ...1、实现下述三种算法,并用以下无序序列加以验证

    论文研究-一种新的数字图像置乱方案.pdf

    提出了一种新的数字图像置乱概念...配对的选择方式和移位次数决定于离散Chebyshev映射系统生成的密钥混沌序列。混沌系统的特性使得该置乱方法具有随机性和变化的多样性。讨论了置乱算法的安全性问题并给出了实验结果。

    华东《计算机图形学》2017年春学期在线作业(一).doc

    〔 〕是图形的基本元素,其生成算法直接决定着系统的效率. A. 直线和圆弧 B. 直线和多边形 C. 圆弧和多边形 D. 曲线和曲面 正确答案: 13. 计算机图形学与计算机图像处理的关系是〔 〕. A. 计算机图形学是基础,...

    svtyper:贝叶斯基因分型仪用于结构变异

    用户必须提供基因型位点的VCF文件(可能由生成),以及与对齐的Illumina配对末端读段的BAM / CRAM文件。 SVTyper评估来自配对末端和分裂阅读序列比对的不一致和一致阅读,以推断每个位点的基因型。 算法细节和基准...

Global site tag (gtag.js) - Google Analytics