Началось с того, что смотрел вакансии на одном сайте. Увиденная задачка заинтересовала и заставила вспомнить былое. Вакансия, к слову, из ДС. Стало интересно, насколько мои высушенные мозги годятся для дела в нормальных конторах.
Есть последовательность идентификаторов, строящаяся по особым правилам:
1. Первый идентификатор последовательности имеет вид «A1». Второй - «A2», третий - «A3» и так далее.
За «A9» следующий - «B1». Следующий после «Z9» имеет вид «A1-A1», потом «A1-A2» и так далее.
После «A1-Z9» следующим идет «A2-A1».
2. Максимальная длина идентификатора - десять групп по два символа.
3. В идентификаторах никогда не должны присутствовать буквы «D», «F», «G», «J», «M», «Q», «V», и цифра «0».
Нужно: на C++ написать библиотечный класс, предназначенный для использования другими программистами.
Функция должна получать в качестве входного параметра строку с идентификатором из описанной последовательности, и генерировать на выходе строку, содержащую следующий идентификатор последовательности.
Например, функция получает «A1-Z9» и возвращает «A2-A1».
Вот моя реализация, хочу услышать здравую критику грамотного народа. Судя по наблюдениям, здесь такой встречается.
main.cpp
#include <iostream>
#include <cstring>
#include "cmeganumber.h"
using namespace std;
int main(int argc, char** argv)
{
CMegaNumber t;
t = "C9-Z9-Z9-Z9-Z9-Z9-Z9-Z9-Z9-Z9";
cout << "baseval = " << t.szvalue() << endl;
cout << "newval = " << (++t).szvalue() << ", overflow = " << t.m_bOverflow << endl;
return 0;
}
cmeganumber.h
#ifndef CMEGANUMBER_H_INCLUDED
#define CMEGANUMBER_H_INCLUDED
class CMegaNumber
{
private:
char m_lpszValue[30];
bool m_bAssigned;
public:
bool m_bOverflow;
CMegaNumber();
CMegaNumber& operator=(const char * lpszValue);
CMegaNumber& operator++();
char * szvalue() { return m_lpszValue; };
};
#endif // CMEGANUMBER_H_INCLUDED
cmeganumber.cpp
#include <cstring>
#include "cmeganumber.h"
// CMegaNumber implementation
/* constructor
*/
CMegaNumber::CMegaNumber()
{
m_bOverflow = false;
m_bAssigned = false;
memset(m_lpszValue, 0, 30);
}
/* assignment operator overload
*/
CMegaNumber& CMegaNumber::operator=(const char * lpszValue)
{
if(30 <= strlen(lpszValue))
{
strcpy(m_lpszValue, "err-too-long");
m_bAssigned = false;
return *this;
}
strcpy(m_lpszValue, lpszValue);
m_bAssigned = true;
return *this;
}
/* pre-increment operator overload
*/
CMegaNumber& CMegaNumber::operator++()
{
if(!m_bAssigned)
{
strcpy(m_lpszValue, "err-not-assigned");
return *this;
}
bool bIncHigh = false;
char * p = m_lpszValue + strlen(m_lpszValue) - 1;
*p == '9' ? *p = '1', bIncHigh = true : (*p)++;
p--;
if(bIncHigh)
while(p >= m_lpszValue && bIncHigh)
{
switch(((unsigned long)p - (unsigned long)m_lpszValue) % 3)
{
case 1:
*p == '9' && bIncHigh ? *p = '1' : ((*p)++, bIncHigh = false);
break;
case 0:
*p == 'Z' && bIncHigh ? *p = 'A' : ((*p)++, bIncHigh = false);
while(*p == 'D' ||
*p == 'F' ||
*p == 'G' ||
*p == 'J' ||
*p == 'M' ||
*p == 'Q' ||
*p == 'V') (*p)++;
break;
case 2:;
}
p--;
}
m_bOverflow = bIncHigh;
return *this;
}