°ú¸ñ: | Programming Language |
±³¼ö: | ÇÑ»ó¿µ |
Á¦ÃâÀÏ: | 29-Sep-97 |
Á¦ÃâÀÚ: | ±è±â¿ë, 93208-002, Áö¸®Çаú |
while (tuple ÀÌ Á¸ÀçÇÏ´Â µ¿¾È) { skyline += tuple; }
while ((ch = getchar()) != EOF) { tuple.AddChar(ch); if (tuple.IsValid()) { skyline += tuple; tuple.Clear(); } }
// // SkyLine.h // #define MAXCHAR 256 #define max(a, b) ((a) > (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b)) // enum BOOL { FALSE, TRUE }; typedef int BOOL; class CoordNode { public: double x, y; CoordNode *next; CoordNode() { x = 0; y = 0; next = NULL; } CoordNode(double sx, double sy) { x = sx; y = sy; next = NULL; } void DeleteNextNode(); }; class Tuple { protected: char str[MAXCHAR]; int cur; BOOL bValid; BOOL bComment; BOOL isUseful(char ch); void verify(); public: double x1, y, x2; Tuple(); BOOL AddChar(char ch); BOOL IsValid() { return bValid; } void Clear() { cur = 0; bValid = FALSE; bComment = FALSE; } void Print(); }; class SkyLine { protected: CoordNode *insert(CoordNode *pNode); void compact(); void pullHeight(Tuple &t); public: CoordNode coordHead; SkyLine() {} ~SkyLine(); SkyLine &operator +=(Tuple &t); void Print(); }; class Exception { public: enum ErrType { NoError, ErrNoSpace, ErrTooLongTuple, ErrInvalidFormat } err; void *param; Exception() { err = NoError; param = NULL; } Exception(ErrType etype, void *p) { err = etype; param = p; } BOOL Handle(); };
// // SkyLine.cpp // #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include "SkyLine.h" void CoordNode::DeleteNextNode() { CoordNode *pFree; pFree = next; if (!pFree) return; next = pFree->next; delete pFree; } Tuple::Tuple() { x1 = 0; x2 = 0; y = 0; cur = 0; bValid = FALSE; str[MAXCHAR-1] = '\0'; bComment = FALSE; } BOOL Tuple::isUseful(char ch) { if (!bComment && ch == '#') { bComment = TRUE; return FALSE; } if (bComment) { if (ch == '\n') bComment = FALSE; return FALSE; } if (isdigit(ch) || ch == '.' || ch == '+' || ch == '-') return TRUE; if (ch == '(' || ch == ',' || ch == ')') return TRUE; return FALSE; } void Tuple::verify() { int nGet; nGet = sscanf(str, "(%lf,%lf,%lf)", &x1, &y, &x2); bValid = (nGet == 3) ? TRUE : FALSE; if (!bValid) { Exception e(Exception::ErrInvalidFormat, this); throw e; } } BOOL Tuple::AddChar(char ch) { if (!isUseful(ch)) return FALSE; str[cur++] = ch; if (ch == ')') { str[cur] = '\0'; verify(); return TRUE; } if (cur >= MAXCHAR - 2) { Exception e(Exception::ErrTooLongTuple, this); throw e; } return FALSE; } void Tuple::Print() { str[cur] = '\0'; printf("%s", str); } SkyLine::~SkyLine() { while (coordHead.next) { coordHead.DeleteNextNode(); } } SkyLine &SkyLine::operator +=(Tuple &t) { CoordNode *pLeft, *pRight, *pPrev; pLeft = new CoordNode(t.x1, t.y); pRight = new CoordNode(t.x2, 0); if (!pLeft || !pRight) { Exception e(Exception::ErrNoSpace, NULL); throw e; } pPrev = insert(pRight); if (pRight->y < pPrev->y) { pRight->y = pPrev->y; } pPrev = insert(pLeft); if (pLeft->y < pPrev->y) { pLeft->y = pPrev->y; } pullHeight(t); compact(); return *this; } CoordNode *SkyLine::insert(CoordNode *pNode) { CoordNode *pPrev = &coordHead; while (pPrev->next) { if (pPrev->next->x >= pNode->x) { break; } pPrev = pPrev->next; } pNode->next = pPrev->next; pPrev->next = pNode; return pPrev; } void SkyLine::pullHeight(Tuple &t) { CoordNode *pNode = coordHead.next; while (pNode) { if (pNode->x >= t.x2) return; if (pNode->x > t.x1 && pNode->y < t.y) pNode->y = t.y; pNode = pNode->next; } } void SkyLine::compact() { CoordNode *pNode = coordHead.next; while (pNode) { if (!pNode->next) break; if (pNode->x == pNode->next->x) { pNode->y = max(pNode->y, pNode->next->y); pNode->DeleteNextNode(); continue; } if (pNode->y == pNode->next->y) { pNode->x = min(pNode->x, pNode->next->x); pNode->DeleteNextNode(); continue; } pNode = pNode->next; } } void PrintDouble(double num) { static const int MAXDECIMAL = 6; if ((double)(int)num == num) { printf("%d", (int)num); return; } int n; int m; double mul; for (n = 1, m = 10; n < MAXDECIMAL; n++, m *= 10) { mul = num * m; if ((double)(int)mul == mul) { break; } } printf("%.*f", n, num); } void SkyLine::Print() { CoordNode *pNode = coordHead.next; while (pNode) { putchar('('); PrintDouble(pNode->x); putchar(','); PrintDouble(pNode->y); putchar(')'); pNode = pNode->next; } putchar('\n'); } BOOL Exception::Handle() { switch (err) { case ErrInvalidFormat: printf("%s", "Error: Invalid tuple input:\n"); ((Tuple *)param)->Print(); putchar('\n'); return TRUE; case ErrTooLongTuple: printf("%s", "Error: Too long tuple input:\n"); ((Tuple *)param)->Print(); putchar('\n'); return TRUE; case ErrNoSpace: printf("%s", "Error: Memory allocation failed.\n"); return TRUE; default: return FALSE; } } int main(void) { int ch; Tuple tuple; SkyLine skyline; while ((ch = getchar()) != EOF) { try { tuple.AddChar(ch); if (tuple.IsValid()) { skyline += tuple; tuple.Clear(); } } catch (Exception e) { e.Handle(); exit(1); } } skyline.Print(); return 0; }