1 问题描述
碎片字符串:形如aabbaaacaa的字符串,可分为五个相同连续字母组成的碎片:‘aa’,‘bb’,‘aaa’,‘c’,‘aa’,其中每个碎片只出现一次,即该字符串包含’aa’,‘bb’,‘aaa’,'c’四个碎片,且输出时按字典序排序。
输入:aaabbaaacaa 输出:
aa
aaa
bb
c
2 方法
模拟过程,每次把得到子串《字符,个数》放到一个二维数组里,各行按a~z索引,每一列记录子串长(保证不重复存入)
思想:先记录信息到一张表,再从表中取出数据
3 代码
#include <iostream>
#include <vector>
#include<string>
#include<algorithm>
using namespace std;
#define check(c) cout<<c<<endl
//name
typedef int TIMES;//同一个字符出现的次数
typedef pair<int, int> StrInfo;//first 行号 second 出现次数或者长度
class CounterOfstrs
{
public:
CounterOfstrs(){}
CounterOfstrs(string s):m_str(s) {
//test func
}
~CounterOfstrs(){}
void showAns() {
int _Ptr_str=0;
int size = m_str.size();
while (_Ptr_str < size) {
StrInfo _str_info;//放到循环里每次恢复为空
readStrs(_Ptr_str,_str_info);
writeTable(_str_info);
++_Ptr_str;
}
printAns();
}
void readStrs(int &ptr, StrInfo &sInfo) {
char _Now = m_str[ptr];
sInfo.first = _Now - 'a';
sInfo.second = ptr;
while (ptr< m_str.size()&&m_str[ptr] == _Now) {
ptr++;
}
sInfo.second = ptr-sInfo.second;
ptr--;//恢复
}
void writeTable(StrInfo &sInfo) {
int _Row_number = sInfo.first;
int _Str_length = sInfo.second;
bool _Exist = find(m_lengtTable[_Row_number], _Str_length);
if (!_Exist) {
m_lengtTable[_Row_number].push_back(_Str_length);
}
}
bool find(vector<TIMES>& strLens, int len) {
bool _Exist = false;
for (auto x : strLens) {
if (x == len) {
_Exist = true;
break;
}
}
return _Exist;
}
void printAns() {
for (int i = 0; i < 27; i++) {
int _Strlens_size = m_lengtTable[i].size();
if (_Strlens_size != 0) {
sort(m_lengtTable[i].begin(), m_lengtTable[i].end());
for (int j = 0; j < _Strlens_size; j++) {
showStr(i, m_lengtTable[i][j]);
}
}
}
}
void showStr(int rowNumber, int len) {
char _Now = rowNumber+'a';
while (len--) {
printf_s("%c", _Now);
}
printf_s("\n");
}
private:
vector<TIMES> m_lengtTable[27];
string m_str;
};
int main() {
CounterOfstrs ctest("aaasssbbbaassabbs");
ctest.showAns();
system("pause");
return 0;
}
法二
借助数组set的元素唯一性,将所有的子串加入到一个set中,(默认字典序)最后输出结果
#include<iostream>
#include<set>
#include<string>
using namespace std;
int main() {
//data
set<string> set_str;
string str = "";
//input
cin >> str;
//exe
for (int i = 0; i < str.length(); i++) {
string temp = "";
temp += str[i];
while (i < str.length()&&str[i] == str[i + 1]) {
temp += str[i++];
}
set_str.insert(temp);//这一步是核心,将重复子串删除
}
//output
for(string s: set_str) {
cout << s << endl;
}
return 0;
}