Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> собственный клас вектор 
V
    Опции темы
ИванМ
Дата 1.4.2010, 17:37 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 3
Всего: 23



Код

Vector<T>& Vector<T> ::erase(int k)
{
    if(k>=n||k<0) 
    {
        cout<<"index out of range"<<endl;
        return *this;
    }
    Vector buf=*this;
    for(int i=k;i<n-1;i++)
        buf[i]=buf[i+1];
    n--;
    delete V;
    V=new T[n];
    for(int i=0;i<n;i++)
        (*this)[i]=buf[i];
    return *this;
}

PM MAIL   Вверх
toxx
Дата 1.4.2010, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 4
Всего: 13



ИванМ
Первый раз когда я писал предыдущее своё сообщение я так вас и понял, но 
потом подумал может быть вы опять не это от меня хотите и увидел, что
проще это с одним циклом for...

А вот еще метод resize(int) у вектора он 
1.перевыделяет количество памяти массива на нужную?
2.и копирует все элементы предыдущего массива и если размер больше он лишние элементы зануляет?(если размер больше предыдущего массива)


Это сообщение отредактировал(а) toxx - 1.4.2010, 18:03
PM MAIL   Вверх
ИванМ
Дата 1.4.2010, 18:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 3
Всего: 23



Цитата(toxx @  1.4.2010,  17:58 Найти цитируемый пост)
1.перевыделяет количество памяти массива на нужную?

да

Цитата(toxx @  1.4.2010,  17:58 Найти цитируемый пост)
и копирует все элементы предыдущего массива и если размер больше он лишние элементы зануляет? 

это зависит от разработчика
самое оптимально это да, занулить
PM MAIL   Вверх
toxx
Дата 1.4.2010, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 4
Всего: 13



ИванМ
Код

void Vector<T>::resize(int k)
{
    delete[] V;
    n=k;
    V=new T[n];
    for(int i=0;i<n;i++)
        (*this)[i]=0;
}


вот этого будет достаточно?

Это сообщение отредактировал(а) toxx - 1.4.2010, 18:05
PM MAIL   Вверх
ИванМ
Дата 1.4.2010, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 3
Всего: 23



toxx, нет, надо еще сохранить элементы, которые были до этого, меньшие k
PM MAIL   Вверх
toxx
Дата 1.4.2010, 18:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 4
Всего: 13



Код

void Vector<T>::resize(int k)
{
    Vector buf=*this;
    delete[] V;
    n=k;
    V=new T[n];
    for(int i=0;i<n;i++)
    if(i<buf.size())(*this)[i]=buf[i];
        else (*this)[i]=0;
}


Вот, протестировал вроде бы работает.
PM MAIL   Вверх
ИванМ
Дата 1.4.2010, 18:40 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 3
Всего: 23



toxx, да, вроде правильно.
PM MAIL   Вверх
toxx
Дата 1.4.2010, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 4
Всего: 13



Цитата(ИванМ @ 1.4.2010,  18:40)
toxx, да, вроде правильно.

ИванМ
Спасибо за подсказки.
PM MAIL   Вверх
bsa
Дата 2.4.2010, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



toxx, вообще-то твой код метода resize() довольно замысловат и далеко не оптимален.
Ты должен, создать новый объект нового размера, скопировать туда остающиеся данные из старого вектора. Затем, ты должен обменять поля V и n этих объектов.
По-хорошему, вектор вообще нужно делать с использованием размещающего new, чтобы при уменьшении размера не было необходимости освобождать память и копировать оставшиеся данные. А при увеличении - увеличивать несколько больше, чем требуется, чтобы было меньше этих затратных операций (например, если вызывать push для stl-вектора, то выделенная память (capacity) будет выделсять так: 2, 4, 8, 16, 32, 64, 128, 256, ...; таким образом, нетрудно заметить, что для 256 элементов память будет перевыделяться только 8 раз, а по твоему алгоритму - все 512, если использовать resize).

Это сообщение отредактировал(а) bsa - 2.4.2010, 11:37
PM   Вверх
toxx
Дата 2.4.2010, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 4
Всего: 13



Цитата(bsa @ 2.4.2010,  11:36)
toxx, вообще-то твой код метода resize() довольно замысловат и далеко не оптимален.
Ты должен, создать новый объект нового размера, скопировать туда остающиеся данные из старого вектора. Затем, ты должен обменять поля V и n этих объектов.
По-хорошему, вектор вообще нужно делать с использованием размещающего new, чтобы при уменьшении размера не было необходимости освобождать память и копировать оставшиеся данные. А при увеличении - увеличивать несколько больше, чем требуется, чтобы было меньше этих затратных операций (например, если вызывать push для stl-вектора, то выделенная память (capacity) будет выделсять так: 2, 4, 8, 16, 32, 64, 128, 256, ...; таким образом, нетрудно заметить, что для 256 элементов память будет перевыделяться только 8 раз, а по твоему алгоритму - все 512, если использовать resize).

Если это будет оптимально, то я попробую переделать щас )Тогда у меня пара вопросов:

1.выделение больше это не плохо?(например мне надо 129 а выделяется 256...)
2.Это так хорошо компенсируется количеством вызовов resize?

Просто нас всё учат сколько нужно столько и выдели)Лишнего не выделять, а то приводятся примеры с размерностью массивов не 10 а в энное количество раз больше.


Это сообщение отредактировал(а) toxx - 2.4.2010, 13:37
PM MAIL   Вверх
bsa
Дата 2.4.2010, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(toxx @  2.4.2010,  13:35 Найти цитируемый пост)
Просто нас всё учат сколько нужно столько и выдели)Лишнего не выделять, а то приводятся примеры с размерностью массивов не 10 а в энное количество раз больше.
Есть рамки разумного. Конечно, если ты заполняешь массив путем 513 вызовов метода push, то любой алгоритм будет работать неоптимально. Или сильно тормозить, или выделит память под лишние 511 элементов. Учитывая нынешние объемы памяти, второе предпочтительней первого.
Но в любом случае, реализация resize через 1 полное и оно частичное копирование всего массива - это перебор. Достаточно одного "частичного".
PM   Вверх
toxx
Дата 2.4.2010, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 4
Всего: 13



Цитата(bsa @ 2.4.2010,  14:40)
Цитата(toxx @  2.4.2010,  13:35 Найти цитируемый пост)
Просто нас всё учат сколько нужно столько и выдели)Лишнего не выделять, а то приводятся примеры с размерностью массивов не 10 а в энное количество раз больше.
Есть рамки разумного. Конечно, если ты заполняешь массив путем 513 вызовов метода push, то любой алгоритм будет работать неоптимально. Или сильно тормозить, или выделит память под лишние 511 элементов. Учитывая нынешние объемы памяти, второе предпочтительней первого.
Но в любом случае, реализация resize через 1 полное и оно частичное копирование всего массива - это перебор. Достаточно одного "частичного".

Да это верно...=)
Только разберусь со своим деревом(опять чето не удаляет ничего), и попробую реализовать,что вы посоветовали...
PM MAIL   Вверх
mes
Дата 2.4.2010, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(toxx @  2.4.2010,  12:35 Найти цитируемый пост)
Просто нас всё учат сколько нужно столько и выдели)Лишнего не выделять, а

Вектор не может знать сколько нужно, поэтому он должен подбирать средне-оптимальную стратегию,
но при этом должен оставлять возможность "ручного" управления.
Т.е. если программист в курсе что у него будет именно 129 элементов, он может сделать vector.reserve (129), и спокойно через push добавлять элементы, не испытывая (лишней) переаллокации.
Также хочу отметить, что это плохое решение - выбирать один контейнер на все случаи жизни.. 
Вектор удобен в случае рандомного доступа к элементам, но для "произвольного" наполнения он не эффективен. 
Но и тут не все так плохо, как кажется.
Программист может для наполнения использовать например очередь, которая не будет столь необдуманно копировать содержимое, как вектор, а также не будет столь жадная на память как список. Ну а как наполнение закончено и необходим быстрый рандомный доступ и линейное расположение, то можно за один присест, перекопировать очередь в вектор.

Исходя из вышесказнного считаю, что создание своего вектора иначе, чем для учебных целей, плохая затея.. 




--------------------
PM MAIL WWW   Вверх
ИванМ
Дата 2.4.2010, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 3
Всего: 23



mes, ты все говоришь правильно. Но думаю в данном случае это избыточная информация. Студенту просто нужно написать программу как их учили. И с этой задачей toxx справился.
Но твои советы могут служить в продолжении темы, для самообразования.
PM MAIL   Вверх
mes
Дата 2.4.2010, 17:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



toxx, как совет по оформлению кода : используйте пустые строчки для разделения логических блоков функции,
а также не скупитесь на пробелы и ясные имена хотя бы для не локальных переменных.
т.е. вместо :
Код

void Vector<T>::resize(int k)
{
    Vector buf=*this;
    delete[] V;
    n=k;  
    V=new T[n];
    for(int i=0;i<n;i++)
    if(i<buf.size())(*this)[i]=buf[i];
        else (*this)[i]=0;
}

примерно так :
Код

void Vector<T>::resize(int new_size)
{
    Vector buf = *this;
    delete[] V;

    m_size = new_size; 
    V = new T[m_size];

    for(int i=0; i<m_size; ++i )
      if (i<buf.size())  (*this)[i] = buf[i];
      else               (*this)[i] = 0;
}


и Вам будет легче, и у форумчан глаза целей.
smile
P.S. содержимое  использованно только для примера оформления, ибо оно далеко от приемлегого..
smile


--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0617 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.