此代码稍作修改代码:Given a string array, return all groups of strings that are anagrams
我花了最近1个小时阅读地图,集和其他文章的参考文献,但仍然无法理解。
#include <map>
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
int main(){
int n; cin >>n;
string word;
map<string, set<string> > anagrams;
for (int i=0;i<n;i++){
cin >> word;
string sortedWord(word);
sort(sortedWord.begin(), sortedWord.end());
anagrams[sortedWord].insert(word);
}
for (auto& pair : anagrams){
for (auto& word: pair.second){
cout << word << " ";
}
//cout << "\n";
}
}
据我所知,集合更像是一个有序向量。所以当我们来到这行代码时
anagrams[sortedWord].insert(word);
它使用我们的sortedWord作为键并将该对插入到字谜中。现在,当我继续插入对时,anagrams会根据sortedWord自动排序。因此,例如,如果我插入cat,god,按此顺序执行,anagrams将包含:
act act
act cat
dgo god
现在,当我使用基于范围的循环时,它会打印此对的第二项。我的理解是否正确? 我有两个问题。当我们使用sortedWord作为键时,为什么不替换之前的值?例如,act cat应该取代act act。这是因为map或set的实现?第二个问题,当我尝试打印pair.first跟随输入时,我得到一些随机输出:
Input:
5
cat act dog tac god
Output(for pair.second):
act cat tac dog god
Output(for pair.first):
a c t d g o
如果有人能给我进一步使用套装,我将不胜感激。
答案 0 :(得分:3)
对于std::map<std::string, std::set<std::string> >
,执行此操作时:
anagrams[sortedWord].insert(word);
它会返回对存储在std::set<std::string>
的{{1}}的引用,或者它(基本上)会创建一个新的sortedWord
并将其存储在该密钥中。由于您没有为其分配 set
,因此set
不会被替换。但在这种情况下,每次set
具有相同的值时,都会在sortedWord
上使用insert
方法将其添加到现有集合中。
就std::set
输出而言,它不是随机的。在地图中,您将遍历键和值(键为pair.first
,值为first
)。因此,在这种情况下,second
是来自pair.first
的字符串。所以第一次迭代是sortedWords
,第二次迭代是act
。因为然后迭代这些字符串对象,就会获得单个字符。
就结构而言,您的地图可以显示为:
dgo
答案 1 :(得分:3)
anagrams[sortedWord].insert(word);
它使用我们的sortedWord作为键并将该对插入到字谜中。
不完全正确。 anagrams
是容器,其中每个键都映射到set
。这意味着,您可以在anagrams[key]
内部拥有大量值,但它们永远不会重复。
考虑输入:cat act dog god none cat
,字谜将更像是这样:
anagrams-+-act-+-act
| +-cat
|
+-dgo-+-dog
| +-god
|
+-enno-+-none
请注意,cat
不会重复,dog
和god
输入都将存储在无意义的dgo
密钥下。
当您迭代第一个对的值时,您会获得密钥,但由于密钥不是set
,而是string
,您将获得单个字符而不是单词。
在我的示例中,您将获得类似a c t d g o e n n o
的内容,这正是键中的字符。
答案 2 :(得分:1)
首先,为什么map<string, set<string> >
中的键不能替换东西?
代码执行此操作:
string sortedWord(word);
sort(sortedWord.begin(), sortedWord.end());
anagrams[sortedWord].insert(word);
因此,对于任何单词,它都是先排序的,例如
act -> act
cat -> act
并将排序后的版本用作键,以查找适当的值,即std::set
个字符串。未排序的版本word
将插入到集合中。这不会取代之前的情况。
其次,如果你在一个字符串上使用一个基于循环的范围,你将获得每个字母。