#include <iostream>
#include <cassert>
#include <vector>
#include <cctype>
int const ADD_SIZE = 10;
class MyIntSet {
private:
std::pair<int, int> *setTable;
int tableSize;
int tableCapacitySize;
void _initialize();
void _erase(std::pair<int, int> *p);
void _insert(std::pair<int, int> *p, std::pair<int, int>q);
std::pair<int, int> *positionToInsert(int, bool &);
public:
MyIntSet() { this->_initialize(); }
MyIntSet(int beg, int end) {this->_initialize(); this->insert(beg, end); }
~MyIntSet();
void insert(int n);
void insert(int beg, int end);
void erase(int n);
bool isFoundP(int n);
bool isEmptyP();
bool isRegularP();
void dump();
};
/* コンストラクタ共通 */
void MyIntSet::_initialize() {
setTable = nullptr;
tableSize = 0;
tableCapacitySize = 0;
}
/* myVector 要素削除 */
/* 配列の縮小は行わない */
void MyIntSet::_erase(std::pair<int, int> *erase_point) {
assert(erase_point >= setTable && erase_point < &setTable[tableSize]);
std::pair<int, int> *p, *q;
if (tableSize > 0) {
p = erase_point;
q = p + 1;
for (; q != &setTable[tableSize]; p++, q++)
*p = *q;
--tableSize;
if (tableSize == 0) {
delete[] setTable;
setTable = nullptr;
tableCapacitySize = 0;
}
}
}
/* myVector 要素追加 */
void MyIntSet::_insert(std::pair<int, int> *insert_point, std::pair<int, int>insert_value) {
assert((insert_point >= setTable && insert_point <= &setTable[tableSize]) || (insert_point == nullptr && tableCapacitySize == 0));
if (tableSize >= tableCapacitySize) {
/* リサイズ */
tableCapacitySize += ADD_SIZE; tableCapacitySize *= 2;
std::pair<int, int> *setTableNew = new std::pair<int, int>[tableCapacitySize];
std::pair<int, int> *p, *q;
for (p = setTable, q = setTableNew; p != &setTable[tableSize]; p++, q++) {
*q = *p;
}
/* インサート位置のリサイズによる修正 */
if (insert_point == nullptr)
insert_point = setTableNew;
else
insert_point =setTableNew + (insert_point - setTable);
delete[] setTable;
setTable = setTableNew;
}
/* データの移動 */
std::pair<int, int> *p, *q;
if (tableSize > 0) {
p = &setTable[tableSize - 1];
q = &setTable[tableSize];
for (; p >= insert_point; --p, --q)
*q = *p;
}
tableSize++;
*insert_point = insert_value;
}
MyIntSet::~MyIntSet() { delete[] setTable; setTable = nullptr; }
/*
std::pair<int, int> *MyIntSet::positionToInsertObsolete(int n, bool &isInSet) {
std::pair<int, int> *p;
for (p = &this->setTable[0]; p != &this->setTable[tableSize]; p++) {
if (n >= p->first && n <= p->second) {
isInSet = true;
return p;
}
if (n < p->first) {
isInSet = false;
return p;
}
}
isInSet = false;
return p;
}
*/
/*-------------------------------------------------------------------------*/
/* binary-search */
std::pair<int, int> *MyIntSet::positionToInsert(int n, bool &isBelongToSet) {
int s = 0, t = tableSize, h;
if (tableSize == 0) {
isBelongToSet = false;
return setTable;
}
for (;;) {
if (s >= t) {
isBelongToSet = false;
return &setTable[t];
}
h = (s + t) / 2;
if (n >= setTable[h].first && n <= setTable[h].second) {
isBelongToSet = true;
return &setTable[h];
}
if (n < setTable[h].first) {
if ((h > 0 && n > setTable[h - 1].second) || h == 0) {
isBelongToSet = false;
return &setTable[h];
}
t = h;
continue;
}
if (n > setTable[h].second) {
s = h + 1;
continue;
}
std::cout << "positionToInsert(): s = " << s << ", t = " << t << std::endl;
assert(1==0);
}
}
/*-------------------------------------------------------------------------*/
/* 集合に n は含まれるか?*/
bool MyIntSet::isFoundP(int n) {
bool isBelongToMyIntSet;
this->positionToInsert(n, /*ref*/isBelongToMyIntSet);
if (isBelongToMyIntSet) {
return true;
}
return false;
}
/* for デバッグ・ダンプ*/
void MyIntSet::dump() {
std::pair<int, int> *p;
for (p = &this->setTable[0]; p != &this->setTable[tableSize]; p++)
std::cout << p->first << "-" << p->second << ",";
std::cout << std::endl;
}
/* for デバッグ・集合の内部表現が矛盾なく正しいか?*/
bool MyIntSet::isRegularP() {
std::pair<int, int> *p;
bool isRegularReturn = true;
for (p = &this->setTable[0]; p != &this->setTable[tableSize]; p++) {
if (p->first > p->second) {
isRegularReturn = false;
break;
}
if (p != &setTable[0] && p->first <= (p - 1)->second) {
isRegularReturn = false;
break;
}
}
if (isRegularReturn == false) {
this->dump();
}
return isRegularReturn;
}
/* 集合への整数要素の追加 */
void MyIntSet::insert(int n) {
std::pair<int, int> *p;
bool isBelongToMyIntSet;
bool isStored = false;
p = this->positionToInsert(n, /*ref*/isBelongToMyIntSet);
if (isBelongToMyIntSet) {
return;
}
if (p != &setTable[0] && (p - 1)->second == n - 1) {
(p - 1)->second = n;
isStored = true;
}
if (p != &setTable[tableSize] && p->first == n + 1) {
p->first = n;
isStored = true;
}
if (p != &setTable[tableSize] && (p - 1)->second == p->first) {
/* section merging */
(p - 1)->second = p->second;
this->_erase(p);
isStored = true;
}
if (!isStored)
this->_insert(p, std::pair<int, int>(n, n));
}
void MyIntSet::insert(int beg, int end) {
for (int n = beg; n <= end; n++)
this->insert(n);
}
/* 集合への整数要素の削除 */
void MyIntSet::erase(int n) {
std::pair<int, int> *p;
bool isBelongToMyIntSet;
p = this->positionToInsert(n, /*ref*/isBelongToMyIntSet);
if (!isBelongToMyIntSet) return;
if (n == p->first && n == p->second) {
this->_erase(p);
return;
}
if (n == p->first && n < p->second) {
p->first++;
return;
}
if (n == p->second && n > p->first) {
p->second--;
return;
}
/* division */
int q = p->second;
p->second = n - 1;
this->_insert(++p, std::pair<int, int>(n + 1, q));
}
bool MyIntSet::isEmptyP() {
return (this->tableSize == 0);
}
/*-------------------------------------------------*/
int const min = 1;
int const max = 99999;
void anchor_list(std::string str) {
MyIntSet myIntSet;
if (str.find(">>") != 0) return;
std::string::const_iterator p = str.begin(), q;
p++; p++;
for (; p != str.end();) {
if (!isdigit(*p))
break;
q = p;
while (isdigit(*p)) p++;
int n = std::atoi(std::string(q, p).c_str());
if (p == str.end()) {
myIntSet.insert(n);
break;
}
if (*p == ',') {
myIntSet.insert(n);
p++;
continue;
}
if (*p == '-') {
p++;
q = p;
while (isdigit(*p)) p++;
int m = std::atoi(std::string(q, p).c_str());
myIntSet.insert(n, m);
if (*p == ',') {
p++;
continue;
}
break;
}
}
int buf = -1;
std::cout << "[ ";
for (int n = min; n <= max; n++) {
if (myIntSet.isFoundP(n)) {
if (buf != -1) std::cout << buf << ",";
buf = n;
}
}
if (buf != -1)
std::cout << buf;
std::cout << " ]";
}
void f(std::string str) {
std::cout << str << " : ";
anchor_list(str);
std::cout << std::endl;
}
int main() {
f(">>1");
f(">>1-3");
f(">>1,3");
f(">>1-3,5,9-10");
f(">>000000-000000001");
f(">>289494");
f(">>0-2,99998-100000");
f(">>3,0-3,4,5,6,4,2-8");
f(">>1-3,5,9-10");
return 0;
}
/* end */