簡體   English   中英

向量在C ++和push_back()中的使用

[英]Use of Vectors of vectors in C++ & push_back( )

我是C ++的新手,可能在這里缺少一些非常基本的東西,但是我正在嘗試創建向量的向量

#include <iostream>
#include <stack>
#include <string>
#include <map>
#include <vector>
#include <algorithm>


using namespace std;

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs)
    {
        vector<vector<string>> result;
        map<string,vector<string>> myMap;

        if(strs.size() == 0)
        {
            return result;
        }

        for(string s : strs)
        {
            string temp = s;
            sort(temp.begin(),temp.end());
            auto it = myMap.find(temp);
            if(it != myMap.end())
            {
                it->second.push_back(s);
            }
            else
            {
                vector<string> newVector;
                newVector.push_back(s);
                myMap.insert(pair<string,vector<string>>(temp,newVector));
                result.push_back(newVector);
            }
        }
        cout<< myMap["abt"].size() <<endl;
        return result;
    }
};


int main(int argc, const char * argv[])
{
    Solution mySolution;
    vector<string> myStrings {"eat", "tea", "tan", "ate", "nat", "bat"};
    auto result = mySolution.groupAnagrams(myStrings);

    for(vector<string> v: result)
    {
        //cout << v.size() << endl;
        for(string s: v)
        {
            cout << s << " ";
        }
        cout << endl;
    }
    return 0;
}

我期望輸出看起來像這樣

[
  ["ate", "eat","tea"],
  ["nat","tan"],
  ["bat"]
]

當我嘗試在main()中打印向量的向量時,向量的所有大小都為1。

好吧,當我在地圖上打印矢量的尺寸時,這些尺寸在我看來就可以了。 我在這里想念什么?

更新-

使用以下更改修復了它

for(string s : strs)
{
    string temp = s;
    sort(temp.begin(),temp.end());
    auto it = myMap.find(temp);
    if(it != myMap.end())
    {
        it->second.push_back(s);
    }
    else
    {
        vector<string> newVector;
        newVector.push_back(s);
        myMap.insert(pair<string,vector<string>>(temp,newVector));
    }
}
for(auto it: myMap)
{
    result.push_back(it.second);
}

我仍然想知道是否有一種方法可以避免最終循環遍歷地圖並實現我最初打算要做的事情?

這是這部分:

{
    vector<string> newVector;
    newVector.push_back(s);
    myMap.insert(pair<string,vector<string>>(temp,newVector));
    result.push_back(newVector);
}

每次給result一個具有一個元素的新向量。 更改地圖矢量工作而非矢量的原因是因為vector::push_back每次都會創建一個副本。


為了解決這個問題,有兩種方法。

  1. 您可以嘗試與地圖同時更新結果,並獲取向量以存儲對地圖副本的一些引用。
  2. 由於您不將result用於處理步驟,僅將結果用於結果,因此您可以在完成地圖后編譯向量。

我更喜歡方法2,因為您永遠不會返回地圖本身。 此外,還有一種從一種容器類型轉換為另一種容器類型的技術,例如, 此問題給出了有關所涉及內容的一些想法。

問題出在這部分代碼上:

vector<string> newVector;
newVector.push_back(s);
myMap.insert(pair<string,vector<string>>(temp,newVector));
result.push_back(newVector);

細分:

vector<string> newVector;

創建一個新的本地臨時向量。

newVector.push_back(s);

newVector的后面為string分配空間,並將s復制到其中。

myMap.insert(pair<string,vector<string>>(temp,newVector));

按原樣創建一個包含temp副本和newVector副本的std :: pair,然后在映射中為匹配對分配空間,然后將臨時對復制(即再次復制字符串和向量)到其中。

result.push_back(newVector);

這將在結果的后面為新向量分配空間,並將newVector復制到其中。

resultmyMap包含的獨立快照newVector在這一點上。 您的其余代碼將更新myMap的向量,但結果保持不變。

您可以通過不動態生成result ,而僅在完成所有工作后構建它來解決此問題:

    // take a reference to each string in the vector,
    // const indicates it will be immutable
    for(const string& s : strs)
    {
        string temp = s;
        sort(temp.begin(),temp.end());
        std::vector<string>& dest = myMap[temp];
        dest.emplace_back(s);
    }

    cout<< myMap["abt"].size() <<endl;

    for (auto& kv : myMap)  // kv: key value
    {
        // std::move tells 'emplace_back' it can steal the
        // vector's data right out of kv.second.
        result.emplace_back(std::move(kv.second));
    }

結果代碼在此處演示: http : //ideone.com/eofloM

#include <iostream>
#include <stack>
#include <string>
#include <map>
#include <vector>
#include <algorithm>


using namespace std;

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs)
    {
        vector<vector<string>> result;
        map<string,vector<string>> myMap;

        if(strs.size() == 0)
        {
            return result;
        }

        for(const string& s : strs)
        {
            string temp = s;
            sort(temp.begin(),temp.end());
            std::vector<string>& dest = myMap[temp];
            dest.emplace_back(s);
        }

        cout<< myMap["abt"].size() <<endl;

        for (auto& kv : myMap)  // kv: key value
        {
            result.emplace_back(std::move(kv.second));
        }

        return result;
    }
};


int main(int argc, const char * argv[])
{
    Solution mySolution;
    vector<string> myStrings {"eat", "tea", "tan", "ate", "nat", "bat"};
    auto result = mySolution.groupAnagrams(myStrings);

    for(vector<string> v: result)
    {
        //cout << v.size() << endl;
        for(string s: v)
        {
            cout << s << " ";
        }
        cout << endl;
    }
    return 0;
}       

我仍然想知道是否有一種方法可以避免最終循環遍歷地圖並實現我最初打算要做的事情?

class Solution {

private:
        vector<vector<string>*> result;
        map<string,vector<string>> myMap;

public:
    vector<vector<string>*> groupAnagrams(vector<string>& strs)
    {
//        vector<vector<string>*> result;
//        map<string,vector<string>> myMap;

只需得出結果並映射類的成員即可。 請參閱將類型更改為vector的vector的指針。

        else
        {
            vector<string> newVector;
            newVector.push_back(s);
            auto p = myMap.insert(pair<string,vector<string>>(temp,newVector));

            //p is pair<iterator, bool>
            //where iterator is pointing to the inserted element
            //so p.first->second is the new vector

            result.push_back(&(p.first->second));
        }

請注意,我們在地圖上放置了向量的地址。

for(vector<string>* v: result)
{
    for(string s: *v)
    {
        cout << s << " ";
    }
    cout << endl;
}

迭代向量並考慮指針類型,結果為:

eat tea ate 
tan nat 
bat

這消除了第二個循環並使用了較少的空間,但使代碼有點復雜。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM