seminar2
This commit is contained in:
parent
46d1c64684
commit
ab6732eded
98 changed files with 10319 additions and 0 deletions
38
seminar02_encapsulation/homework/code/0circle/circle.cpp
Normal file
38
seminar02_encapsulation/homework/code/0circle/circle.cpp
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#include <iostream>
|
||||
#include <math.h>
|
||||
#include "circle.h"
|
||||
#include "point.h"
|
||||
|
||||
Circle::Circle(const Point& acenter, float aradius) {
|
||||
mCenter = acenter;
|
||||
mRadius = aradius;
|
||||
}
|
||||
Circle::Circle() {
|
||||
mCenter = Point {0, 0};
|
||||
mRadius = 1;
|
||||
}
|
||||
Circle::Circle(const Circle& circle) {
|
||||
mCenter = circle.mCenter;
|
||||
mRadius = circle.mRadius;
|
||||
}
|
||||
Point Circle::getCenter() const { return mCenter; }
|
||||
float Circle::getRadius() const { return mRadius; }
|
||||
|
||||
void Circle::setCenter(const Point& p) {
|
||||
mCenter = p;
|
||||
}
|
||||
void Circle::setRadius(float radius) {
|
||||
mRadius = radius > 0 ? radius : 0;
|
||||
}
|
||||
float Circle::getArea() const {
|
||||
return mRadius * mRadius * M_PI;
|
||||
}
|
||||
float Circle::getDistance(const Point& p) {
|
||||
return mCenter.distance(p) - mRadius;
|
||||
}
|
||||
bool Circle::isColliding(const Circle& c) const {
|
||||
return (mCenter.distance(c.getCenter()) - (mRadius + c.getRadius()) > 0) ? false : true;
|
||||
}
|
||||
void Circle::move(const Point& p) {
|
||||
mCenter = mCenter + p;
|
||||
}
|
||||
23
seminar02_encapsulation/homework/code/0circle/circle.h
Normal file
23
seminar02_encapsulation/homework/code/0circle/circle.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#include "point.h"
|
||||
class Circle
|
||||
{
|
||||
private:
|
||||
Point mCenter;
|
||||
float mRadius;
|
||||
|
||||
public:
|
||||
Circle(const Point& acenter, float aradius);
|
||||
Circle();
|
||||
Circle(const Circle& circle);
|
||||
Point getCenter() const;
|
||||
float getRadius() const;
|
||||
|
||||
void setCenter(const Point& p);
|
||||
void setRadius(float radius);
|
||||
float getArea() const;
|
||||
float getDistance(const Point& p);
|
||||
bool isColliding(const Circle& c) const;
|
||||
void move(const Point& p);
|
||||
};
|
||||
|
||||
|
||||
44
seminar02_encapsulation/homework/code/0circle/main.cpp
Normal file
44
seminar02_encapsulation/homework/code/0circle/main.cpp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#include <iostream>
|
||||
#include "point.h"
|
||||
#include "circle.h"
|
||||
|
||||
using std::cout, std::endl;
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
Point p = {7, -1};
|
||||
Point q = {-4, 2};
|
||||
cout << "Point p = " << p << endl;
|
||||
cout << "Point q = " << q << endl;
|
||||
cout << "p + q = " << p + q << endl;
|
||||
|
||||
|
||||
Circle a {{4, 1}, 3};
|
||||
Circle b;
|
||||
// b = a;
|
||||
|
||||
cout << "Circle a: center: " << a.getCenter() << " radius: " << a.getRadius() << endl;
|
||||
cout << "Circle b: center: " << b.getCenter() << " radius: " << b.getRadius() << endl;
|
||||
|
||||
cout << "Area of a = " << a.getArea() << endl;
|
||||
cout << "Distance from point p to circle a = " << a.getDistance(p) << endl;
|
||||
|
||||
|
||||
|
||||
cout << "Collisions:" << endl;
|
||||
if (a.isColliding(b))
|
||||
cout << "Yes, a is colliding b" << endl;
|
||||
else
|
||||
cout << "No, a isn't colliding b" << endl;
|
||||
|
||||
|
||||
|
||||
cout << "Moving b by {1, 1}:" << endl;
|
||||
b.move({1, 1});
|
||||
if (a.isColliding(b))
|
||||
cout << "Yes, a is colliding b" << endl;
|
||||
else
|
||||
cout << "No, a isn't colliding b" << endl;
|
||||
|
||||
}
|
||||
82
seminar02_encapsulation/homework/code/0circle/point.cpp
Normal file
82
seminar02_encapsulation/homework/code/0circle/point.cpp
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
#include "point.h"
|
||||
|
||||
|
||||
Point::Point(float x, float y)
|
||||
{
|
||||
mx = x;
|
||||
my = y;
|
||||
}
|
||||
|
||||
Point::Point()
|
||||
{
|
||||
mx = 0;
|
||||
my = 0;
|
||||
}
|
||||
|
||||
|
||||
float Point::getX() const
|
||||
{
|
||||
return mx;
|
||||
}
|
||||
|
||||
float Point::getY() const
|
||||
{
|
||||
return my;
|
||||
}
|
||||
|
||||
void Point::setX(float x)
|
||||
{
|
||||
mx = x;
|
||||
}
|
||||
|
||||
void Point::setY(float y)
|
||||
{
|
||||
my = y;
|
||||
}
|
||||
|
||||
float Point::norm() const
|
||||
{
|
||||
return std::sqrt(mx * mx + my * my);
|
||||
}
|
||||
|
||||
void Point::normalize()
|
||||
{
|
||||
float pnorm = norm();
|
||||
mx /= pnorm;
|
||||
my /= pnorm;
|
||||
}
|
||||
|
||||
float Point::distance(const Point& p) const
|
||||
{
|
||||
return std::sqrt((p.mx - mx) * (p.mx - mx) + (p.my - my) * (p.my - my));
|
||||
}
|
||||
|
||||
Point Point::operator+(const Point& right) const
|
||||
{
|
||||
Point result = {mx + right.mx, my + right.my};
|
||||
return result;
|
||||
}
|
||||
|
||||
Point Point::operator*(float a) const
|
||||
{
|
||||
Point result = {a * mx, a * my};
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Point operator*(float a, const Point& p)
|
||||
{
|
||||
Point result = {a * p.mx, a * p.my};
|
||||
return result;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& left, const Point& right)
|
||||
{
|
||||
left << "(" << right.mx << ", " << right.my << ")";
|
||||
return left;
|
||||
}
|
||||
37
seminar02_encapsulation/homework/code/0circle/point.h
Normal file
37
seminar02_encapsulation/homework/code/0circle/point.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
/*
|
||||
Поля x и y сделаны приватными
|
||||
Конкретно для этого класса их можно было сделать публичными
|
||||
Так как пользователь всё-равно будет иметь доступ без ограничений к этим полям через геттеры и сеттеры
|
||||
Но они сделаны приватными для образовательных целей
|
||||
*/
|
||||
|
||||
class Point
|
||||
{
|
||||
private:
|
||||
float mx, my;
|
||||
|
||||
public:
|
||||
|
||||
Point(float x, float y);
|
||||
Point();
|
||||
|
||||
float getX() const;
|
||||
float getY() const;
|
||||
void setX(float x);
|
||||
void setY(float y);
|
||||
|
||||
void normalize();
|
||||
float distance(const Point& p) const;
|
||||
float norm() const;
|
||||
Point operator+(const Point& right) const;
|
||||
Point operator*(float a) const;
|
||||
|
||||
|
||||
|
||||
friend Point operator*(float a, const Point& p);
|
||||
friend std::ostream& operator<<(std::ostream& left, const Point& right);
|
||||
};
|
||||
|
||||
|
||||
307
seminar02_encapsulation/homework/code/1number/number.cpp
Normal file
307
seminar02_encapsulation/homework/code/1number/number.cpp
Normal file
|
|
@ -0,0 +1,307 @@
|
|||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
/*
|
||||
Класс Number -- класс положительных больших чисел
|
||||
|
||||
Большое число будет храниться в динамическом массиве data
|
||||
Каждый элемент этого массива содержит разряд числа в 100-ричной системе счисления
|
||||
(так как base = 100)
|
||||
По сути, каждый элемент data хранит две цифры числа в десятичной записи
|
||||
|
||||
Значение 100 для системы счисления выбрано как компромис между
|
||||
эффективностью и удобством написания программы.
|
||||
Если выбрать значения базы 10 - то программа будет не так эффективна по памяти
|
||||
Если выбрать значения базы 256 (максимально эффективное использование памяти для типа char),
|
||||
то алгоритм печати на экран сильно усложнится
|
||||
В качестве альтернативы, можно было выбрать базу 1e9,
|
||||
изменив при этом тип элементов c char на int
|
||||
|
||||
capacity - размер массива data
|
||||
size - сколько ячеек занимет число в массиве data
|
||||
size <= capacity
|
||||
|
||||
Для удобства разряды числа хранятся в обратном порядке
|
||||
Например, число 12345678 соответствует массиву
|
||||
data = {78, 56, 34, 12}
|
||||
(это упрощает многие алгоритмы с такими числами)
|
||||
*/
|
||||
|
||||
|
||||
class Number
|
||||
{
|
||||
private:
|
||||
static const int base = 100;
|
||||
std::size_t size;
|
||||
std::size_t capacity;
|
||||
char* data;
|
||||
|
||||
public:
|
||||
|
||||
Number(int a)
|
||||
{
|
||||
#ifdef _DEBUG_CONSTRUCTOR
|
||||
std::cout << "(Number constructor " << a << " -> ";
|
||||
#endif
|
||||
// Находим размер необходимой памяти под это число
|
||||
int temp = a;
|
||||
capacity = 0;
|
||||
while (temp != 0)
|
||||
{
|
||||
temp /= base;
|
||||
capacity += 1;
|
||||
}
|
||||
|
||||
// Отдельно обрабатываем случай, когда число равно 0
|
||||
if (capacity == 0)
|
||||
capacity = 1;
|
||||
|
||||
// Выделяем память и записывем число a в массив data
|
||||
// Например, число 12345678 представится в виде массива [78, 56, 34, 12]
|
||||
|
||||
data = new char[capacity];
|
||||
|
||||
for (int i = 0; i < capacity; ++i)
|
||||
{
|
||||
data[i] = a % base;
|
||||
a /= base;
|
||||
}
|
||||
|
||||
// В данном случае размер будет равен вместимости
|
||||
size = capacity;
|
||||
#ifdef _DEBUG_CONSTRUCTOR
|
||||
std::cout << *this << ")" << std::endl;
|
||||
#endif
|
||||
}
|
||||
// Конструктор по умолчанию
|
||||
Number() : Number(0) {}
|
||||
// Конструктор копирования
|
||||
Number(const Number& n) {
|
||||
size = n.size;
|
||||
capacity = n.capacity;
|
||||
data = new char[capacity];
|
||||
for (int i = 0; i < size; i++) {
|
||||
data[i] = n.data[i];
|
||||
}
|
||||
}
|
||||
Number(const char* str) {
|
||||
int len = std::strlen(str);
|
||||
size = (len + len % 2) / 2;
|
||||
capacity = size;
|
||||
data = new char[capacity];
|
||||
char buf[2];
|
||||
for (int i = 0; i < size; i++) {
|
||||
buf[1] = str[len - 2 * i - 1];
|
||||
if (len - 2 * i - 1 > 0) {
|
||||
buf[0] = str[len - 2 * i - 2];
|
||||
}
|
||||
else {
|
||||
buf[0] = '0';
|
||||
}
|
||||
data[i] = std::stoi(buf);
|
||||
}
|
||||
}
|
||||
~Number()
|
||||
{
|
||||
delete [] data;
|
||||
}
|
||||
Number& operator=(const Number& right) {
|
||||
capacity = right.capacity;
|
||||
size = right.size;
|
||||
data = new char[capacity];
|
||||
for (int i = 0; i < size; i++) {
|
||||
data[i] = right.data[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Number operator+(const Number& a) {
|
||||
Number result;
|
||||
int i;
|
||||
char carry = 0;
|
||||
int max_size = size > a.size ? size : a.size;
|
||||
|
||||
result.capacity = max_size + 1;
|
||||
result.data = new char[capacity];
|
||||
|
||||
for (i = 0; i < max_size; ++i) {
|
||||
result.data[i] = (data[i] + a.data[i] + carry) % base;
|
||||
carry = (data[i] + a.data[i] + carry) / base;
|
||||
}
|
||||
|
||||
if (carry) {
|
||||
result.data[i] = carry;
|
||||
result.size = max_size + 1;
|
||||
}
|
||||
else {
|
||||
result.size = max_size;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
void operator+=(const Number& a) {
|
||||
*this = *this + a;
|
||||
}
|
||||
|
||||
bool isEven() const {
|
||||
if (data[0] % 2) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Number operator*(const Number& right) const {
|
||||
#ifdef _DEBUG_MUL
|
||||
std::cout << "arg1=" << *this << "(capacity=" << capacity << ",size=" << size << ")" << " " << "arg2=" << right << "(capacity=" << right.capacity << ",size=" << right.size << ")"<< std::endl;
|
||||
#endif
|
||||
int i, j;
|
||||
int temp;
|
||||
Number result;
|
||||
|
||||
result.capacity = capacity + right.capacity;
|
||||
int *carry = (int*)std::calloc(result.capacity, sizeof(int));
|
||||
|
||||
result.data = (char*)calloc(result.capacity, sizeof(char));
|
||||
#ifdef _DEBUG_MUL
|
||||
std::cout << "carry:[" << carry[0];
|
||||
for (int k = 1; k < result.capacity; ++k) {
|
||||
std::cout << "," << carry[k];
|
||||
}
|
||||
std::cout << "]" << std::endl;
|
||||
#endif
|
||||
for (i = 0; i < size; ++i) {
|
||||
for (j = 0; j < right.size; ++j) {
|
||||
#ifdef _DEBUG_MUL
|
||||
std::cout << i + j << ":" << static_cast<int>(result.data[i + j]) << " + " << static_cast<int>(data[i]) << " * " << static_cast<int>(right.data[j]) << " + " << carry[i+j] << std::endl;
|
||||
#endif
|
||||
temp = (result.data[i + j] + data[i] * right.data[j] + carry[i + j]);
|
||||
result.data[i + j] = temp % base;
|
||||
carry[i + j + 1] += temp / base;
|
||||
carry[i + j] = 0;
|
||||
|
||||
}
|
||||
}
|
||||
#ifdef _DEBUG_MUL
|
||||
std::cout << "result before applying carry:" << result << std::endl;
|
||||
std::cout << "carry:[" << carry[0];
|
||||
for (int k = 1; k < result.capacity; ++k) {
|
||||
std::cout << "," << carry[k];
|
||||
}
|
||||
std::cout << "]" << std::endl;
|
||||
#endif
|
||||
if (carry[i + j - 1]) {
|
||||
result.data[i + j - 1] = carry[i + j - 1];
|
||||
result.size = i + j;
|
||||
carry[i + j - 1] = 0;
|
||||
}
|
||||
else {
|
||||
result.size = i + j - 1;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_MUL
|
||||
std::cout << "before correcting capacity, result=" << result << std::endl;
|
||||
#endif
|
||||
// correcting capacity
|
||||
/*char* temp_data = (char *)calloc(result.size, sizeof(char));
|
||||
for (i = 0; i < result.size; ++i) {
|
||||
temp_data[i] = result.data[i];
|
||||
}
|
||||
|
||||
free(result.data);
|
||||
result.capacity = result.size;
|
||||
result.data = (char*)calloc(result.size,sizeof(char));
|
||||
for (i = 0; i < result.size; ++i) {
|
||||
result.data[i] = temp_data[i];
|
||||
}
|
||||
|
||||
free(temp_data);*/
|
||||
free(carry);
|
||||
#ifdef _DEBUG_MUL
|
||||
std::cout << "return value=" << result << "(capacity=" << result.capacity << ",size=" << result.size << ")" << std::endl << "======" << std::endl;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
void operator*=(const Number& a) {
|
||||
*this = *this * a;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& stream, const Number& right);
|
||||
friend int main();
|
||||
friend Number factorial(int n);
|
||||
};
|
||||
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, const Number& right)
|
||||
{
|
||||
#ifdef _DEBUG_COUT
|
||||
stream << "[";
|
||||
for (std::size_t i = 0; i < right.size; ++i) {
|
||||
stream << static_cast<int>(right.data[right.size - 2 - i]) << ",";
|
||||
}
|
||||
stream << "]";
|
||||
#else
|
||||
// Печатаем самый большой разряд
|
||||
stream << (int)right.data[right.size - 1];
|
||||
|
||||
// Печатаем остальные разряды с заполнением нулями до 2-х цифр
|
||||
// setfill и setw это то же самое, что и в языке C спецификатор %02d
|
||||
for (std::size_t i = 0; i < right.size - 1; ++i)
|
||||
stream << std::setfill('0') << std::setw(2) << (int)right.data[right.size - 2 - i];
|
||||
#endif
|
||||
return stream;
|
||||
}
|
||||
|
||||
Number fib(int n) {
|
||||
Number a = 0; // F0
|
||||
Number b = 1; // F1
|
||||
for (int i = 1; i <=n; ++i) {
|
||||
if (i % 2) {
|
||||
a += b;
|
||||
}
|
||||
else {
|
||||
b += a;
|
||||
}
|
||||
}
|
||||
if (n % 2) {
|
||||
return b;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
Number factorial(int n) {
|
||||
Number result{1};
|
||||
for (int i = 2; i < n + 1; ++i) {
|
||||
result = Number(i) * result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Number x = Number("25852016738884976640000");
|
||||
Number y = Number("24");
|
||||
|
||||
//char s[3];
|
||||
//Number result = "1";
|
||||
//for (int i = 1; i < 26; ++i) {
|
||||
//s = std::to_string(i);
|
||||
//sprintf(s, "%d", i);
|
||||
// result = (Number{i} * result);
|
||||
//}
|
||||
//x += y;
|
||||
//Number z = x + y;
|
||||
//std::cout << fib(1000) << std::endl;
|
||||
//x = x * Number(24)*Number{25};
|
||||
//y = factorial(5);
|
||||
//std::cout << x << " " << x.capacity << " " << x.size << std::endl;
|
||||
//std::cout << y << " "<< y.capacity << " " << y.size << std::endl;
|
||||
// 90405070506200618121707-18-13-05-18-08
|
||||
//std::cout << "===" << std::endl << Number(2) * Number(3) << " "<< Number(3) * Number(2) << std::endl;
|
||||
//std::cout << "5! = " << Number(2) * Number(3) * Number(4) * Number(5) << std::endl;
|
||||
std::cout << factorial(1000) << std::endl;
|
||||
//std::cout << Number("620448401733239439360000") * Number(25) << std::endl;
|
||||
}
|
||||
|
||||
BIN
seminar02_encapsulation/homework/homework_encapsulation.pdf
Normal file
BIN
seminar02_encapsulation/homework/homework_encapsulation.pdf
Normal file
Binary file not shown.
202
seminar02_encapsulation/homework/homework_encapsulation.tex
Normal file
202
seminar02_encapsulation/homework/homework_encapsulation.tex
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
\documentclass{article}
|
||||
\usepackage[utf8x]{inputenc}
|
||||
\usepackage{ucs}
|
||||
\usepackage{amsmath}
|
||||
\usepackage{amsfonts}
|
||||
\usepackage{marvosym}
|
||||
\usepackage{wasysym}
|
||||
\usepackage{upgreek}
|
||||
\usepackage[english,russian]{babel}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{float}
|
||||
\usepackage{textcomp}
|
||||
\usepackage{hyperref}
|
||||
\usepackage{geometry}
|
||||
\geometry{left=2cm}
|
||||
\geometry{right=1.5cm}
|
||||
\geometry{top=1cm}
|
||||
\geometry{bottom=2cm}
|
||||
\usepackage{tikz}
|
||||
\usepackage{ccaption}
|
||||
\usepackage{multicol}
|
||||
\usepackage{fancyvrb}
|
||||
|
||||
\usepackage{listings}
|
||||
%\setlength{\columnsep}{1.5cm}
|
||||
%\setlength{\columnseprule}{0.2pt}
|
||||
|
||||
\usepackage{colortbl,graphicx,tikz}
|
||||
\definecolor{X}{rgb}{.5,.5,.5}
|
||||
|
||||
\date{}
|
||||
\begin{document}
|
||||
\pagenumbering{gobble}
|
||||
|
||||
\lstset{
|
||||
language=C++, % choose the language of the code
|
||||
basicstyle=\linespread{1.1}\ttfamily,
|
||||
columns=fixed,
|
||||
fontadjust=true,
|
||||
basewidth=0.5em,
|
||||
keywordstyle=\color{blue}\bfseries,
|
||||
commentstyle=\color{gray},
|
||||
stringstyle=\ttfamily\color{orange!50!black},
|
||||
showstringspaces=false,
|
||||
%numbers=false, % where to put the line-numbers
|
||||
numbersep=5pt,
|
||||
numberstyle=\tiny\color{black},
|
||||
numberfirstline=true,
|
||||
stepnumber=1, % the step between two line-numbers.
|
||||
numbersep=10pt, % how far the line-numbers are from the code
|
||||
backgroundcolor=\color{white}, % choose the background color. You must add \usepackage{color}
|
||||
showstringspaces=false, % underline spaces within strings
|
||||
captionpos=b, % sets the caption-position to bottom
|
||||
breaklines=true, % sets automatic line breaking
|
||||
breakatwhitespace=true, % sets if automatic breaks should only happen at whitespace
|
||||
xleftmargin=.2in,
|
||||
extendedchars=\true,
|
||||
keepspaces = true,
|
||||
}
|
||||
\lstset{literate=%
|
||||
*{0}{{{\color{red!20!violet}0}}}1
|
||||
{1}{{{\color{red!20!violet}1}}}1
|
||||
{2}{{{\color{red!20!violet}2}}}1
|
||||
{3}{{{\color{red!20!violet}3}}}1
|
||||
{4}{{{\color{red!20!violet}4}}}1
|
||||
{5}{{{\color{red!20!violet}5}}}1
|
||||
{6}{{{\color{red!20!violet}6}}}1
|
||||
{7}{{{\color{red!20!violet}7}}}1
|
||||
{8}{{{\color{red!20!violet}8}}}1
|
||||
{9}{{{\color{red!20!violet}9}}}1
|
||||
{~} {$\sim$}{1}
|
||||
}
|
||||
|
||||
\title{Семинар \#2: Инкапсуляция. Домашнее задание.\vspace{-5ex}}\date{}\maketitle
|
||||
|
||||
\section*{Класс Circle}
|
||||
Допустим, что мы хотим создать программу, которая будет работать с окружностями (это может быть игра или, например, графический редактор). Для того, чтобы сделать код более понятным и удобным в использовании, мы решили создать класс окружности. Кроме того, мы решили использовать уже ранее написанный класс точки в 2D пространстве (файлы \texttt{point.h} и \texttt{point.cpp}). Создайте класс окружности, который будет включать следующие методы:
|
||||
\begin{itemize}
|
||||
\item Конструктор \texttt{Circle(const Point\& acenter, float aradius)}, который будет задавать поля \texttt{center} и \texttt{radius} соответстующими значениями.
|
||||
\item Конструктор по умолчанию \texttt{Circle()} - задаются значения, соответствующие единичной окружности с центром в начале координат.
|
||||
\item Конструктор копирования \texttt{Circle(const Circle\& circle)}
|
||||
\item Сеттеры и геттеры, для полей \texttt{center} и \texttt{radius}. Поле \texttt{radius} нельзя задать отрицательным числом. При попытке задания его отрицательным числом оно должно устанавливаться в значение \texttt{0}.
|
||||
\item Метод \texttt{float getArea() const}, который будет возвращать площадь поверхности круга.
|
||||
\item Метод \texttt{float getDistance(const Point\& p) const}, который будет возвращать расстояние от точки \texttt{p}, до ближайшей точки окружности.
|
||||
\item Метод \texttt{bool isColliding(const Circle\& c) const}, который будет возвращать \texttt{true}, если круг пересекается с кругом \texttt{c}.
|
||||
\item Метод \texttt{void move(const Point\& p)}, который будет перемещать кружок на вектор \texttt{p}.
|
||||
\end{itemize}
|
||||
Весь начальный код содержится в папке \texttt{0circle}. При компиляции нужно указывать все \texttt{.cpp} файлы, которые вы хотите скомпилировать:
|
||||
\begin{verbatim}
|
||||
g++ main.cpp point.cpp
|
||||
\end{verbatim}
|
||||
\begin{itemize}
|
||||
\item Создайте файлы \texttt{circle.h} и \texttt{circle.cpp} и перенесите реализацию класса окружности из файла \texttt{main.cpp} в эти файлы.
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\newpage
|
||||
\section*{Класс Number (большое число)}
|
||||
Стандартные целочисленные типы данных, такие как \texttt{int} имеют фиксированный небольшой размер. Соответственно значения, которые можно хранить в переменных этих типов ограничены. Типичное максимальное значение \texttt{char} равно $2^7 - 1 = 127$, тип \texttt{int} обычно ограничен $2^{31}-1 = 2147483647$ и даже тип \texttt{unsigned long long} имеет ограничение в $2^{64}-1 = 1.8 * 10^{19}$. Хранить действительно большие числа в этих типах невозможно. В этом задании нужно сделать класс, с помощью которого будет удобно складывать и умножать большие целые положительные числа. Начальный код этого класса содержится в \texttt{1number/number.cpp}. Изучите этот код.
|
||||
|
||||
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[scale=1]{../images/number1.png}
|
||||
\caption{Представление числа 12345678 в памяти с помощью нашего класса Number}
|
||||
\label{fig:nummber1}
|
||||
\end{figure}
|
||||
|
||||
|
||||
\subsection*{Задания:}
|
||||
\begin{itemize}
|
||||
\item \textbf{Конструктор по умолчанию:} Напишите конструктор по умолчанию \texttt{Number()}, который будет создавать число равное нулю.
|
||||
\item \textbf{Конструктор копирования:} Напишите конструктор копирования \texttt{Number(const Number\& n)}.
|
||||
\item \textbf{Конструктор из строки:} Напишите конструктор \texttt{Number(const char* str)}, который будет создавать большое число на основе строки. Предполагаем, что на вход конструктору всегда идёт корректная строка. Например, число из примера можно будет создать так:
|
||||
\begin{lstlisting}
|
||||
Number a = Number("12345678");
|
||||
\end{lstlisting}
|
||||
\item \textbf{Присваивание:} Напишите оператор присваивания \texttt{Number\& operator=(const Number\& right)}.
|
||||
\item \textbf{Сложение:} Напишите и протестируйте операторы сложения \texttt{operator+} и оператор присваивания сложения \texttt{operator+=}. Реализовывать оба этих оператора с нуля необязательно. Ведь, если написан один из этих операторов, то очень просто написать другой.
|
||||
\item \textbf{Числа Фибоначчи:} Числа Фибоначчи задаются следующим образом:
|
||||
\begin{align*}
|
||||
F_0 &= 0\\
|
||||
F_1 &= 1\\
|
||||
F_n &= F_{n-1} + F_{n-2}
|
||||
\end{align*}
|
||||
Используйте класс \texttt{Number}, чтобы вычислить $F_{1000}$. Правильный ответ:
|
||||
\begin{verbatim}
|
||||
F(1000) = 43466557686937456435688527675040625802564660517371780402481729089536555417949051890
|
||||
40387984007925516929592259308032263477520968962323987332247116164299644090653318793829896964992
|
||||
8516003704476137795166849228875
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
|
||||
|
||||
\item \textbf{Четность:} Напишите метод \texttt{bool isEven() const}, который будет проверять является ли наше число чётным и, если это верно, возвращает \texttt{true}, в ином случае возвращает \texttt{false}.
|
||||
|
||||
\item \textbf{Произведение:} Напишите метод \texttt{Number operator*(const Number\& right) const} - оператор умножения одного числа \texttt{Number} на другое. Протестируйте вашу функцию на различных примерах (умножение большого числа на большое, умножение большого числа на небольшое ($< 100$) или на ноль, умножение двух небольших чисел и т. д.).\\
|
||||
\item \textbf{Факториал:} Используйте написанный оператор для вычисления факториала от 1000. \\
|
||||
Правильный ответ:
|
||||
\begin{verbatim}
|
||||
1000! = 40238726007709377354370243392300398571937486421071463254379991042993851239862902059
|
||||
2044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759
|
||||
9188236277271887325197795059509952761208749754624970436014182780946464962910563938874378864
|
||||
8733711918104582578364784997701247663288983595573543251318532395846307555740911426241747434
|
||||
9347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379
|
||||
5345242215865932019280908782973084313928444032812315586110369768013573042161687476096758713
|
||||
4831202547858932076716913244842623613141250878020800026168315102734182797770478463586817016
|
||||
4365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186
|
||||
1168115536158365469840467089756029009505376164758477284218896796462449451607653534081989013
|
||||
8544248798495995331910172335555660213945039973628075013783761530712776192684903435262520001
|
||||
5888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838
|
||||
9714760885062768629671466746975629112340824392081601537808898939645182632436716167621791689
|
||||
0977991190375403127462228998800519544441428201218736174599264295658174662830295557029902432
|
||||
4153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690
|
||||
8979684825901254583271682264580665267699586526822728070757813918581788896522081643483448259
|
||||
9326604336766017699961283186078838615027946595513115655203609398818061213855860030143569452
|
||||
7224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136
|
||||
4932734975655139587205596542287497740114133469627154228458623773875382304838656889764619273
|
||||
8381490014076731044664025989949022222176590433990188601856652648506179970235619389701786004
|
||||
0811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614
|
||||
8396573822911231250241866493531439701374285319266498753372189406942814341185201580141233448
|
||||
2801505139969429015348307764456909907315243327828826986460278986432113908350621709500259738
|
||||
9863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826
|
||||
2809561214509948717012445164612603790293091208890869420285106401821543994571568059418727489
|
||||
9809425474217358240106367740459574178516082923013535808184009699637252423056085590370062427
|
||||
1243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000
|
||||
\end{verbatim}
|
||||
|
||||
\item \textbf{Числа-градины:} Возьмём некоторое число $n$ и будем последовательно применять к нему следующую функцию:
|
||||
\begin{equation*}
|
||||
f(n) =
|
||||
\begin{cases}
|
||||
n / 2, &\textup{если n - четное}\\
|
||||
3 n + 1, &\textup{если n - нечетное}
|
||||
\end{cases}
|
||||
\end{equation*}
|
||||
В результате получится некоторая последовательность. Например, при $n = 7$ получится:
|
||||
\begin{verbatim}
|
||||
7 -> 22 -> 11 -> 34 -> 17 -> 52 -> 26 -> 13 -> 40 -> 20 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1
|
||||
\end{verbatim}
|
||||
Последовательность доходит до 1. Вам нужно написать функцию, которая будет по начальному числу находить длину такой последовательности (\texttt{steps}) и максимальное число в этой последовательности(\texttt{max}). Например, для числа $7$, максимальное число в последовательности будет равно $52$, а длина последовательности -- $16$. Напишите программу, которая будет по начальному числу находить длину последовательности и максимальный элемент в ней.
|
||||
|
||||
Тесты для проверки:
|
||||
\begin{verbatim}
|
||||
n = 7 steps = 16; max = 52
|
||||
n = 256 steps = 8; max = 256
|
||||
n = 1117065 steps = 527; max = 2974984576
|
||||
n = 4761963248413673697 steps = 2337; max = 9926927712374950744648
|
||||
|
||||
n = 90560792656972947582439785608972465789628974587264056284658721771
|
||||
steps = 1630;
|
||||
max = 773658021643749360792171137214151494851244403993540980838080564520
|
||||
\end{verbatim}
|
||||
Для решения этой задачи нужно написать оператор сравнения и метод деления на 2 (оператор целочисленного деления можно не писать).
|
||||
\item \textbf{Раздельная компиляция:} Перенесите объявление класса \texttt{Number} в файл \texttt{number.h}, а определение методов в файл \texttt{number.cpp}. Раздельно скомпилируйте эту программу.
|
||||
\end{itemize}
|
||||
|
||||
\end{document}
|
||||
Reference in a new issue