zoukankan      html  css  js  c++  java
  • 终曲[HDU-2572]

    终曲 HDU - 2572  时间限制1000ms 内存限制128MB

    问题大意:

    给定三个字符串s,s1,s2,要求求出s中包含s1s2的最短子串。

    这道题我是用了分两步的方法去做的。首先求出$s$中包括$s_1$和$s_2$的子串,然后输出其最短的。我这里直接使用了标准库的string类的find()方法,依次查找到$s_1$和$s_2$的起始位置为$p_1$、$p_2$,那么事实上就可以确定一个子串了($s_1[min(p_1,p_2)..(max(p_1,p_2)+len)]$,其中$len$是$s_1$,$s_2$中出现在后面的串的长度)。这里有一点需要注意的是,这种方法并不能完全确定所有的子串,因为假如在$p_2$之后同样出现了和$s_2$相同的串,则从$p_1$到$p_3+length$同样也是$s_2$的子串。如果要求出所有的子串,就应该使用双指针查找的方式。好在题目要求只需要输出其最短的,而$p_3>max(p_1,p_2)$显然成立,因此这些串显然更长,不符合要求,自然可以排除掉。这样求出一个子串之后,把他放进优先队列pq里,而后将s利用substr()方法进行截取(从$min(p_1,p_2)$之后到原字符串末尾),再进行如此迭代操作,直到找不到目标子串为止。这样输出优先队列的top元素即为答案。当然这里利用vector容器然后调用sort()函数也是可以的。更简洁的做法,便是每捕捉到一个子串就进行比较,保留其中最短的。

    主要需要提及一下,priority_queue容器需要指定比较大小的方式,对于有特殊比较需求,应该重载类的比较运算符<或者自定义一个仿函数。在C++ STL中,仿函数就是一个类(或者结构体),重载了其“()”运算符,使之看起来更像一个函数调用。这里就自定义了一个仿函数mylesscmp,用来对子串进行比较,以便于输出。如果不自定义这个仿函数,他会自动调用stringoperator<进行比较,与题目要求就不一致了。

     1 #include<iostream>
     2 #include<string>
     3 #include<queue>
     4 #include<algorithm>
     5 using namespace std;
     6 struct mylesscmp
     7 {
     8     bool operator() (string a, string b)
     9     {
    10         if (a.length() < b.length())
    11             return false;
    12         if (a.length() > b.length())
    13             return true;
    14         else
    15             return (a > b);
    16     }
    17 };
    18 int main()
    19 {
    20     string src, sub1, sub2;
    21     int T;
    22     cin >> T;
    23     while (T--)
    24     {
    25         priority_queue<string, vector<string>, mylesscmp> pq;
    26         cin >> src >> sub1 >> sub2;
    27         int pos1, pos2;
    28         while (1)
    29         {
    30             pos1 = src.find(sub1, 0);
    31             pos2 = src.find(sub2, 0);
    32             if (pos1 == -1 || pos2 == -1)
    33                 break;
    34             int mn, len;
    35             if (pos1 > pos2)
    36             {
    37                 mn = pos2;
    38                 len = pos1 - pos2 + sub1.length();
    39             }
    40             else
    41             {
    42                 mn = pos1;
    43                 len = pos2 - pos1 + sub2.length();
    44             }
    45             pq.push(src.substr(mn, len));
    46             src = src.substr(mn + 1, src.length() - mn - 1);
    47         }
    48         if (pq.empty())
    49             cout << "No" << endl;
    50         else
    51             cout << pq.top() << endl;
    52     }
    53     return 0;
    54 }

     

  • 相关阅读:
    模块之datetime
    模块之time模块
    模块之相对路径导入
    模块之包跨模块导入
    模块
    迭代器
    leetcode234 回文链表(Easy,不简单)
    leetcode543 二叉树的直径(Easy 不简单)
    leetcode538 把二叉树转换为累加树(Easy,不简单)
    leetcode136 只出现一次的数字(Easy)
  • 原文地址:https://www.cnblogs.com/ggggg63/p/6715539.html
Copyright © 2011-2022 走看看