Д.з. презентация

Содержание

Числа в обратном порядке - 1 list l; // Вариант с list // Добавляем числа в обратном // порядке for (;;) { cin >> n; // Читаем числа if (n==0)

Слайд 1Д.з.




Слайд 2Числа в обратном порядке - 1
list l; // Вариант с list

//

Добавляем числа в обратном
// порядке
for (;;) {
cin >> n; // Читаем числа
if (n==0) // до 0
break;
l.push_front(n);
}

// Печатаем
for (auto p=l.begin(); p!=l.end(); p++) {
cout << *p << "\n";
}

vector v;// Вариант с vector

for (;;) {
cin >> n;
if (n==0)
break;
v.push_back(n);
}

// Идем от конца к началу
auto p = v.end();

while (p != v.begin() {
p--;
cout << *p << "\n";
}


Слайд 3Числа в обратном порядке - 2
Какой вариант лучше?
Для больших объёмов list

гораздо медленнее!
list – только если надо часто добавлять в середину (или удалять)
Еще можно было использовать deque (следующее занятие)


Слайд 4Шаблон swp
template
void swp(T& x, T& y)
{
T tmp = x;
x

= y;
y = tmp;
}

Замечание:
T tmp; // Так хуже, чем T tmp = x;
tmp = x;
- Немного медленнее
- Более существенно, работает только если в классе есть конструктор по умолчанию (определение менее общее).




Слайд 5Специализация swp для string
class string {
char* p;
int len;
public:
friend void swp(string& x,

string& y);

};


void swp(string& x, string& y)
{
swp(x.p, y.p);
swp(x.len, y.len);
}




Слайд 6shared_string
class shared_string {
char* p;
// len для краткости не используем

// Воспомогaтельные методы

// Поставить

указатель p на
// данную строку и увеличить
// в ней счетчик.
void set_ptr(char * newp)
{
p = newp;
(*newp)++;
}

// Уменьшить счетчик в строке,
// на которую указывает p.
// Если надо, удалить строку.
void drop_ptr()
{
(*p)--;
if (*p == 0) {
cout << "Deleting " << p + 1;
delete [] p;
}
}

public:




Слайд 7shared_string - продолжение
shared_string(const char* s = "")
{
p = new

char[strlen(s)+2];
*p = 1;
strcpy(p + 1, s);
}

~shared_string()
{
drop_ptr();
}

shared_string(const shared_string& from)
{
set_ptr(from.p);
}

shared_string& operator=
(const shared_string& from)
{
if (p != from.p) {
drop_ptr();
set_ptr(from.p);
}
return *this;
}

void print() const
{
cout << p+1;
}

}; // Конец определения класса




Слайд 8shared_string - замечания
Еще вариант – non-intrusive
Называется: reference counting (счетчик ссылок)
Похожая вещь:

smart pointers (умные указатели).
shared_ptr в новой стандартной библиотеке




Слайд 9Copy on write
(Этот слайд на занятии не показывался, но в презентации

пусть останется, может кому-то будет интересно посмотреть..)

Хотелось бы: shared_string + возможность менять строки
Идея: разделять строки перед изменением

string s = "abc";
string s1 = s; // s.p и s1.p указывают на одну строку

s[i] = '!'; // Создается _отдельная_ копия строки,
// и изменения происходят в ней.

Недостатки: М.б. получается слишком сложно..




Слайд 10Еще про namespace




Слайд 11Еще возможности
Инкрементальное определение
namespace abc { … определения … } …

что-то вне namespace …
namespace abc { … еще определения … }

Глобальное пространство имен ::f() – глобальная функция
using ::f;

M.б. вложенные
abc::klm




Слайд 12Еще про STL




Слайд 13Еще про итераторы
Итераторы для вектора

Те же операции
p + n p –

n p += n p -= n

Итераторы и константы

const_iterator

void f(const vector& v)
{
// Тут просто итераторы
// использовать нельзя
vector::const_iterator p
=v.begin();

Но, еще раз, м.б. лучше не писать тип p явно:
auto p = v.begin();


Слайд 14Вставка и удаление
insert l.insert(p, n);
Вставляет перед p
Работает быстро (время O(1)
(T.е. не зависит

от длины списка)
Работает и для vector, но для vector время линейно от длины




erase l.erase(p);

Тоже работает быстро
Тоже работает и для vector, но за линейное время




Слайд 15vector – дополнительные возможности
Просто для сведения, на экзамене не будет:
reserve

v.reserve(1000); // Зарезервировать место
присваивание v = v1;
сравнение
if (v == v1)
лексикографическое сравнение if (v < v1)
swap swap(v, v1); // Эффективно




Слайд 17map (ассоциативный массив)
#include
using namespace std;

map m;

m[3.14] = 55;
m[2.238] =

73;
m[9.0] = 15;

cout << m[3.14];
m[9.0]++;

3.14 – ключ
55 - значение

Что будет, если написать так?:
cout << m[99.9];
Напечатается 0 !
Добавляется новый ключ, значение равно 0
В общем случае – для значения вызывается к-р по умолчанию




Слайд 18Итератор для map
Как перебрать все ключи?

for (auto p = m.begin();

p != m.end(); p++)
cout << p->first
<< p->second << " ";

Итератор указывает на структуру pair (пара) с полями first, second
(Кстати: Для итераторов определен оператор ->)

Ключи идут в порядке возрастания

Можно быстро найти значние по ключу:
p = m.find(i);
if (p == m.end() )
cout << "Не найдено";
else
cout << p->second;
поиск – быстро
O(log N)



Слайд 19Еще про map
Внутреннее представление:
дерево поиска (red-black tree)

Удаление
m.erase(i);
или
m.erase(p);

Еще добавление: insert
Можно

добавить пару
Чтобы задать пару есть очень простая функция (точнее, шаблон) make_pair
m.insert(make_pair(i, x));







Слайд 20map – что может быть ключом?
М.б. любой тип, для которого задан

operator<
map m1; map m2;
map m3;
// (Если задан abc::operator<)
map m; // Ошибка!
В принципе, можно задавать свою функцию сравнения
Совет: Если строка должна быть ключом – только map.
Не пытайтесь map или map и т.д.! Все равно не получится..




Слайд 21Пример работы с map
// Вводим пары чисел и печатаем их в

порядке возрастания
// первого числа
#include
using namespace std;
...
map m;
double x; int i;
while ( cin >> x >> j )
m[x] = j; // или можно то же записать, как
// m.insert(make_pair(x, j));

for (auto p = m.begin(); p != m.end(); p++)
cout << p->first << "-" << p->second << "\n";




Слайд 22Еще пример – телефонная книга
#include
#include
#include
using namespace std;
 
// Определим

тип phonebook –
// телефонная книга
typedef map
phonebook;
phonebook pb; // Тел. книга
// (вначале она пустая)

// Так задаются значения
pb["Иванов"] = 3223322;
 

pb["Петров"] = 2991234;
pb["Сидоров"] = 1231231;

// Печатаем телефон Петрова
cout << pb["Петров"];
 
// Печатаем все телефоны
for (auto p = pb.begin();
p != pb.end(); p++) {
cout << p->first << "-"
<< p->second <<"\n";
}
 





Слайд 23Tелефонная книга - продолжение
// Так можно проверить, есть ли человек в

тел.книге
if ( pb.find("Smith") != pb.end() ) {
cout << "Есть";
} else {
cout << "Нет";
}
 
// Так можно удалить человека из книги
pb.erase("Чижиков");




Слайд 24Шаблоны классов




Слайд 25Пример: шаблон класса "стек"
template
class stack {
T stk[100];

int size;

public:
stack() :
size(0)
{}

void push(const T& x)
{
size[size++] = x;
}

T pop
{
return stk[--size];
}
};

Использование

stack s1;
stack s2;
stack s3;
stack> s4;
При использовании параметры надо указывать явно




Слайд 26Замечания
Методы можно описывать вне класса

template void stack::push(const T& x)
{

... }

В частности, конструктор:
template
stack::stack(): size(0)
{}




Слайд 27Еще возможности
Не типовые параметры:
template
class stack {

T stk[maxsize]; …
};
stack s;
Такие параметры м.б. только целые (и в некоторых случаях указатели)
При вызове д.б. константы
Внутри - как константы

Параметры по умолчанию template class stack { …

stack s; // To же, что stack




Слайд 28Специализация
Специализация шаблона

template
class stack {
// Что-то особенное
};

Реальный пример из STL –

vector

Специализация метода

template <>
void stack:: push(double x) {
// Что-то особенное
};




Слайд 29Частичная специализация
template
class stack {
// Что-то особенное
};

М.б. сложная система разных

специализаций
template
class abc { … };

template
class abc { … };

template
class abc { … };

template
class abc { … };

template
class abc { … };







Слайд 30Шаблон метода
class abc {

template
void f(T x) {

… }

};
abc x;
x.f(5); // f
x.f(3.14); // f

// Пример
template
class complex {
T re, im;


template
complex(const T1& from) :
re(from.re), im(from.im)
{}
};

// Хотим задать преобразование
// complex -> complex
complex c1(1,2);
complex c2 = c1;
Генерируется конструктор
complex
(const complex& from)




Слайд 31Параметры - шаблоны
template < template class T >
class abc {
T

x;
T y;
T z;

};

abc v;




Слайд 32Замечание
Когда мы пишем шаблоны – это мы пишем код, который работает

для разных типов.
Называется: полиморфизм
Статический полиморфизм




Слайд 33Как лучше писать шаблоны алгоритмов для работы с контейнерами?




Слайд 34Д.з. про шаблон для печати - 1
// Вариант 1a
template
void

print(T& c)
{
T::iterator p;
for (p = c.begin(); p != c.end(); p++)
cout << *p << " ";
}

// Пример вызова
list l; vector v;

print(l);
print(v);

// Вариант 1б - исправленный
template
void print(T& c)
{
typename T::iterator p;
for (p = c.begin(); p != c.end(); p++)
cout << *p << " ";
}




Слайд 35Д.з. про шаблон для печати - 2
// Вариант 1в – const

correctness

template
void print(const T& c)
{
typename T::const_iterator p;
for (p = c.begin(); p != c.end(); p++)
cout << *p << " ";
}

// Вариант 1г – C++11

template
void print(const T& c)
{
for (auto p = c.begin(); p != c.end(); p++)
cout << *p << " ";
}




Слайд 36Д.з. про шаблон для печати - 3
// Вариант 2
template
void

print(T from, T to)
{
for (T p = from; p != to; p++)
cout << *p << " ";
}

// Пример вызова
vector v;
list l;

print(v.begin(), v.end());
print(l.begin(), l.end());

Преимущества:
Можно вызывать не только для всего контейнера
print(v.begin() +2,
v.end()-3);

Очень мало требует от T
Только *, ++, !=.
int a[10];

print(a, a+10);

Недостатки:
Дольше писать ☹




Слайд 37Библиотека MFC. Рисование в Windows программах. Все за 10 минут.




Слайд 38Создание MFC программы
Ряд заклинаний (инструкция на сайте)
Получится рабoтающая программа (которая пока

ничего не делает).
Найти место, куда вписать свой код
CAbcView::OnDraw(CDC* pDC) { // TODO




Слайд 39Рисование в MFC
CDC* pDC - device context
pDC->Ellipse(x1, y1, x2, y2);
pDC->MoveTo(x, y);
pDC->LineTo(x, y);



Слайд 41Д.з. - 1
Ввести число n и потом n раз фамилию человека

и оценку. Напечатать для каждого человека, сколько пятерок он получил. Например, вводим:
5
Иванов 5 Петров 4 Сидоров 5 Иванов 3 Сидоров 5
И д.б. напечатано: Иванов 1 Петров 0 Сидоров 2

Напоминание – как вводить слова: #include string s; … cin >> s;
Описать тип (типы?) для телефонной книги: имя → телефон, имя, адрес (день рождения?). Привести пример работы с таким типом.




Слайд 42Д.з. - 2
Шаблон queue - очередь (аналог stack, но first in

– first out).
// Пример использования
queue q;
q.push(3); q.push(7); q.push(11);
cout << q.pop(); // 3
cout << q.pop(); // 7

Можно считать, что очередь фиксированной длины и реализовать, как массив (примерно как стек в слайдах)

Можно реализовать с использованием vector или list (или deque)
(И тогда вы можете сказать, что применили шаблон «адаптер»…)




Слайд 43Д.з. - 3
MFC - вложенные треугольники (соединяем середины сторон). Сколько треугольников

– как хотите, фиксированное количество, или пока очередной не станет очень маленьким.
MFC – треугольник Серпинского
Замечания:
Если сделана задача 5 – задачу 4 можно не делать, она зачтется автоматически
Присылать достаточно только тот файл, который вы меняли – в данном случае это …View.cpp
Если хотите, можно эту программу написать с помощью любой среды и библиотеки, не обязательно MFC





Обратная связь

Если не удалось найти и скачать презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое ThePresentation.ru?

Это сайт презентаций, докладов, проектов, шаблонов в формате PowerPoint. Мы помогаем школьникам, студентам, учителям, преподавателям хранить и обмениваться учебными материалами с другими пользователями.


Для правообладателей

Яндекс.Метрика