Поиск:

Ответ в темуСоздание новой темы Создание опроса
> стандартные алгоритмы, Unique( stat,end) 
:(
    Опции темы
ano360
Дата 23.1.2007, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Есть в библиотеке стандартных шаблонов такой алгоритм как Unique-по идее он удаляет все повторяющиеся элементы.
Есть ли какаиенибудь ограничения или особенности при сипользовонии этой функци.
У меня она почемуто не работает.

Код


bool even(TRCords c1,TRCords c2){
return c1==c2 ;
}

class TRCords{
        public:
        int i;
        int j;
        TRCords(){i=j=0;}
        TRCords(int i1,int j1){i=i1;j=j1;}
        bool operator<(TRCords &ob2){return(i<ob2.i&&j<ob2.j);}
        bool operator>(TRCords &ob2){return(i>ob2.i&&j>ob2.j);}
        bool operator==(TRCords &ob2){return (i==ob2.i && j==ob2.j);}
        bool operator!=(TRCords &ob2){return (i!=ob2.i || j!=ob2.j);}                
};

vector<TRCords>vectorTemp;

 unique(vectorTemp.begin(),vectorTemp.end(),even);



--------------------
Жизнь есть.
PM MAIL WWW ICQ   Вверх
zkv
Дата 23.1.2007, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

Репутация: 1
Всего: 92



Цитата(ano360 @  23.1.2007,  18:51 Найти цитируемый пост)
У меня она почемуто не работает.

а в чем это выражается? 
Код

vector<TRCords>vectorTemp;
//где то тут должно быть заполнение вектора
 unique(vectorTemp.begin(),vectorTemp.end(),even);

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


Опытный
**


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

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



дубликаты не удаляются. Просто не удаляются, как были, так и остаются.

Цитата

//где то тут должно быть заполнение вектора

Да. там просто ОЧЕНЬ много всякого када, на имеющего к проблеме отношения.
массив точно заполняется, сразу после вызова unique, у меня след. код.
Код


for(int j1=0;j1<int(vectorTemp.size());j1++)
                                WriteConsole(GetStdHandle( STD_OUTPUT_HANDLE ),(String(" ")+vectorTemp[j1].i+String(" ")+vectorTemp[j1].j+String("~")).data(),5,0,NULL);
                                WriteConsole(GetStdHandle( STD_OUTPUT_HANDLE ),(String("\n")).data(),1,0,NULL);


Да, и вот ещё странность-vectorTemp не чистится, но это пока не доказано

Добавлено @ 19:22 
Код

for(int j1=0;j1<int(vectorTemp.size());j1++)
                               WriteConsole(GetStdHandle( STD_OUTPUT_HANDLE ),(String(" ")+vectorTemp[j1].i+String(" ")+vectorTemp[j1].j+String("~")).data(),5,0,NULL);
                               WriteConsole(GetStdHandle( STD_OUTPUT_HANDLE ),(String("\n")).data(),1,0,NULL);

                               unique(vectorTemp.begin(),vectorTemp.end(),even);

                               for(int j1=0;j1<int(vectorTemp.size());j1++)
                                WriteConsole(GetStdHandle( STD_OUTPUT_HANDLE ),(String(" ")+vectorTemp[j1].i+String(" ")+vectorTemp[j1].j+String("~")).data(),5,0,NULL);
                                WriteConsole(GetStdHandle( STD_OUTPUT_HANDLE ),(String("\n")).data(),1,0,NULL);

при запуске следующего выводятся 2 идентичные строки:
2 2~ 2 3~ 2 4~ 3 2~ 3 4~ 4 2~ 3 2~ 3 4~ 4 2~ 4 4~ 5 2~ 5 3~ 5 4~ 4 4~
2 2~ 2 3~ 2 4~ 3 2~ 3 4~ 4 2~ 3 2~ 3 4~ 4 2~ 4 4~ 5 2~ 5 3~ 5 4~ 4 4~


--------------------
Жизнь есть.
PM MAIL WWW ICQ   Вверх
ano360
Дата 23.1.2007, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



кстати, вариант запуска unique(vectorTemp.begin(),vectorTemp.end()); у меня не работает, ыдаёт ошибку и посылает к исходникам, хотя operator== для ТРКордс, как вы видете, определён.


У кого есть какие идеи? Даже самые безумные


--------------------
Жизнь есть.
PM MAIL WWW ICQ   Вверх
zkv
Дата 23.1.2007, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

Репутация: 1
Всего: 92



Цитата(ano360 @  23.1.2007,  19:40 Найти цитируемый пост)
У кого есть какие идеи? Даже самые безумные 

посмотрите комментарии в этом примере, здесь говорится про последовательные элементы:
Код

//from MSDN
// alg_unique.cpp
// compile with: /EHsc
#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
#include <ostream>

using namespace std;

// Return whether modulus of elem1 is equal to modulus of elem2
bool mod_equal ( int elem1, int elem2 )
{
   if ( elem1 < 0 ) 
      elem1 = - elem1;
   if ( elem2 < 0 ) 
      elem2 = - elem2;
   return elem1 == elem2;
};

int main( )
{
   vector <int> v1;
   vector <int>::iterator v1_Iter1, v1_Iter2, v1_Iter3,
         v1_NewEnd1, v1_NewEnd2, v1_NewEnd3;

   int i;
   for ( i = 0 ; i <= 3 ; i++ )
   {
      v1.push_back( 5 );
      v1.push_back( -5 );
   }

   int ii;
   for ( ii = 0 ; ii <= 3 ; ii++ )
   {
      v1.push_back( 4 );
   }
   v1.push_back( 7 );
   
   cout << "Vector v1 is ( " ;
   for ( v1_Iter1 = v1.begin( ) ; v1_Iter1 != v1.end( ) ; v1_Iter1++ )
      cout << *v1_Iter1 << " ";
   cout << ")." << endl;

   // Remove consecutive duplicates
   v1_NewEnd1 = unique ( v1.begin ( ) , v1.end ( ) );

   cout << "Removing adjacent duplicates from vector v1 gives\n ( " ;
   for ( v1_Iter1 = v1.begin( ) ; v1_Iter1 != v1_NewEnd1 ; v1_Iter1++ )
      cout << *v1_Iter1 << " ";
   cout << ")." << endl;

   // Remove consecutive duplicates under the binary prediate mod_equals
   v1_NewEnd2 = unique ( v1.begin ( ) , v1_NewEnd1 , mod_equal );

   cout << "Removing adjacent duplicates from vector v1 under the\n "
        << " binary predicate mod_equal gives\n ( " ;
   for ( v1_Iter2 = v1.begin( ) ; v1_Iter2 != v1_NewEnd2 ; v1_Iter2++ )
      cout << *v1_Iter2 << " ";
   cout << ")." << endl;

   // Remove elements if preceded by an element that was greater
   v1_NewEnd3 = unique ( v1.begin ( ) , v1_NewEnd2, greater<int>( ) );

   cout << "Removing adjacent elements satisfying the binary\n "
        << " predicate mod_equal from vector v1 gives ( " ;
   for ( v1_Iter3 = v1.begin( ) ; v1_Iter3 != v1_NewEnd3 ; v1_Iter3++ )
      cout << *v1_Iter3 << " ";
   cout << ")." << endl;
   cin.get();
}


PM MAIL   Вверх
ano360
Дата 23.1.2007, 20:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Это всё,конечно, здорово, и я вспомнил как пользоваться промтом, но мне это чёто не очень помогло.
Мож я тупой?
или уникуе удаляет только одинаковые эл-ты, стоящие друг за другом?

Это сообщение отредактировал(а) ano360 - 23.1.2007, 20:06


--------------------
Жизнь есть.
PM MAIL WWW ICQ   Вверх
zkv
Дата 23.1.2007, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

Репутация: 1
Всего: 92



Цитата(ano360 @  23.1.2007,  20:05 Найти цитируемый пост)
или уникуе удаляет только одинаковые эл-ты, стоящие друг за другом?

судя по примеру - да, но в описании нигде не встречал такого утверждения, у меня в студии удаляются только последовательные элементы  
PM MAIL   Вверх
ano360
Дата 23.1.2007, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



в чаком случае мне проще будет самому написать ф-ю удаления повторяющихся э-тов.


--------------------
Жизнь есть.
PM MAIL WWW ICQ   Вверх
ano360
Дата 23.1.2007, 20:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



А как получить интератор элемента вектора с опред номером. допустим 3 его эл-та?

Я тут функцмю сортировки накидал, вдруг кому понадобится, только необходимо знать интератор эл -та

Код

template <class X> vector<X> RUnique(vector<X> &vec1){
int vec1_s = vec1.size();
for (int i=0;i<vec1_s;i++)
        for (int j=i+1;j<vec1_s;j++)
                if (vec1[j]==vec1[i])
                        vec1.erase[ интератор эл-та номер j ] ;

return vec1_s;
}


Это сообщение отредактировал(а) ano360 - 23.1.2007, 20:51


--------------------
Жизнь есть.
PM MAIL WWW ICQ   Вверх
segmentation_fault
Дата 24.1.2007, 00:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

Репутация: нет
Всего: 1



ano360, итератор определяется так: 
Код

vec1.begin()+=j;

Но твоя функция не будет работать, т.к. после удаления элементов, размер вектора уменьшается, так что твой цикл
Код

 for (int j=i+1;j<vec1_s;j++) 

будет указывать за пределы вектора. 
Если порядок элементов вектора не принципиален, можешь сделать так:
создай сет, скопируй туда содержимое вектора, очисти вектор и скопируй туда содержимое сета. Одинаковые элементы в сет не копируются, так что получишь то, что хотел.  
PM MAIL   Вверх
Vyacheslav
Дата 24.1.2007, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Про unique
1. Во-первых он "удаляет"  смежные  дубликаты
2. А во-вторых, он реально ничего не удаляет, как и любой remove-подобный алгоритм. Он просто перемещает дубликаты за логический конец и возвращает итератор этого логического конца. Причем, что самое неприятное, никто при этом не гарантирует, что в результате перемещения, часть перемещаемых элементов не исчезнет.
Поэтому вызов  такого рода грубейшая ошибка
Код

 unique(vectorTemp.begin(),vectorTemp.end(),even);
 
Чтобы происходло реальное удаление смежных дубликатов следует использовать связку erase-unique
Код

  vectorTemp.erase( unique(vectorTemp.begin(),vectorTemp.end(),even), vectorTemp.end());



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
stmamont
Дата 24.1.2007, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



ano360
у этой сортировки сложность n^2 , логичней использовать встроенную в stl сортировку


--------------------
user posted image
PM MAIL ICQ   Вверх
ano360
Дата 24.1.2007, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(stmamont @ 24.1.2007,  14:08)
ano360
у этой сортировки сложность n^2 , логичней использовать встроенную в stl сортировку

А конкретней?
Если вы имеете ввиду sort



Это сообщение отредактировал(а) ano360 - 24.1.2007, 17:37


--------------------
Жизнь есть.
PM MAIL WWW ICQ   Вверх
ano360
Дата 24.1.2007, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Вот конечный вр-т:
Код

template <class X> vector<X> RUnique(vector<X> &vec1){
for (int i=0;i<vec1.size();i++)
        for (int j=i+1;j<vec1.size();j++)
                if (vec1[j]==vec1[i])
                        vec1.erase(vec1.begin()+j) ;

return vec1;
}


Добавлено @ 17:41 
Цитата(stmamont @ 24.1.2007,  14:08)
ano360
у этой сортировки сложность n^2 , логичней использовать встроенную в stl сортировку

Что вы имели ввиду? про с ложность n^2. Это как?

Это сообщение отредактировал(а) ano360 - 24.1.2007, 17:41


--------------------
Жизнь есть.
PM MAIL WWW ICQ   Вверх
stmamont
Дата 24.1.2007, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Код

for (int i=0;i<vec1.size();i++)
        for (int j=i+1;j<vec1.size();j++)


сложность алгоритма - n^2

в то время как средняя сложность алгоритма встроенного sort составляет n * log n
где n количество сортируемых элементов в массиве.


--------------------
user posted image
PM MAIL ICQ   Вверх
ano360
Дата 24.1.2007, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



круто, но мне ещё ведь надо и удалить все лишние эл-ты, а не только отсортировать, а моя ф-я делает итои другое.



--------------------
Жизнь есть.
PM MAIL WWW ICQ   Вверх
segmentation_fault
Дата 24.1.2007, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

Репутация: нет
Всего: 1



ano360, а почему бы тебе не отсортировать сначала вектор стандартным алгоритмом, а потом применить unique, как это обьяснил Vyacheslav, т.к. в отсортированном векторе,  все одинаковые элементы теперь действительно будут последовательными. 
PM MAIL   Вверх
Vyacheslav
Дата 24.1.2007, 19:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Цитата(segmentation_fault @  24.1.2007,  00:01 Найти цитируемый пост)
создай сет, скопируй туда содержимое вектора, очисти вектор и скопируй туда содержимое сета. Одинаковые элементы в сет не копируются, так что получишь то, что хотел.   


Логично smile
Код

#pragma hdrstop
#include <iterator>
#include<vector>
#include<set>
#include <algorithm>
#include <iostream>



//---------------------------------------------------------------------------

#pragma argsused
using namespace std;

template< class T>
void my_unique(vector<T>& tmp)
{
    set<T> set_tmp(tmp.begin(), tmp.end());
    vector<T>(set_tmp.begin(),set_tmp.end()).swap(tmp);
}


int main(int argc, char* argv[])
{
    int temp[10] = { 1,2,3,4,5,1,2,3,4, 6  };
    vector<int> vectorTemp(temp, temp + 10);
   
    //вывод на консоль содержимого вектора 
    copy(vectorTemp.begin(),vectorTemp.end(),ostream_iterator< int, char >(cout," "));
    cout << endl;

    my_unique( vectorTemp );

     //вывод на консоль содержимого вектора  после удаления дубликатов
    copy(vectorTemp.begin(),vectorTemp.end(),ostream_iterator< int, char >(cout," "));
    cout << endl;
    return 0;
}
//---------------------------------------------------------------------------



Можно задействовать  и sort c unique
Код

template< class T>
void my_unique(vector<T>& tmp)
{
    sort(tmp.begin(), tmp.end());
    tmp.erase(unique(tmp.begin(), tmp.end()), tmp.end());
}



Добавлено @ 20:08 
Кстати для понимания работы unique посмотрите, что получится, если просто вызвать unique без erase
Код

void my_unique(vector<T>& tmp)
{
    sort(tmp.begin(), tmp.end());
    //tmp.erase(unique(tmp.begin(), tmp.end()), tmp.end());
    unique(tmp.begin(), tmp.end()); // грубая ошибка
}  



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
ano360
Дата 24.1.2007, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



segmentation_fault-Вы считаете это будет работать быстрее чем нов. функция?


--------------------
Жизнь есть.
PM MAIL WWW ICQ   Вверх
stmamont
Дата 24.1.2007, 22:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



ano360, быстрее чем твоя - точно. особенно при больших объемах данных. и уж точно - надежно


--------------------
user posted image
PM MAIL ICQ   Вверх
Vyacheslav
Дата 25.1.2007, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Кстати в первом варианте сделал ошибку. Конечно же надо было
Код

template< class T>
void my_unique(vector<T>& tmp)
{
    //set<int> set_tmp(tmp.begin(), tmp.end());
    set<T> set_tmp(tmp.begin(), tmp.end());
    //vector<int>(set_tmp.begin(),set_tmp.end()).swap(tmp);
    vector<T>(set_tmp.begin(),set_tmp.end()).swap(tmp);
}




--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

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

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

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

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


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

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


 




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


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

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