暴力枚举(字符串匹配)-Blue Jeans POJ - 3080

暴力枚举(字符串匹配)-Blue Jeans POJ - 3080

题目:

Genographic项目是IBM与国家地理学会之间的研究合作伙伴关系,该合作伙伴正在分析数十万贡献者的DNA,以绘制地球的分布图。

作为IBM研究人员,您的任务是编写一个程序,该程序将在给定的DNA片段之间找到共同点,这些片段可以与单个调查信息相关联以识别新的遗传标记。

通过在分子中发现氮碱基的顺序列出DNA碱基序列,可以注意到DNA碱基序列。有四个碱基:腺嘌呤(A),胸腺嘧啶(T),鸟嘌呤(G)和胞嘧啶(C)。6个碱基的DNA序列可以表示为TAGACC。

给定一组DNA碱基序列,请确定出现在所有序列中的最长碱基序列。

Input
该问题的输入将从包含单个整数n的行开始,该整数指示数据集的数量。每个数据集都包含以下数据:

单个正整数m(2 <= m <= 10)指示此数据集中的碱基序列数。
m行,每个行包含一个由60个碱基组成的单个碱基序列。
Output
对于输入中的每个数据集,输出所有给定碱基序列共有的最长碱基子序列。如果最长的公共子序列的长度小于3个碱基,则显示字符串“no significant commonalities”。如果存在多个最长长度相同的子序列,则仅输出按字典序最小的子序列。

Sample Input
3
2
GATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
3
GATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATA
GATACTAGATACTAGATACTAGATACTAAAGGAAAGGGAAAAGGGGAAAAAGGGGGAAAA
GATACCAGATACCAGATACCAGATACCAAAGGAAAGGGAAAAGGGGAAAAAGGGGGAAAA
3
CATCATCATCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
ACATCATCATAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AACATCATCATTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT

Sample Output
no significant commonalities
AGATAC
CATCATCAT

题意:

输 入 m 个 长 度 为 60 的 字 符 串 , 判 断 能 否 在 m 个 串 中 找 出 共 同 的 长 度 大 于 等 于 3 的 子 串 。 输入m个长度为60的字符串,判断能否在m个串中找出共同的长度大于等于3的子串。 m60m3

题解:

暴 力 枚 举 。 暴力枚举。

① 、 把 第 一 个 串 看 作 模 式 串 , 第 一 层 从 60 到 3 枚 举 子 串 的 长 度 k 。 ② 、 第 二 层 枚 举 模 式 串 的 起 点 i 。 截 取 长 度 为 k 的 子 串 t m p 。 ③ 、 对 剩 下 m − 1 个 串 进 行 匹 配 , 匹 配 成 功 的 标 志 是 指 针 j = m + 1 , 把 匹 配 成 功 的 答 案 存 入 a n s 。 同 时 要 注 意 a n s 的 字 典 序 未 必 最 小 , 因 此 要 在 当 前 k 循 环 内 继 续 更 新 。 在 k 的 某 一 趟 循 环 中 , 若 能 匹 配 成 功 , 那 么 这 趟 循 环 结 束 后 必 然 得 出 答 案 。 ④ 、 判 断 能 否 找 到 大 于 等 于 3 的 共 同 子 串 的 标 志 是 a n s 是 否 为 空 。 ①、把第一个串看作模式串,第一层从60到3枚举子串的长度k。\\②、第二层枚举模式串的起点i。截取长度为k的子串tmp。\\③、对剩下m-1个串进行匹配,匹配成功的标志是指针j=m+1,把匹配成功的答案存入ans。\\ \qquad同时要注意ans的字典序未必最小,因此要在当前k循环内继续更新。\\ \qquad在k的某一趟循环中,若能匹配成功,那么这趟循环结束后必然得出答案。\\④、判断能否找到大于等于3的共同子串的标志是ans是否为空。 603kiktmpm1j=m+1ansanskk3ans


代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define ll long long
#define inf 0x7fffffff
using namespace std;
const int M=11;
int T,m;
string s[M];

int main()
{
    cin>>T;
    while(T--)
    {
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
            cin>>s[i];

        string ans="";
        for(int k=60;k>=3;k--)  ///枚举最长长度
        {
            for(int i=0;i+k<=60;i++)  ///枚举模式串的起点
            {
                string tmp=s[1].substr(i,k);
                int j;
                for(j=2;j<=m;j++)   ///枚举剩下的m-1个串
                {
                    if(s[j].find(tmp,0)==-1)
                        break;
                }
                if(j==m+1&&(ans.empty() || ans>tmp )) ///j==m+1则说明以i为起点长度为k的子串与剩下m-1个串都匹配,
                    ans=tmp;   ///这里不能break,还要继续往下找字典序更小的
            }
            if(!ans.empty()) break;   ///非空,说明已经找到,第一次找到的必然是长度最大的
        }

        if(ans.empty()) cout<<"no significant commonalities"<<endl;
        else cout<<ans<<endl;
    }

    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值