題目描述:
輸入一個字符串(不含空格), 請尋找輸入中包含所有蛇形字符串。
蛇形字符串定義:
1.蛇形字符串由連續字符對組成,其特點如下:
1.1 字符對定義:字符對由同一字母的大寫和小寫組成(前大后小)。如:Aa,Dd;
1.2 蛇形字符串中包含的字符對,必須是連續字母,並按照字母順序排序。如:AaBbCc或OoPpQqRrSs;
2.從輸入中尋找字符組成蛇形字符串(字符順序不限),符合規則:
2.1 每次尋找必須是最長的蛇形字符串;
2.2 使用過的字符不能重復使用;
例: 輸入SxxsrR^AaSs
正確過程:
Step1:SxxsrR^AaSs -> RrSs (找到兩對連續字符對:Ss、Rr,可以組成蛇形字符串。另,Ss后應該是Tt,但當前字符串SxxsrR^AaSs中不包含,所以當前蛇形字符串到Ss結束。本輪查找結果是RrSs。)
Step2:xs^AaSs -> Aa
Step3:xx^Ss -> Ss
……(省略其他錯誤說明)
輸入描述:
一個字符串(不含空格,字符串長度<=5000)
輸出描述:
- 所有包含的蛇形字符串,按首字母升序排列(即A在Z前);(這里和前面2.1中“每次尋找必須是最長的蛇形字符串”沖突!)
- 同一個首字母的情況,按照蛇形字符串長度升序輸出;
- 如果沒有找到,輸出Not Found。
示例1:
輸入:SwSE$3454356DD$$E#eswsxxsssAAWDxxdderfvcRFER65645hbg^%%UnbnvccTRChnyvcxcvVCFR
輸出:
(下面這個輸出是題目給出的,但事實上和上面說的矛盾,是錯誤的!)
(這里我先按照上面的編寫了很久,結果用這個案例自測一直錯誤;后來改成能輸出下面結果的代碼,即不管長度按照首字母順序輸出,這能夠通過自測,提交之后能夠通過60%的案列;然后很暴躁地重讀題目,發現這個bug,就修改回原先的方法,並優化了代碼,這才通過所有測試案例……因為這么小的系統bug,真的是耗神又耗時啊……)
CcDdEeFf
CcDdEe
RrSs
Ss
VvWw
(下面這個輸出才是符合前面所說,是正確的)
CcDdEeFf
CcDdEe
RrSs
VvWw
Ss
1.思考
- 首先想到利用ASCII碼來簡化操作,這樣所有的記錄都可以用“a”+數字進行;
- 先定義一個26長度的vector <int> mp來計數Aa這樣的有幾個,每次找到並計數,再從str中刪除;
- 然后調用自己編寫的FindS()函數,來找到最長的蛇形字符串,用res來記錄字符串開始和結束的位置,最后輸出,輸出的時候要在mp計數的對應位置-1;
- 如果存在蛇形字符串,則反復調用FindS()函數,直到所有蛇形字符串都輸出;
- 如果FindS()函數沒有找到蛇形字符串,則輸出Not Found。
2.實現
- 這里一方面也因為自己太急躁沒有完全讀清楚題意,另一方面因為自己被之前不知名的Bug折騰的沒有底,再加之時間一點點耗盡,所以耗費時間超級長;
- 進度差不多是這樣的:半小時左右完成代碼編寫,之后40min左右一直在dubug。導致最后完成這道題之后只剩下20min左右了……
- 遇事一定不能慌!心態還是不行,有待提升!
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
bool FindS(vector<char>& str, vector<int>& mp)
{
int count = 0, mxs = 0, i = 0, j = 0;
vector<int> range(2);
bool flag = false;
while (i < 26){
if (mp[i]>0){
count = 1;
j = i + 1;
while (j < 26 && mp[j]>0){
count++;
j++;
}
if (count > mxs){
flag = true;
mxs = count;
range[0] = i;
range[1] = j - 1;
}
i = j + 1;
}
else{
i++;
}
}
if (flag == false)
return false;
vector<char> res;
for (int i = range[0]; i <= range[1]; i++){
res.push_back('A' + i);
res.push_back('a' + i);
mp[i]--;
}
int lres = res.size();
for (int i = 0; i < lres; i++){
if (i < lres - 1){
cout << res[i];
}
else{
cout << res[i] << endl;
}
}
return true;
}
int main(){
string input;
vector<char> str;
while (getline(cin, input)){
str.clear();
vector<int> mp(26, 0);
for (auto in : input){
str.push_back(in);
}
/* //So complicated
int posa, posA;
for (int i = 0; i < 26; i++){
auto pA = find(str.begin(), str.end(), 'A' + i);
auto pa = find(str.begin(), str.end(), 'a' + i);
while (pa != str.end() && pA != str.end()){
posa = pa - str.begin();
posA = pA - str.begin();
str.erase(str.begin() + max(posa, posA));
str.erase(str.begin() + min(posa, posA));
mp[i]++;
pA = find(str.begin(), str.end(), 'A' + i);
pa = find(str.begin(), str.end(), 'a' + i);
}
}*/
//Optimize mp
int len = str.size(), ai, Ai;
vector<int> ma(26, 0), mA(26, 0);
for (int i = 0; i < len; i++){
ai = str[i] - 'a';
if (ai >= 0 && ai < 26){
ma[ai]++;
continue;
}
Ai = str[i] - 'A';
if (Ai >= 0 && Ai < 26){
mA[Ai]++;
}
}
for (int i = 0; i < 26; i++){
mp[i] = min(ma[i], mA[i]);
}
//FindSnake
bool flag = false;
while (1){
if (FindS(str, mp) == false){
break;
}
else{
flag = true;
}
}
if (flag == false){
cout << "Not Found" << endl;
}
}
return 0;
}