在 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
每次都会创建一个副本。
要解决这个问题,有两种方法。
- 您可以尝试在更新地图
- 的同时更新结果,并让向量存储对地图副本的一些引用。
- 由于您不将
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));
创建一个 std::p air 包含一个 temp 副本和一个 newVector 副本 - 按原样,然后为映射中的匹配对分配空间,并将临时对(即再次复制字符串和向量)复制到其中。
result.push_back(newVector);
这会在结果的后面为新向量分配空间,并将newVector
复制到其中。
此时,result
和myMap
包含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;
只需制作结果并映射类的成员即可。看到类型更改为矢量指针的矢量。
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
这占用了第二个循环并使用更少的空间,但使代码有点复杂。
- 写入向量<向量<bool>>
- 函数向量_指针有不同的原型,我可以构建一个吗
- std::向量与传递值的动态数组
- 将值指定给向量(2D)的向量中的某个位置
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 如何使用向量的template_back函数
- 尝试通过多个向量访问变量时,向量下标超出范围
- 如何通过派生类函数更改基类中的向量
- C++从另一个类访问公共静态向量的正确方法是什么
- 如何将ampl中的集合表示为c++中的向量
- 变量没有改变?通过向量的函数调用
- 迭代时从向量和内存中删除对象
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 计算排序向量的向量中唯一值的计数
- 矩阵向量乘法(cublasDgemv)返回零
- 一对向量构造函数:初始值设定项列表与显式构造
- 将结构向量排序为子组
- 在C++中调整向量中的索引
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么