Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.216.251.37] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Не могу придумать, чем реализовать следущюю задачу:
Нужно создать некотурую структуру формата int type | dword h1 | dword h2 кол-во элементов нужно динамически увеличивать. + от чего возникают проблемы - нужно удалять некоторые элементы, при этом нужно иметь возможность искать по элементу структуры. чем бы это реализовать? |
Сообщ.
#2
,
|
|
|
typedef struct _Type { int type DWORD h1 DWORD h2 _Type( int _type, DWORD _h1, DWORD _h2 ): type(_type), h1( _h1 ), h2( _h2 ) {} } StructType; typedef std::vector<StructType> MyVector; typedef MyVector::iterator MyVectorIterator; MyVector m_stlVector; /*добавляем элемент*/ m_stlVector.push_back( StructType( 0,12,12 ) ); m_stlVector.push_back( StructType( 3,10,11 ) ); /*удаляем элемент*/ MyVectorIterator i = std::find(m_stlVector.begin(), m_stlVector.end(), StructType( 0,12,12 )); if( i != m_stlVector.end() ) m_stlVector.erase( i ); |
Сообщ.
#3
,
|
|
|
Спасибо, а можно таким образом добавлять в определённую позицию определённый элемент?
Например сначала помещаем type и h1 потом по h1 находим элемент и добавляем значение h2? И удалять не по маске всех элементов сразу, а по какому-то одному, к примеру h2? Можно ответить просто "можно" и я уйду разбираться с vector =) |
Сообщ.
#4
,
|
|
|
Цитата freecod @ Спасибо, а можно таким образом добавлять в определённую позицию определённый элемент? добавлять/удалять элементы из середины вектора можно, но не рекомендуется - при этом будет произведено копирование всего содержимого вектора, и это будет медленно работать на больших массивах данных. Лучше для этого использовать связанные списки типа std::list<>. А вообще ознакомься со всем STL - разнообразными контейнерами, алгоритмами и проч. |
Сообщ.
#5
,
|
|
|
Цитата добавлять/удалять элементы из середины вектора можно, но не рекомендуется - при этом будет произведено копирование всего содержимого вектора, и это будет медленно работать на больших массивах данных. Лучше для этого использовать связанные списки типа std::list<>. А вообще ознакомься со всем STL - разнообразными контейнерами, алгоритмами и проч. если парядок не важен, то можно так: MyVectorIterator i = std::find(m_stlVector.begin(), m_stlVector.end(), StructType( 0,12,12 )); if( i != m_stlVector.end() ) { std::swap( i, m_stlVector.end() ); m_stlVector.erase( m_stlVector.end() ); } |
Сообщ.
#6
,
|
|
|
freecod
Честно я стандартную библиотеку не знаю . Но для решения этого у меня есть пара заготовок . инклуде файл с классом . информация ложится в динамическую память . надо расширяю надо сужаю . Но это не шаблон , поэтому подгонка занимает время . Но тупиков в работе поменьше . Надо эту инфру кидаю в файл , надо извлекаю . так что если полуфабрикат нужен скажи . Если нет то пользуйся тем что предложили. |
Сообщ.
#7
,
|
|
|
Вообще разбираюсь уже с list, но если не жалко - зааттачь, хорошие сорсы лишними не бывают =)
|
Сообщ.
#8
,
|
|
|
ну это так для ознакомления структура
см по ссылке только вместо массива твоя структура http://www.cyberforum.ru/post55082.html еще вопрос dword это что char или unsigned short . |
Сообщ.
#9
,
|
|
|
dword это 4 байта (double word, word - это слово == 2 байта)
char это 1 байт unsigned short это 2 байта. |
Сообщ.
#10
,
|
|
|
Цитата Dem_max @ dword это 4 байта (double word, word - это слово == 2 байта) char это 1 байт unsigned short это 2 байта. Может он имел ввиду char * ? Да, dword это 4 байта, define к unsigned long Добавлено Я вот смотрю в STL все контейнеры оерентированны на единичные элементы. То есть даже структура помещается как единичный элемент. Но у меня такая задача: вот у меня 3 связанных переменных - int и два dword. их - массив. То есть если бы мне было известно необходимое кол-во элементов я бы задал struct base{ int type; DWORD h1; DWORD h2; }; base some_base[100]; и использовал бы. Но у меня есть такой нюанс - по первых мне нужно по любому элементу этой "тройки" (один элемент структуры, "строчка" из [type, h1, h2]) в соотв. "ряду" найти например где h1 == 12345678 и получить позицию этой "тройки". То есть мне это воображается как-то вроде int pos = find(some_base.h1, 12345678); DWORD need = some_base[pos].h2; то есть обращаться к каждому подэлементу и упрявляться с этим. плюс ещё сколько у меня будет этих "троек" - хз, и они регулярно обновляются - одни удаляю, другие записываю, так что классический struct не подходит... как можно догадаться - это связаные хендлы, которые группируются в реальном времени. То есть list в макро-плане удовлетворяет, но как при этом искать по всем h1, а не по тройкам, найти его позицию, обратится к другим переменным "строки" - не представляю. |
Сообщ.
#11
,
|
|
|
это main.cpp
#include <iostream> using namespace std; #include "struk.h" int main (){ truk ST; struk A[10]; for (int i=0;i<10;i++){ A[i].h1=i; A[i].h2=2*i; A[i].type=3*i; ST.add(A[i]); } cout << ST; cout <<"type=3 N="<<ST.find_type(3)<<endl; cout <<"h1=7 N="<<ST.find_h1(7)<<endl; cout <<"h2=10 N="<<ST.find_h2(10)<<endl; ST.del (5);cout << " del n=5"<<endl; cout << ST; return 0; }; Добавлено это struk.h class struk { public: int h1; int type; int h2; }; class truk { private: char Name[20]; struk * pT; // указатель буфера int Len; public: truk(); ~truk(); void clear(); // очиска буфера void add(struk & St); // добавить элемент struk get(int i); // получить элемент void del(int i); // удалить элемент int find_type(int i); int find_h1 (int i); int find_h2 (int i); friend ostream& operator<< (ostream& theStream,truk & theString); }; truk::truk(){ pT = new struk[0]; Len=0; } truk::~truk(){ delete []pT; Len=0; } void truk::clear(){ delete []pT; pT = new struk[0]; Len=0; } void truk::add(struk & St){ struk *pT2= new struk[Len+1]; int i; for(i=0;i<Len;i++) pT2[i]=pT[i]; pT2[i]=St; delete []pT; pT=pT2; Len++; } struk truk::get(int i){ if (i > Len) i=Len; struk St=pT[i-1]; return St; } void truk::del(int i){ if ((i<=Len)&&(i!=0)){ i--; struk *pT2= new struk[Len-1]; int j,k; for(j=k=0;k<Len;j++,k++){ if (i==j) k++; pT2[j]=pT[k]; } delete []pT; pT=pT2; Len--; } } int truk::find_type(int i){ // k - это найденый номер ; k=0 - такого элемента нет int j,k=0; for(j=0;j<Len;j++) if (pT[j].type==i) k=j+1; return k; } int truk::find_h1(int i){ int j,k=0; for(j=0;j<Len;j++) if (pT[j].h1==i) k=j+1; return k; } int truk::find_h2(int i){ int j,k=0; for(j=0;j<Len;j++) if (pT[j].h2==i) k=j+1; return k; } ostream & operator << (ostream & theStream,truk & AAA ){ theStream <<"N"<<"\t"<<"type"<<"\t"<<"h1"<<"\t"<<"h2 "<< endl; for (int i=0;i<AAA.Len;i++) theStream <<(i+1)<<"\t"<< AAA.pT[i].type <<"\t"<< AAA.pT[i].h1 <<"\t"<< AAA.pT[i].h2 << endl; return theStream; } Добавлено даю тебе словно все int - но если разберешься с кодом то слепишь все завтра если тебе надо кину как этот блок записать или считать с винта . |
Сообщ.
#12
,
|
|
|
насчет поиска:
если че не понятно спрашивай. typedef struct _BaseStruct { int type; unsigned long h1; unsigned long h2; _BaseStruct(){} _BaseStruct( int _type, unsigned long _h1, unsigned long _h2) : type(_type), h1(_h1), h2(_h2) {} } BaseStruct; /* */ static bool _f( const BaseStruct& _val, const unsigned long& _f_value ) { return ( _val.h1 == _f_value ); } /* */ template<class TFValue, class container> typename container::iterator& Find(typename container::iterator& _begin, typename container::iterator& _end, const TFValue& _FindValue, bool (*fun)(const typename container::value_type& _Val, const TFValue& _f_value) ) { typename container::iterator& i = _begin; while ( i != _end ) { if( fun( *i, _FindValue ) ) return i; ++i; } return _end; } typedef std::vector<BaseStruct> MyVector; typedef MyVector::iterator MyVectorIterator; typedef MyVector::const_iterator MyVectorConstIterator; int _tmain(int argc, _TCHAR* argv[]) { MyVector g_stlVector; g_stlVector.push_back( BaseStruct(0,1231321,4564654) ); g_stlVector.push_back( BaseStruct(1,128771,459894) ); g_stlVector.push_back( BaseStruct(2,1266651,46989894) ); MyVectorIterator i = Find<unsigned long, MyVector>(g_stlVector.begin(), g_stlVector.end(), 1266651, &_f ); if( i != g_stlVector.end() ) { printf("type = %d\n" "h1 = %d\n" "h2 = %d\n" ,(*i).type,(*i).h1,(*i).h2); } return 0; } |
Сообщ.
#13
,
|
|
|
Кстати, вопрос про STL. C подключением чего-либо из STL, например #include <string>, как это влияет на размер и работоспособность на разных win-площадках? как я понимаю класс работы целиком прекомпилируется в бинарник и не требует внешних либ? Как конкретно std::string ведёт себя с большими размерами данных, никаких проблем использовать string как хранилище пары сотен кб данных? И когда я сделаю string = ""; память высвободится?
|
Сообщ.
#14
,
|
|
|
это main cpp
#include <iostream> #include <fstream> using namespace std; #include "struk.h" int main (){ truk ST; struk A[10]; for (int i=0;i<10;i++){ A[i].h1=i; A[i].h2=2*i; A[i].type=3*i; ST.add(A[i]); } cout << ST; cout <<"type=3 N="<<ST.find_type(3)<<endl; cout <<"h1=7 N="<<ST.find_h1(7)<<endl; cout <<"h2=10 N="<<ST.find_h2(10)<<endl; ST.del (5);cout << " del n=5"<<endl; cout << ST; save("file.dn",ST); truk D; load("file.dn",D); cout << D; return 0; }; Добавлено это struk.h class struk { public: int type; unsigned long h1; unsigned long h2; }; class truk { private: char Name[20]; struk * pT; // указатель буфера int Len; public: truk(); ~truk(); void clear(); // очиска буфера void add(struk & St); // добавить элемент struk get(int i); // получить элемент void del(int i); // удалить элемент int find_type(int i); int find_h1 (unsigned long i); int find_h2 (unsigned long i); friend ostream& operator<< (ostream& theStream,truk & theString); friend void save(char *NameFile,truk & AA); friend void load(char *NameFile,truk & AA); }; truk::truk(){ pT = new struk[0]; Len=0; } truk::~truk(){ delete []pT; Len=0; } void truk::clear(){ delete []pT; pT = new struk[0]; Len=0; } void truk::add(struk & St){ struk *pT2= new struk[Len+1]; int i; for(i=0;i<Len;i++) pT2[i]=pT[i]; pT2[i]=St; delete []pT; pT=pT2; Len++; } struk truk::get(int i){ if (i > Len) i=Len; struk St=pT[i-1]; return St; } void truk::del(int i){ if ((i<=Len)&&(i!=0)){ i--; struk *pT2= new struk[Len-1]; int j,k; for(j=k=0;k<Len;j++,k++){ if (i==j) k++; pT2[j]=pT[k]; } delete []pT; pT=pT2; Len--; } } int truk::find_type(int i){ // k - это найденый номер ; k=0 - такого элемента нет int j,k=0; for(j=0;j<Len;j++) if (pT[j].type==i) k=j+1; return k; } int truk::find_h1(unsigned long i){ int j,k=0; for(j=0;j<Len;j++) if (pT[j].h1==i) k=j+1; return k; } int truk::find_h2(unsigned long i){ int j,k=0; for(j=0;j<Len;j++) if (pT[j].h2==i) k=j+1; return k; } ostream & operator << (ostream & theStream,truk & AAA ){ theStream <<"N"<<"\t"<<"type"<<"\t"<<"h1"<<"\t"<<"h2 "<< endl; for (int i=0;i<AAA.Len;i++) theStream <<(i+1)<<"\t"<< AAA.pT[i].type <<"\t"<< AAA.pT[i].h1 <<"\t"<< AAA.pT[i].h2 << endl; return theStream; } void save(char *NameFile,truk & AA){ ofstream out(NameFile,ios::out |ios::binary); if(!out) cout <<"files don't open "<<endl; else{ out.write((char*)&AA.Len,sizeof(int)); out.write((char*)AA.pT,(sizeof(struk)*AA.Len)); out.close(); } }; void load(char *NameFile,truk & AA){ ifstream in(NameFile,ios::in |ios::binary); if(!in) cout <<"files don't open "<<endl; else { in.read((char*)&AA.Len,sizeof(int)); AA.pT = new struk[AA.Len]; in.read((char*)AA.pT,(sizeof(struk)*AA.Len)); cout<<"READ OK" <<endl; in.close(); } }; Добавлено freecod хоть спасибо скажет ? ведь в метапрограмировании в шаблонах ему втыкать и не перевтыкать А тут рабочий код с примером как его запускать Удачи!!!! Добавлено freecod использовать char если надо обрабатывать побайтно - тупиковый вариант лучше использовать unsigned short и делить его-побайтно . тогда можно считать файл целиком и поинтером или масивом к нему добраться #include <iostream> using namespace std; int main (){ cout << sizeof(unsigned short)<<" bytes"<< endl; unsigned short A=5; unsigned short B=A/256; unsigned short C=A%256; cout <<A<<"\t"<<B <<"\t"<<C<< endl; return 0; } ладно я умолкаю и отваливаю подальше . |
Сообщ.
#15
,
|
|
|
Изобретаем велосипеды, господа) Причем еще и одноразового использования...
Цитата freecod @ То есть list в макро-плане удовлетворяет, но как при этом искать по всем h1, а не по тройкам, найти его позицию, обратится к другим переменным "строки" - не представляю. Для поиска в контейнерах существуют как минимум 2 стандартных алгоритма: find и find_if. Во втором можно задавать условие для поиска - те искать по одному элементу структуры. К сожалению, при использовании чистого STL это условие должно быть оформлено в виде отдельной функции или класса: bool findFunc(const base& elem) { if (условие) return true; return false; } ... iterator elem = std::find_if(mylist.begin(), mylist.end(), &findFunc); Используя boost, можно уложится и в одну строчку(см boost::bind, boost::lambda) Например, вызов find_if может выглядеть примерно так: find_if(mylist.begin(), mylist.end(), bind(&base::getHandle1, _1) == valueISeek); Цитата qwone @ struk.h Когда делаешь велосипед, большая вероятность напороться на грабли. Вот и здесь, я бы отметил для начала следующее: 1. Отсутствие конструктора копирования - может привести к ошибкам защиты памяти(типа Segmentation Fault) в некоторых случаях(при копировании объекта, например, при передаче его в качестве аргумента в функцию). 2. Неоптимально реализована функция add(), что будет заметно на более-менее больших объемах данных - каждый раз полностью копируется всё содержимое массива, производится вызовы new[] и delete[]. То же с функцией del(). 3. Не шаблон, хотя не так уж и сложно его сделать. 4. Обычно в таких классах перегружается operator[] Цитата freecod @ Кстати, вопрос про STL. C подключением чего-либо из STL, например #include <string>, как это влияет на размер и работоспособность на разных win-площадках? как я понимаю класс работы целиком прекомпилируется в бинарник и не требует внешних либ? В STL используются шаблоны, отсюда она полностью header only, те не требует всяких .lib файлов(исключая разве что потоки cin/cout etc), все функции встраиваемые(inline), что положительно влияет на скорость, и отрицательно - на размер. Что касается std::string, то проблем или тормозов при работе с большими файлами не замечал, хотя особенности реализации тут уже зависят от конкретной версии STL. |