前段时间有以下作为面试问题,并且在基本语法上窒息得很厉害,以至于我无法进步(一旦肾上腺素开始发挥作用,编码就会消失。)
给定一个字符串列表,返回一个字符串集合列表,这些字符串集合是输入集合的变位词。即 "dog","god","foo" 应该返回 {"dog","god"}。之后,我自己创建了代码作为健全性检查,现在它已经存在了一段时间。我欢迎对此提出意见,看看我是否遗漏了什么,或者我是否可以更有效地完成它。以此为契机提高自己并学习其他技巧:
void Anagram::doWork(list input, list> &output)
{
  typedef list < pair < string, string>> SortType;
  SortType sortedInput;
  // sort each string and pair it with the original
  for(list< string >::iterator i = input.begin(); i != input.end(); ++i)
  {
    string tempString(*i);
    std::sort(tempString.begin(), tempString.end());
    sortedInput.push_back(make_pair(*i, tempString));
  }
  // Now step through the new sorted list
  for(SortType::iterator i = sortedInput.begin(); i != sortedInput.end();)
  {
    set< string > newSet;
    // Assume (hope) we have a match and pre-add the first.
    newSet.insert(i->first);
    // Set the secondary iterator one past the outside to prevent
    // matching the original
    SortType::iterator j = i;
    ++j;
    while(j != sortedInput.end())
    {
      if(i->second == j->second)
      {
        // If the string matches, add it to the set and remove it
        // so that future searches need not worry about it
        newSet.insert(j->first);
        j = sortedInput.erase(j);
      }
      else
      {
        // else, next element
        ++j;
      }
    }
    // If size is bigger than our original push, we have a match 
    // - save it to the output
    if(newSet.size() > 1)
    {
       output.push_back(newSet);
    }
    // erase this element and update the iterator
    i = sortedInput.erase(i);
  }
}
在查看评论并了解更多信息后,这是第二次通过:
void doBetterWork(list input, list> &output)
{
  typedef std::multimap< string, string > SortedInputType;
  SortedInputType sortedInput;
  vector< string > sortedNames;
  for(vector< string >::iterator i = input.begin(); i != input.end(); ++i)
  {
    string tempString(*i);
    std::sort(tempString.begin(), tempString.end());
    sortedInput.insert(make_pair(tempString, *i));
    sortedNames.push_back(tempString);
  }
  for(list< string >::iterator i = sortedNames.begin(); i != sortedNames.end(); ++i)
  {
    pair< SortedInputType::iterator,SortedInputType::iterator > bounds;
    bounds = sortedInput.equal_range(*i);
    set< string > newSet;
    for(SortedInputType::iterator j = bounds.first; j != bounds.second; ++j)
    {
      newSet.insert(j->second);
    }
    if(newSet.size() > 1)
    {
      output.push_back(newSet);
    }
    sortedInput.erase(bounds.first, bounds.second);
  }
}