Սկիզբ » Ուսումնական նյութեր » Ծրագրավորում » ՈՒղղանկյուն դասի իրականացումը (մի հարցազրույցից)

ՈՒղղանկյուն դասի իրականացումը (մի հարցազրույցից)

| Սեպտեմբեր 26, 2012 | 3 Մեկնաբանություններ |

Ֆիրմաներից մեկում հարցազրույցի էի: Ինձ տվեցին բոլոր տափակ հարցերը. էլ պոլիմորֆիզմ, էլ ալգորիթմի բարդություն, էլ STL-ի կոնտեյներ: Մի խոսքով, այն ամենը, ինչից հնարավոր չէ որևէ եզրակացություն անել հարցվողի պատրաստվածության մասին: Ես լուրջ դեմք ընդունած համառորեն տալիս էի դասագրքային պատասխաններ, նրանք էլ լուրջ դեմքով լսում էին տափակ հարցերի տափակ պատասխանները:

Վերջում, որպես իմ կոդ գրելու ունակությունները վերջնականորեն ստուգելու եղանակ, հանձնարարվեց իրականացնել “ուղղանկյուն” դասը և նրանում իրականացնել երկու ուղղանկյունների հատումը ստուգող մեթոդ: Չդիմացա գայթակղությանը և որոշեցի գրել ամենաթիթիզ ձևերով:

Ստորև ներկայացնում եմ իմ կոդը.


Դասի սահմանման rectangle.h ֆայլը:

/** @file rectangle.h */

#ifndef RECTANGLE_H
#define RECTANGLE_H

/** 
 * @brief Point in cartesian coordinate system.
 */
class Point {
public:
    double x;
    double y;

public:
    Point() : x(0.0), y(0.0) {}
    Point(double cx, double cy) : x(cx), y(cy) {}
    Point(const Point& p) : x(p.x), y(p.y) {}
};

/** @brief Equality of two @c Points. */
bool operator==(const Point& p0, const Point& p1);

/** @brief Compare two @c Points. 
 *
 * Returns @c true, if @code p0.x < p1.x @endcode and
 * @code p0.y < p1.y @endcode.
 */
bool operator<(const Point& p0, const Point& p1);

/**
 * @brief Rectangle in cartesian plane.  
 *
 * Rectangle is represented in plane with two points: @c origin and @c corner.
 */
class Rectangle {
private:
    /// @brief bottom left coordinate 
    Point ori;
    /// @brief top right coordinate
    Point cor;

public:
    /** @brief Default constructor.
     *
     * This constructor creates "zero" rectangle, where
     * @c origin=(0,0) and @c corner=(0,0).
     */
    Rectangle();

    /** @brief Copy constructor */
    Rectangle(const Rectangle& rec);

    /** @brief Basic constructor. 
     *
     * @param o the @c origin of rectangle,
     * @param c the @c corner of rectangle
     */
    Rectangle(const Point& o, const Point& c);

    inline Point origin() const { return ori; }
    inline Point corner() const { return cor; }

    inline double area() const { return (cor.x - ori.x) * (cor.y - ori.y); }
    inline double perimter() const { return 2 * (cor.x - ori.x) + 2 * (cor.y - ori.y); }

    /**
     * @brief Intersection of two Rectangles.
     *
     * If @c this overlaps @c rec then this function constructs
     * and returns overlapping area as a new @c Rectangle object,
     * otherwise it returnd "zero" rectangle.
     *
     * @param rec Rectangle to intersect with current object.
     *
     * @returns Overlapping area an a new Rectangle.
     */
    Rectangle intersect(const Rectangle& rec);

private:
    /**
     * @brief Checks mutial positioning of @c origin and @c corner.
     * 
     * If @c origin is not in left side and below of @c corner, then 
     * this function swaps @c origin and @c corner.
     */
    void checkAndCorrect();
};

/** @brief comparison operator for two @c Rectangles. */
bool operator==(const Rectangle& r0, const Rectangle& r1);

#endif//RECTANGLE_H

Դասի իրականացմանա rectangle.cpp ֆայլը:

/** @file rectangle.cpp */

#include <algorithm>

#include "rectangle.h"

/**/
bool operator==(const Point& p0, const Point& p1)
{
    return (p0.x == p1.x) && (p0.y == p1.y);
}

/**/
bool operator<(const Point& p0, const Point& p1)
{
    return (p0.x < p1.x) && (p0.y < p1.y);
}

/**/
Rectangle::Rectangle()
    : ori(Point()), cor(Point())
{
    checkAndCorrect();
}

/**/
Rectangle::Rectangle(const Rectangle& rec)
    : ori(rec.ori), cor(rec.cor)
{}

/**/
Rectangle::Rectangle(const Point& o, const Point& c)
    : ori(o), cor(c)
{
    checkAndCorrect();
}

/**/
Rectangle Rectangle::intersect(const Rectangle& rec)
{
    double left = std::max(rec.origin().x, ori.x);
    double bottom = std::max(rec.origin().y, ori.y);
    Point small(left, bottom);

    double right = std::min(rec.corner().x, cor.x);
    double top = std::min(rec.corner().y, cor.y);
    Point large(right, top);

    if( small < large )
        return Rectangle(small, large);
    return Rectangle();
}

/**/
void Rectangle::checkAndCorrect()
{
    if( ori < cor ) return;
    Point temp(cor);
    cor = ori;
    ori = temp;
}

/**/
bool operator==(const Rectangle& r0, const Rectangle& r1)
{
    return (r0.origin() == r1.origin()) && (r0.corner() == r1.corner());
}

Դասը ստուգող տեստերի utests.cpp ֆայլը:

#include <iostream>

#include "rectangle.h"

/**/
void print(const Point& p)
{
    std::cout << "<" << p.x << ", " << p.y << ">";
}

/**/
void print(const Rectangle& r)
{
    std::cout << "[";
    print(r.origin());
    std::cout << "; ";
    print(r.corner());
    std::cout << "]" << std::endl;
}

#define CHECK(e) std::cout << (e ? "PASS" : "FAIL") << " --> " << #e << std::endl;

/*
This test checks Point objects construction 
and assignment one to another. 
*/
void testPoint()
{
    Point p0;
CHECK(p0 == Point(0.0,0));

    Point p1(1.2, 3.4);
CHECK(p1 == Point(1.2,3.4));

    Point p2(Point(5.6, 7.8));
CHECK(Point(5.6,7.8) == p2);

    Point p3 = p1;
CHECK(p3 == Point(1.2,3.4));
}

#define REC(a,b,c,d) Rectangle(Point(a,b),Point(c,d))

/*
First, this test checks Rectangle object construction.

Then, it checks overlaping of two rectangles. The schematics below
show test cases.

           +-----------------+
           |r14              |
           |                 |
           +-----------------+

     +---------+         +-----------+
     |r5       |         |         r7|
     |     +---|---------|---+       |   +-----+
     |     |   |         |   |       |   |     |
     +---------+         +-----------+   |     |
           |      +----+     |           |     |
           |  r3  | r16|     |           |     |
           |      +----+     |           |     |
     +---------+         +-----------+   |     |
     |     |   |         |   |       |   | r12 |
     |     +-------------|---+       |   +-----+
     | r4      |         |        r6 |
     +---------+         +-----------+

r3 is intersected with r4, r5, r6, r7, r12, r14, r16
*/
void testRectangle()
{
    Rectangle r0;
    Rectangle r1(Point(2,2), Point(7,7));
    Rectangle r1a(Point(7,7), Point(2,2));
CHECK(r1 == r1a);
    Rectangle r2(r1);

    Rectangle r3(Point(5,2), Point(10,5));
    Rectangle r4(Point(3,1), Point(6,3));
    Rectangle r5(Point(3,4), Point(6,6));
    Rectangle r6(Point(8,1), Point(12,3));
    Rectangle r7(Point(8,4), Point(12,6));

    Rectangle r8 = r3.intersect(r4);
CHECK(r8 == REC(5,2,6,3));
    Rectangle r9 = r3.intersect(r5);
CHECK(r9 == REC(5,4,6,5));
    Rectangle r10 = r3.intersect(r6);
CHECK(r10 == REC(8,2,10,3));
    Rectangle r11 = r3.intersect(r7);
CHECK(r11 == REC(8,4,10,5));

    Rectangle r12(Point(13,2), Point(15,4));
    Rectangle r13 = r3.intersect(r12);
CHECK(r13 == REC(0,0,0,0));

    Rectangle r14(Point(5,8), Point(10,14));
    Rectangle r15 = r3.intersect(r14);
CHECK(r15 == Rectangle());

    Rectangle r16(Point(7,3), Point(8,4));
    Rectangle r17 = r3.intersect(r16);
CHECK(r17 == r16);
}

/**/
int main(int argc, char* argv[])
{
    testPoint();

    testRectangle();

    return 0;
}

Կատարվող մոդուլի կառուցման Makefile ֆայլը:

all:

debug:
g++ -g rectangle.cpp utests.cpp -o rectangle

cover:
g++ -g -fprofile-arcs -ftest-coverage rectangle.cpp utests.cpp -o rectangle
./rectangle
gcov rectangle.cpp

run:
./rectangle

doc:
doxygen *.h *.cpp

clean:
rm -f *.gcov *.gcda *.gcno
rm -f rectangle

Հանուն արդարության պետք է նշեմ, որ Rectangle դասի intersect մեթոդը թխած է Smalltalk լեզվի գրաֆիկական պրիմիտիվների Rectangle դասից:

intersect: aRectangle
  | aPoint left right top bottom |
  aPoint := aRectangle origin.
  aPoint x > origin x ifTrue:[left := aPoint x] ifFalse:[left := origin x].
  aPoint y > origin y ifTrue:[top := aPoint y] ifFalse:[top := origin y].
  aPoint := aRectangle corner.
  aPoint x < corner x ifTrue:[right := aPoint x] ifFalse:[right := corner x].
  aPoint y < corner y ifTrue:[bottom := aPoint y] ifFalse:[bottom := corner y].
  ^Rectangle
    origin: (left@top)
    corner: (right@bottom)

  

ՈՒղղանկյուն դասի իրականացումը (մի հարցազրույցից), 9.9 out of 10 based on 7 ratings

Նշագրեր: , , , ,

Բաժին: Ծրագրավորում, Ուսումնական նյութեր

Կիսվել , տարածել , պահպանել

VN:F [1.9.20_1166]
Rating: 9.9/10 (7 votes cast)

Մեկնաբանություններ (3)

Թրեքբեք հղում | Մեկնաբանությունների RSS ժապավեն

  1. Արթուր says:

    Իմ իմացած տեղերից մենակ ԵՊՀ ում ա որ C++ համարվումա “աստվածների” լեզու, կարևոր չէ թե այլ ինչ լեզուների ու հմտությունների ես տիրապետում ։(
    Ու որպես կանոն, քննություն առնողները հենց ԵՊՀ ից են,քննությունը “հաջող” հանձնողները նույնպես․․ Ես ԴԵՄ չեմ․․․բայց պետք ա առաջ շարժվել․․․ Մենակ քառակուսիներից ու շրջաններից բացի կան այլ հետաքրքիր բաներ։

    +1 Windows չօգտագործելու համար․․․

    • armenbadal says:

      Ցավոք ԵՊՀ-ն արդեն այն մակարդակում չէ, որտեղ կպատրաստվեին C++ որակյալ մասնագետներ։ Իսկ շուկայում այսօր կա նրանց պահանջարկը։ Ես ինքն իմ աշխատանքում օգտագործում եմ 5-6 տարբեր լեզուներ։ Ստացվել է այնպես, որ դրանցից հիմնականը C++-ն է։ Կոնկրետ աշխատանքի համար, որն ունի կոնկրետ պահանջարկ, այդ լեզվի ընտրությունն արդարացված է։

      Հիմնական աշխատանքներն անում եմ Windows 7 համակարգում։ Այն օգտագործում եմ ամեն օր, որովհետև աշխատատեղում այն ամենալավ հարմարեցվածն է։

  2. Gayane says:

    Armen du demq es !!!!!!
    Es vonc vor te krahum em te ed vor firmayum unecats qo interviewn a qez stipel es patmutyun@ grel 😉

    mek el kneres vor hayeren chem grum 🙂

Մեկնաբանեք

Կհաստատվեն միայն մեսրոպատառ հայերենով գրած մեկնաբանությունները

298