首先是昨天在北京大学oj网上看到一个简单的算法题目,虽然简单,但是如何完成一段高效、简洁、让人容易看懂的代码对于我这个基础不好,刚刚进入计算机行业的小白来说还是有意义的。而且在写代码的过程中,会发现自己平时学习中不会发现的问题,所以想写下这个博客,主要是便于自己对算法的理解。

来,上题。

DNA Sorting
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 91599   Accepted: 36781

Description

One measure of ``unsortedness'' in a sequence is the number of pairs of entries that are out of order with respect to each other. For instance, in the letter sequence ``DAABEC'', this measure is 5, since D is greater than four letters to its right and E is greater than one letter to its right. This measure is called the number of inversions in the sequence. The sequence ``AACEDGG'' has only one inversion (E and D)---it is nearly sorted---while the sequence ``ZWQM'' has 6 inversions (it is as unsorted as can be---exactly the reverse of sorted).

You are responsible for cataloguing a sequence of DNA strings (sequences containing only the four letters A, C, G, and T). However, you want to catalog them, not in alphabetical order, but rather in order of ``sortedness'', from ``most sorted'' to ``least sorted''. All the strings are of the same length.

Input

The first line contains two integers: a positive integer n (0 < n <= 50) giving the length of the strings; and a positive integer m (0 < m <= 100) giving the number of strings. These are followed by m lines, each containing a string of length n.

Output

Output the list of input strings, arranged from ``most sorted'' to ``least sorted''. Since two strings can be equally sorted, then output them according to the orginal order.

Sample Input

  1. 10 6
  2. AACATGAAGG
  3. TTTTGGCCAA
  4. TTTGGCCAAA
  5. GATCAGATTT
  6. CCCGGGGGGA
  7. ATCGATGCAT

Sample Output

  1. CCCGGGGGGA
  2. AACATGAAGG
  3. GATCAGATTT
  4. ATCGATGCAT
  5. TTTTGGCCAA
  6. TTTGGCCAAA
  7.  
  8. #01、这是一个很简单的题目,基本上就是看完题目,思路就出来的那种。这个题目主要要解决以下几个小麻烦。
    0X001:存放DNA序列的数据结构,存放这种类型的数据,最好的当然是二维数组啦。m,n是在程序运行过程中用户输入的,显然不能直接char N_DNA[n][m]来定义。
    虽然题目中给出了m和n都要小于等于50,但是设一个太大的数组,还有很多空间浪费,作为一个较真的程序员,显然是心里过不去的。
    如是,我们可以采用下面的方法定义数组,并分配空间。
  1. template <typename T>
  2. //定义Arr数据类型
  3. class Arr
  4. {
  5. public:
  6. Arr(int length)
  7. {
  8. this->length = length;
  9. data = new T[length];
  10. }
  11. T *data;
  12. unsigned int length;
  13. };
  14. typedef Arr<char>* P_of_Arr;//P_of_Arr是一维Arr数组的指针类型
  15. void main()
  16. {
  17. int m, n;
  18. scanf("%d %d", &m, &n);
  19. //构造N_DNA数组
  20. Arr<P_of_Arr> N_DNA(n);
  21. 21 //给N_DNA的data数组的每个指针分配空间
  22. int t;
  23. for (t = ; t < n; t++)
  24. {
  25. N_DNA.data[t] = new Arr<char>(m);
  26. }
  27. }

这里面主要用到两个c++的知识,写出来,加强一下自己的理解。

其一就是temptale的使用,关键字template在这里的作用让class Arr的类型多向化,就是让class Arr可以有多种理解,就是让class Arr成为一个模板,当在其他一些相似但是又不相同的环境下可以被再次使用。通俗点讲,就是先假装,T是已经定义的类型。让编译器认可它,不报错。在Arr定义变量的时候,再来补上T的类型。因此,这样用template模板定义的类型,可以在不同的类型T的环境中使用。

其二是new的使用,首先我们定义一个Arr数组Arr<P_of_Arr> N_DNA(n);我们可以看到Arr构造函数里面,this->length = length;data = new T[length];将n传给Arr域里面的length,并且分配一个T[n]空间的数组,并把指针传给data(注意,这里data是二重指针,也就是数组是data[n],其中data[0,1....n]也是指针,因为定义Arr时,T是P_of_Arr,而typedef Arr<char>* P_of_Arr;//P_of_Arr是一维Arr数组的指针类型)。

  1. int t;
  2. for (t = ; t < n; t++)
  3. {
  4. N_DNA.data[t] = new Arr<char>(m);
  5. }

然后我们循环,依次给data[0,1...n]分配空间.每一个data[i]指向一个一维的Arr类型的数据。

至此,我们就分配了N_DNA.data[n]->data[m]的数组。

#02数据的输入,cin的理解,cin是C++库函数里面的一系列函数,cin>>/cin.get/cin.getline...这些函数的用法在这里不再赘述。

可以参考以下两篇博客,里面讲的比较清楚

个人体会就是在使用和理解这些函数时,了解两个方面问题。

第一、space,tab,Enter是否被从缓冲区中舍弃。<space,tab,Enter>

第二、cin.getline在超出范围时,通过怎样影响输入标志位,来影响后续的输入。<failbit,eofbit,badbit//goodbit>

参考博客: 

     http://www.cnblogs.com/A-Song/archive/2012/01/29/2331204.html

     http://blog.csdn.net/dongtingzhizi/article/details/2299365

之后就是非常常规简单的代码了,定义一个数组rel记录DNA的逆值,然后依次按照逆值从小到大输出DNA序列。

完全的代码如下:

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include<iostream>
  3. using namespace std;
  4. #define MAX 12768
  5. template <typename T>
  6. class Arr
  7. {
  8. public:
  9. Arr(int length)
  10. {
  11. this->length = length;
  12. data = new T[length];
  13. }
  14. T *data;
  15. unsigned int length;
  16. };
  17. typedef Arr<char>* P_of_Arr;
  18. int main(void)
  19. {
  20. int m, n;
  21. scanf("%d %d", &m, &n);
  22. //构造N_DNA数组
  23. Arr<P_of_Arr> N_DNA(n);
  24. int t;
  25. for (t = ; t < n; t++)
  26. {
  27. N_DNA.data[t] = new Arr<char>(m);
  28. }
  29. int i,j,k;
  30. int *rel = new int[n];
  31. //输入DNA序列
  32. cin.getline(N_DNA.data[]->data, m + );
  33. for (i = ; i < n; i++)
  34. cin.getline(N_DNA.data[i]->data, m+);
  35. //循环遍历,用rel记录各个DNA序列的逆值
  36. for (k = ; k < n; k++)
  37. {
  38. rel[k] = ;
  39. for (i = ; i < m; i++)
  40. for (j = i; j < m; j++)
  41. if (N_DNA.data[k]->data[i]>N_DNA.data[k]->data[j])
  42. rel[k]++;
  43. }
  44. int *usedrel = new int[n];//标志rel是否被用
  45. //初始化全为0
  46. for (i = ; i < n; i++)
  47. usedrel[i] = ;
  48. //查找最小的逆值得DNA序列,并输出
  49. for (i = ; i < n; i++)
  50. {
  51. k = -;//记录最小逆值的地址
  52. int min=MAX;//记录最小的逆值
  53. for (j = ; j < n; j++)
  54. if (rel[j] < min&&usedrel[j]==)
  55. {
  56. min = rel[j];
  57. k = j;
  58. }
  59. usedrel[k] = ;//标记已经被访问
  60. for (j = ; j < m; j++)
  61. cout << N_DNA.data[k]->data[j];
  62. cout << endl;
  63. }
  64. return ;
  65. }

运行结果如下:

         
由于题目对于输入输出有要求,所以没有将输入输出分开。

一个简单算法题引发的思考<DNA sorting>(about cin/template/new etc)的更多相关文章

  1. What number should I guess next ?——由《鹰蛋》一题引发的思考

    What number should I guess next ? 这篇文章的灵感来源于最近技术部的团建与著名的DP优化<鹰蛋>.记得在一个月前,查到鹰蛋的题解前,我在与同学讨论时,一直试 ...

  2. 从一段简单算法题来谈二叉查找树(BST)的基础算法

    先给出一道很简单,喜闻乐见的二叉树算法题: 给出一个二叉查找树和一个目标值,如果其中有两个元素的和等于目标值则返回真,否则返回假. 例如: Input: 5 / \ 3 6 / \ \ 2 4 7 T ...

  3. 大话JS面向对象之扩展篇 面向对象与面向过程之间的博弈论(OO Vs 过程)------(一个简单的实例引发的沉思)

    一,总体概要 1,笔者浅谈 我是从学习Java编程开始接触OOP(面向对象编程),刚开始使用Java编写程序的时候感觉很别扭(面向对象式编程因为引入了类.对象.实例等概念,非常贴合人类对于世间万物的认 ...

  4. 一个简单的特效引发的大战之移动开发中我为什么放弃jquery mobile

    我本想安静的做一个美男子,可是,老板不涨工资,反而,一月不如一月. 我为什么放弃jquery mobile插件选择自己写特效? 在开发中大家都知道效率很重要,一个好的工具可以在开发中大大提升效率,工作 ...

  5. java算法题每日一练01,java入门简单算法题小练

    1.给数组做反序 public class Ak01 { public static void main(String[] args) { int[] a = new int[]{22,48,41,2 ...

  6. 一个JAVA题引发的思考

    转载自:http://www.cnblogs.com/heshan664754022/archive/2013/03/24/2979495.html 十年半山 今天在论坛闲逛的时候发现了一个很有趣的题 ...

  7. 第6届蓝桥杯javaA组第7题,牌型种数,一道简单的题带来的思考

    题目: 小明被劫持到X赌城,被迫与其他3人玩牌. 一副扑克牌(去掉大小王牌,共52张),均匀发给4个人,每个人13张. 这时,小明脑子里突然冒出一个问题: 如果不考虑花色,只考虑点数,也不考虑自己得到 ...

  8. C# 一个简单的秒表引发的窗体卡死问题

    一个秒表程序也是我的一个心病,因为一直想写这样的一个东西,但是总往GUI那边想,所以就比较怵,可能是上学的时候学MFC搞出的后遗症吧,不过当我今天想好用Win Form(话说还是第一次写win for ...

  9. 一个简单的CD/CI流程思考,续

    经过各种优化,最终一个非常简单的pipeline出现了,图中没有包含单元测试及静态代码检查的部分,有时间补上.至少实现了提交即构建,也能迅速反馈给开发者. 但是最大的问题是,研发团队还是习惯依赖于部署 ...

随机推荐

  1. target,currentTarget和this三者的区别

    target在事件流的目标阶段:currentTarget在事件流的捕获,目标及冒泡阶段.只有当事件流处在目标阶段的时候,两个的指向才是一样的, 而当处于捕获和冒泡阶段的时候,target指向被单击的 ...

  2. AIX 环境下遇到Device Busy问题

    IBM AIX v5.3操作系统环境下在对网络或网卡进行操作过程中经常遇到"Device Busy"而终止操作例如:#rmdev -l ent1遇到如下返回信息Method err ...

  3. HTML Meta中添加X-UA-Compatible和IE=Edge,chrome=1有什么作用

    你好,这个属性主要是设置浏览器优先使用什么模式来渲染页面的.常见写法如下:<meta http-equiv="X-UA-Compatible" content="I ...

  4. ARCGIS Server 发布服务时出现的问题解决

    target='CFH.ConfigurationFactoryHost'  machine='IBM3850X5'  thread='24072'  elapsed='0.31200'>Ser ...

  5. iOS有用的三方库

    DKNightVersion https://github.com/Draveness/DKNightVersion#podfile 用来为APP添加夜间模式和换肤功能

  6. 常用前端框架Angular和React的一些认识

    为什么要用AngularJs? 要了解为什么使用AngularJS首先就要接受它的思想: 首先,angularJS借助了传统MVC的架构模式(model模型  view视图  controller控制 ...

  7. 循序渐进Python3(十一) --4--  web之jQuery

    jQuery         jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架).jQuery设计的 ...

  8. C# DataTable 和List之间相互转换的方法

    介绍:List/IEnumerable转换到DataTable/DataView,以及DataTable转换到List 正文: 一.List<T>/IEnumerable转换到DataTa ...

  9. POJ2186

    poj2186 popular cows   Every cow's dream is to become the most popular cow in the herd. In a herd of ...

  10. CSS 图片倾斜的制作

    <style> #zhong{ height:600px; width:1350px; position:relative; z-index:2} .znei{ height:60px; ...