终曲[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 }

 

 

 

 

 

 

 

 

 

 

posted @ 2017-04-15 20:39  g63  阅读(260)  评论(0编辑  收藏  举报