【紫书】例题3-6 环状序列(Circular Sequence, ACM/ICPC Seoul 2004, UVa1584)

【题目描述】

长度为n的环状串有n种表示法,分别为某个位置开始顺时针得到。例如,图中的环状串有10种表示:

CGAGTCAGCT,GAGTCAGCTC,AGTCAGCTCG等。在这些表示法中,字典序最小的称为“最小表示”。

输入一个长度为n(n<=100)的环状DNA串(只包含A、C、G、T这4种字符)的一种表示法,你的任务是输出该环状串的最小表示。例如,CTCC的最小表示是CCCT,CGAGTCAGCT的最小表示为AGCTCGAGTC.

输入:

在输入文件的第一行 为序列数量。每一个测试用例都需要一行包含一个循环序列,这个序列被写成一个任意的线性序列。由于循环序列是DNA串,只有四个符号:A,C,G,T。每一序列的长度为n(2<=n<=100)。

输出:

每行为串的字典序最小的序列。下面的样例为2个串的序列。

 

【样例输入】


CGAGTCAGCT 
CTCC

【样例输出】

AGCTCGAGTC 
CCCT

【代码实现】

 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 #define MAX (int)1e2 + 10
 5 
 6 int Isless( const char s[], int i, int start)
 7 {
 8     int len = strlen(s);
 9     printf ("%d\n", len);
10     for ( int j = 0; j < len; j ++)
11         if ( s[(i+j)%len] != s[(start+j)%len])
12             return s[(i+j)%len] < s[(start+j)%len];
13     return 0;
14 }
15 
16 int main()
17 {
18     char s[MAX];
19     while ( scanf ("%s", s) == 1 ) {
20         int start = 0;
21         int n = strlen(s);
22         for ( int i = 1; i < n; i++ ) {
23             if ( Isless(s, i, start) ) start = i;
24         }
25         for ( int i = 0; i < n; i++ ) {
26             printf ("%c", s[(start + i) % n]);
27         }
28         printf ("\n");
29     }
30     
31     return 0;
32 }

 

【总结】

自己想的有点复杂,没能写出来。。直接看的书,但书上题目描述不像上面那样详细,所以对具体输入的实现有些差别。但核心是一样的:下标0~n-1,找到最小字典序的起始位置。只要当前下标的字典序小于之前的,就将它用 start 记录下来,即不断更新 start 。有点类似于一组数中找最小值,只是比较方法单写了一个自定义函数罢了。

其中自定义函数形参表中的 const char* s 是个新的启发,如果写成 char s[] 则会有两点问题:

1. 定义不够准确,自定义函数中并不会对数组s进行修改,所以类型至少应该为 const char ;

2. 如果是形参为数组s[ ],则在函数内无法使用 sizeof 来求出数组长度,而定义为指针则不会有这个麻烦(虽然本题中使用的是 strlen() )。

对于循环数组的下标处理,在循环队列的数组实现时已经学过,但是又忘了。。这回再捡起来:对数组长度取模!

 

转载于:https://www.cnblogs.com/lilinilil/p/8450295.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值