На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Нужна пара трюков
    Не могу придумать, чем реализовать следущюю задачу:
    Нужно создать некотурую структуру формата
    int type | dword h1 | dword h2

    кол-во элементов нужно динамически увеличивать.
    + от чего возникают проблемы - нужно удалять некоторые элементы, при этом нужно
    иметь возможность искать по элементу структуры.
    чем бы это реализовать?
      ExpandedWrap disabled
        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 );
      Сообщение отредактировано: maxim84_ -
        Спасибо, а можно таким образом добавлять в определённую позицию определённый элемент?
        Например сначала помещаем type и h1
        потом по h1 находим элемент и добавляем значение h2?
        И удалять не по маске всех элементов сразу, а по какому-то одному, к примеру h2?

        Можно ответить просто "можно" и я уйду разбираться с vector =)
          Цитата freecod @
          Спасибо, а можно таким образом добавлять в определённую позицию определённый элемент?

          добавлять/удалять элементы из середины вектора можно, но не рекомендуется - при этом будет произведено копирование всего содержимого вектора, и это будет медленно работать на больших массивах данных. Лучше для этого использовать связанные списки типа std::list<>. А вообще ознакомься со всем STL - разнообразными контейнерами, алгоритмами и проч.
            Цитата
            добавлять/удалять элементы из середины вектора можно, но не рекомендуется - при этом будет произведено копирование всего содержимого вектора, и это будет медленно работать на больших массивах данных. Лучше для этого использовать связанные списки типа std::list<>. А вообще ознакомься со всем STL - разнообразными контейнерами, алгоритмами и проч.


            если парядок не важен, то можно так:
            ExpandedWrap disabled
              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() );
              }
            Сообщение отредактировано: maxim84_ -
              freecod
              Честно я стандартную библиотеку не знаю . Но для решения этого у меня есть пара заготовок .
              инклуде файл с классом . информация ложится в динамическую память . надо расширяю надо сужаю . Но это не шаблон , поэтому подгонка занимает время . Но тупиков в работе поменьше . Надо эту инфру кидаю в файл , надо извлекаю .
              так что если полуфабрикат нужен скажи . Если нет то пользуйся тем что предложили.
                Вообще разбираюсь уже с list, но если не жалко - зааттачь, хорошие сорсы лишними не бывают =)
                  ну это так для ознакомления структура
                  см по ссылке только вместо массива твоя структура
                  http://www.cyberforum.ru/post55082.html

                  еще вопрос
                  dword это что char или unsigned short .
                    dword это 4 байта (double word, word - это слово == 2 байта)
                    char это 1 байт
                    unsigned short это 2 байта.
                      Цитата 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, а не по тройкам, найти его позицию,
                      обратится к другим переменным "строки" - не представляю.
                        это main.cpp
                        ExpandedWrap disabled
                          #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
                        ExpandedWrap disabled
                          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 - но если разберешься с кодом
                        то слепишь все
                        завтра если тебе надо кину как этот блок записать или считать с винта .
                          насчет поиска:
                          если че не понятно спрашивай.
                          ExpandedWrap disabled
                            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;
                            }
                            Кстати, вопрос про STL. C подключением чего-либо из STL, например #include <string>, как это влияет на размер и работоспособность на разных win-площадках? как я понимаю класс работы целиком прекомпилируется в бинарник и не требует внешних либ? Как конкретно std::string ведёт себя с большими размерами данных, никаких проблем использовать string как хранилище пары сотен кб данных? И когда я сделаю string = ""; память высвободится?
                              это main cpp
                              ExpandedWrap disabled
                                #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

                              ExpandedWrap disabled
                                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 хоть спасибо скажет ?
                              ведь в метапрограмировании в шаблонах ему втыкать и не перевтыкать
                              А тут рабочий код с примером как его запускать

                              Удачи!!!! :yes:

                              Добавлено
                              freecod использовать char если надо обрабатывать побайтно - тупиковый вариант
                              лучше использовать unsigned short и делить его-побайтно .
                              тогда можно считать файл целиком и поинтером или масивом к нему добраться

                              ExpandedWrap disabled
                                #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;
                                }


                              ладно я умолкаю и отваливаю подальше . :whistle:
                                Изобретаем велосипеды, господа) Причем еще и одноразового использования...

                                Цитата freecod @
                                То есть list в макро-плане удовлетворяет, но как при этом искать по всем h1, а не по тройкам, найти его позицию,
                                обратится к другим переменным "строки" - не представляю.

                                Для поиска в контейнерах существуют как минимум 2 стандартных алгоритма: find и find_if. Во втором можно задавать условие для поиска - те искать по одному элементу структуры. К сожалению, при использовании чистого STL это условие должно быть оформлено в виде отдельной функции или класса:
                                ExpandedWrap disabled
                                  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 может выглядеть примерно так:
                                ExpandedWrap disabled
                                  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.
                                Сообщение отредактировано: pan2004 -
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0551 ]   [ 16 queries used ]   [ Generated: 4.05.24, 13:50 GMT ]