Qtに぀いお。 コンテナラむブラリ

こんにちは、Habr



今日は、おもしろくお䟿利な機胜に぀いおお話したいず思いたす。 圌女の名前はコンテナラむブラリです。 これは1぀ではなく、䟿利な機胜のグルヌプ党䜓です。 そしお、それらの目的は、芁玠のグルヌプの線成ず凊理です。 面癜いですね。 では、詳しく芋おみたしょう。猫ぞようこそ。



゚ントリヌ



ひず぀だけ蚀いたいこずがありたす-この蚘事はプログラマヌの初心者を察象ずしおいたす。 続けたす。


プログラミングで最も䞀般的なタスクの1぀は、芁玠のグルヌプの凊理を敎理するこずです。 プログラマヌは圌女ず䞀緒に倚くの蒞気を取る。 結局のずころ、すべおを棚に眮く必芁がありたす...しかし、Qtには玠晎らしいヘルパヌがありたす-コンテナラむブラリです。 このヘルパヌはQtCoreモゞュヌルにありたす。したがっお、远加のむンクルヌドは必芁ありたせん。 それでは、行きたしょう



QVectorベクトル



ベクトルは、通垞の配列に非垞によく䌌たデヌタ構造です。 ただし、ベクトルクラスを䜿甚するず、単玔な配列に比べおいく぀かの利点がありたす。 たずえば、ベクトル内の芁玠の数サむズを確認したり、動的に拡匵したりできたす。 このコンテナは、他のタむプのコンテナよりも経枈的です。 順次コンテナの最埌に芁玠を远加するには、 push_backメ゜ッドを䜿甚できたす。 ベクトルの芁玠には、むンデックス挔算子[]ず反埩子の䞡方を䜿甚しおアクセスできたす。 䟋



QVector<int> vec; vec.push_back(10); //      vec.push_back(20); vec.push_back(30); qDebug() << vec;
      
      





掚定されたす-QVector10,20,30 。



QByteArrayバむト配列



このコンテナはQVectorに非垞に䌌おいたすが、違いはテンプレヌトクラスではなく、サむズが1バむトの芁玠のみを栌玍できるこずです。 䞭間デヌタストレヌゞが必芁な堎合は、タむプQByteArrayのオブゞェクトを䜿甚できたす。 配列芁玠の数はコンストラクタヌで蚭定でき、[]挔算子を䜿甚しお配列芁玠にアクセスできたす。



 QByteArray arr(3); arr[0] = arr[1] = 0xFF; arr[2] = 0x0;
      
      





QByteArrayクラスのオブゞェクトのデヌタに圧瞮操䜜ず逆倉換を適甚するこずもできたす。 これは、2぀のグロヌバル関数qCompressおよびqUncompressを䜿甚しお実珟されたす。 デヌタを圧瞮および解凍するだけです



 QByteArray a = "Some text..."; QByteArray aCompressed = qCompress(a); qDebug << qUncompress(aCompressed);
      
      





䞀郚のテキスト...が衚瀺されたす。



QBitArrayビット配列



このクラスはビットたたはブヌル 配列を管理したす。 栌玍された各倀は、䜙分なメモリを無駄にするこずなく、1ビットのみを取りたす。 この型は、 bool型の倉数を倚数栌玍するために䜿甚されたす。

 QBitArray arr(3); arr[0] = arr[1] = true; arr[2] = false;
      
      







QListおよびQLinkedListリスト



リストは、関連するアむテムの順序付けられたセットであるデヌタ構造です。 ベクトルずキュヌに察するリストの利点は、これらの操䜜を実行するために最小限のポむンタヌのみが倉曎されるため、任意の䜍眮で芁玠を挿入および削陀する方が効率的であるこずです。唯䞀の䟋倖はリストの䞭倮に芁玠を挿入するこずです。 しかし、欠点がありたす-リストはむンデックスによっおリストの特定の芁玠を怜玢するのにあたり適しおいないため、この目的にはベクタヌを䜿甚するのが最適です。



リストはQListテンプレヌトクラスによっお実装されたす。 䞀般的に、このクラスは芁玠ぞのポむンタの配列です。



リストを操䜜するための特定の操䜜



芁玠の倀を倉曎しない堎合、効率䞊の理由から、[]挔算子の䜿甚は掚奚されたせん。 代わりにatメ゜ッドを䜿甚したす。これは、芁玠ぞの定数参照を返すためです。



最も䞀般的な操䜜の1぀は、リストを走査しお、各リスト項目の倀を順番に取埗するこずです。 䟋

 QList<int> list; list << 10 << 20 << 30; QValueList<int>::iterator it = list.begin(); //         while (it != list.end()) { qDebug() << "Element:" << *it; ++it; }
      
      







コン゜ヌルには以䞋が衚瀺されたす。

芁玠10

芁玠20

芁玠30



倧きなリストを䜿甚する堎合や、芁玠を挿入する必芁がある堎合は、二重にリンクされたQLinkedListリストを䜿甚する方が効率的です。 このコンテナヌはQListよりも倧食いですが、挿入たたは削陀操䜜は、削陀たたは挿入される芁玠の䜍眮に関係なく、4぀のポむンタヌを再定矩するこずになりたす。



qstackのスタック



スタックは、Last In First Out-last come、first goの原則に基づいお機胜するデヌタ構造を実装したす。 ぀たり、他のすべおの芁玠の埌に挿入された芁玠が最初にスタックから削陀されたす。



QStackクラスは、スタック構造の実装です。 このクラスはQVectorから継承されたす 。 スタックにアむテムを眮くプロセスは、通垞pushず呌ばれ、そこから䞀番䞊のアむテムをポップするこずは poping ず呌ばれたす。 プッシュ操䜜ごずにスタックサむズが1ず぀増加し、プッシュ操䜜ごずに1ず぀枛少したす。これらの操䜜では、 プッシュおよびポップ関数がQStackクラスで定矩されたす。 topメ゜ッドは、トップ芁玠ぞのリンクを返したす。 スタックの䜿甚䟋

 QStack<QString> stk; stk.push("Era"); //        stk.push("Corvus Corax"); stk.push("Gathering"); while (!stk.empty()) { qDebug() << "Element:" << stk.pop(); }
      
      







コン゜ヌルには次のようになりたす。

芁玠「収集」

芁玠「Corvus Corax」

芁玠「時代」



QQueueキュヌ



キュヌは、原則に埓っお動䜜するデヌタ構造を実装したす-先着順です。 QListから継承したQQueueクラスにキュヌを実装したした 。



次の䟋は、キュヌの䜿甚䟋を瀺しおいたす。

 QQueue<QString> que; que.enqueue("Era"); que.enqueue("Corvus Corax"); que.enqueue("Gathering"); while (!que.empty()) { qDebug() << "Element:" << que.dequeue(); }
      
      







コン゜ヌルには次のようになりたす。

芁玠「時代」

芁玠「Corvus Corax」

芁玠「収集」



蟞曞QMap、QMultiMap



蟞曞は、原則ずしお、日垞生掻で䜿甚される普通の蟞曞に䌌おいたす。 キヌ倀でむンデックス付けされた同じタむプのアむテムを保存したす。 蟞曞の利点は、特定のキヌに関連付けられた倀をすばやく取埗できるこずです。 重耇を蚱可する耇数の蟞曞を陀き、キヌは䞀意でなければなりたせん。



このタむプのコンテナでは、芁玠を芋぀けるためのキヌずずもに入力したす。キヌは任意のタむプの倀にするこずができたす。 QMapディクショナリの堎合、同じキヌを持぀2぀の異なる芁玠が入力されないようにする必芁がありたす。これらの芁玠の1぀を抜出できないためです。 各キヌは䞀意である必芁がありたす。



QMapオブゞェクトを䜜成するずきは、そのサむズをコンストラクタヌに枡す必芁がありたす。 このサむズは、他のコンテナクラスで通垞行われおいるように、芁玠の最倧数を制限するサむズではありたせんが、䜍眮の数を衚したす。 䜍眮の数は、栌玍されるず予想される芁玠の数よりも倧きくする必芁がありたす。そうしないず、蟞曞内の芁玠の怜玢が十分に効果的に実行されたせん。 この堎合、芁玠の配眮がより䟿利になるため、この倀は玠数のカテゎリに属する​​こずが望たしいです。



いく぀かの方法



蟞曞項目にアクセスする最も䞀般的な方法の1぀は、[]挔算子でキヌを䜿甚するこずです。 ただし、キヌず倀はむテレヌタメ゜ッドkeyずvalueを介しお取埗できるため、これはなくおもかたいたせん。たずえば、

 QMap<QString,QString> mapPhonebook; mapPhonebook["Piggy"] = "+380 93 785 11 11"; mapPhonebook["Kermit"] = "+7 85 123 65 56"; mapPhonebook["Gonzo"] = "+49 73 631 32 21"; QMap<QString,QString>::iterator it = mapPhonebook.begin(); for(;it != mapPhonebook.end(); ++it) { qDebug() << "Name:" << it.key() << "Phone:" << it.value(); }
      
      







コン゜ヌルには次のようになりたす。

名前ハメ撮り電話+49 73 631 32 21

名前カヌミット電話+7 85123 65562 21

名前貯金箱電話+380 93 785 11 11



QHashおよびQMultiHashハッシュ





ハッシュの機胜はQMapず非垞に䌌おいたすが、唯䞀の違いは、キヌで゜ヌトする代わりに、このクラスがハッシュテヌブルを䜿甚するこずです。 これにより、 QMapよりもはるかに高速にキヌ倀を怜玢できたす。



QMapず同様に、芁玠が存圚しないキヌを指定するず芁玠が䜜成されるため、むンデックス挔算子[]を䜿甚する堎合は泚意が必芁です。 したがっお、コンテナのcontainsメ゜ッドを䜿甚しお、キヌにバむンドされた芁玠の存圚を垞に確認するこずが重芁です。



独自のクラスのオブゞェクトをQHashに配眮する堎合は、クラスに比范挔算子==ず特殊関数qHashを実装する必芁がありたす。 比范挔算子の実装䟋は次のずおりです。

 inline bool operator==(const MyClass& mc1, const MyClass& mc2) { return (mc1.firstName() == mc2.firstName() && mc1.secondName() == mc2.secondName() ); }
      
      







qHash関数は、ハッシュ内の各アむテムに察しお䞀意でなければならない数倀を返す必芁がありたす。 䟋

 inline uint qHash(const MyClass& mc) { return qHash(mc.firstName()) ^ qHash(mc.secondName()); }
      
      







QMultiHashクラスはQHashから継承されたす 。 同じキヌで倀を配眮するこずができ、䞀般にQMultiMapに䌌おいたすが、芪クラスの詳现を考慮したす。



倚くのQSet



ドむツの数孊者ゲオルク・カントヌルが蚀ったように、「倚くは倚く、私たちは粟神的には1぀ずしお意味したす。」 これは、Tulipのコンテキストでは、芁玠を䜕らかの順序で曞き蟌み、倀を非垞に迅速に衚瀺し、ナニオン、むンタヌセクション、差などのセットの特性である操䜜を実行する機胜を提䟛するQSetコンテナヌにすぎたせん。 前提条件は、キヌが異なる必芁があるこずです。 QSetコンテナは、デヌタをすばやく取埗するための順序なしリストずしお䜿甚できたす。



セットで実行できる操䜜結合、亀差、差。



2぀のセットを䜜成し、それらに芁玠を曞き蟌みたす。

 QSet<QString> set1; QSet<QString> set2; set1 << "Lorem" << "Ipsum" << "Dolor"; set2 << "Sit" << "Amet" << "Lorem";
      
      







これら2぀のセットを結合する操䜜を実行し、セットの芁玠が倉曎されないようにするために、䞭間のsetResultセットを導入したす。

 QSet<QString> setResult = set1; setResult.unite(set2); qDebug() << " = " << setResult.toList();
      
      







以䞋が画面に衚瀺されたす。



Union =「Lorem」、「Ipsum」、「Dolor」、「Sit」、「Amet」





同様に、 亀差ず差 枛算が実行されたす。



たずめ



今日、読者はあらゆる皮類のQtコンテナを操䜜する方法を孊んでいるはずです。 今日、私は党䜓像のほんの䞀郚を話した。 アルゎリズム、正芏衚珟、QVariantなどがさらに先にありたす。 倚分私はそれらに぀いお曞きたす。



文孊


  1. 1.マックスシュリヌ。 Qt 4.5-プロフェッショナルC ++プログラミング
  2. 2. Qtリファレンスドキュメント




PSこの蚘事は、初心者プログラマヌのトレヌニングを目的ずしおいたす。



All Articles