递归地将项添加到矢量

时间:2011-05-14 17:38:32

标签: c++ recursion vector

我正在尝试创建一个递归函数,该函数输出一个字符串向量,该字符串包含给定字符串的所有可能的单词组合(同时保留字母顺序)。基本上,自动校正打字程序的基础,产生类似于iPhone的效果。

vector<string> allPossibleWords(string str, vector<vector<char> > & adjacentKeys)
{
  vector<string> words;

  cout << str << endl;

  if (str.length() == 0)
  {
    return words;
  }

  char firstLetter = str[0];
  string restOf = str.substr(1, str.length() - 1);
  int position = position_in_vector(firstLetter);

  for (int i = 0; i < adjacentKeys[position].size(); i++) 
  {
    string temp(1, adjacentKeys[position][i]);
    words.push_back(temp);
  }

  //allPossibleWords(restOf, adjacentKeys);
}

int position_in_vector(char letter)
{
  return (letter % 97);
}

例如,如果str是“yp”,则输出应该是包含值{“yp”,“tp”,“gp”,“hp”,“up”,“yo”,“to”的向量,“go”,“ho”,“uo”,“yl”,“tl”,“gl”,“hl”,“ul”}。如果str为“y”,则输出应为包含值{“y”,“t”,“g”,“h”,“u”}的向量。

存储在adjacentKeys中的26个向量包含与存储在向量的第一个位置的字母相邻的字母。

a   qwsz
b   vghjn
c   xdfgv
d   zserfcx
//and so on

我坚持使用这个函数,并且无法弄清楚如何递归地构建这个向量。

2 个答案:

答案 0 :(得分:1)

(更新时间:格林尼治标准时间周日21:30:我已经明显改变了我的答案。我认为现在这样做了。)

这是一个完整的程序。我认为还会有其他变化,但我正在努力保持初始解决方案的精神。在str.length()==0时返回单个空单词非常重要。

#include <vector>
#include <iostream>
using namespace std;


vector<string> allPossibleWords(string str, vector<vector<char> > & adjacentKeys)
{
        vector<string> words;

        // cout << "str=" << str << endl;

        if (str.length() == 0)
        {
                words.push_back("");
                return words;
        }

        char firstLetter = str[0];
        // cout << "firstLetter=" << firstLetter << endl;
        int positionInAdjacentKeys = 0;
        while(positionInAdjacentKeys < adjacentKeys.size() && adjacentKeys.at(positionInAdjacentKeys).front() != firstLetter) {
                ++ positionInAdjacentKeys;
        }
        vector<char> & adjacent = adjacentKeys.at(positionInAdjacentKeys);

        string restOf = str.substr(1, str.length() - 1);
        // cout << firstLetter << ":" << restOf << endl;

        // int position = position_in_vector(firstLetter);

        vector<string> recursiveWords = allPossibleWords(restOf, adjacentKeys);

        for (int i = 0; i < adjacent.size(); i++)
        {
                const string temp(1, adjacent[i]);
                // cout << "  temp=" << temp << endl;
                for(vector<string>::const_iterator i = recursiveWords.begin(); i != recursiveWords.end(); i++)
                {
                        // cout << "new word=" <<  temp + *i << endl;
                        words.push_back(temp + *i);
                }
        }
        return  words;
}


int main() {
        vector<vector<char> > adj;
        vector<char> v1;
        v1.clear();
        v1.push_back('p');
        v1.push_back('o');
        v1.push_back('l');
        adj.push_back(v1);
        v1.clear();
        v1.push_back('y');
        v1.push_back('t');
        v1.push_back('g');
        v1.push_back('h');
        v1.push_back('u');
        adj.push_back(v1);
        adj.push_back(v1);

        vector<string> words = allPossibleWords("yp", adj);

        for(vector<string> :: const_iterator i = words.begin(); i != words.end(); i++) {
                cout << *i << endl;
        }
}

返回

答案 1 :(得分:0)

也许是这样的?我没有测试过,因为我没有你的adjacentKeys矩阵。它可能会稍微优化一下,但我不认为这种方法可以很好地扩展。

我建议从不同的角度攻击问题,可能将你的字典存储在某种K-ary tree中,并且有几个指针在树上行走,根据你的邻接矩阵跟随分支。这将停止生成无效的单词(以及随后的查找以检查有效性),因为分支只存在于有效单词存在的位置。

using namespace std;

void allPossibleWordsHelper(const string& str, 
                            string::size_type index,
                            const vector<vector<char> >& adjacentKeys, 
                            vector<string>& results)
{
    if (str.length() == 0)
    {
        return;
    }

    std::string head = (index > 0) ? str.substr(0, index) : "";
    std::string tail = (index < str.length() - 1) ? str.substr(index + 1) : "";

    vector<string> possibleHeads;
    string::size_type headIndex = (str.length() - index) / 2;
    allPossibleWordsHelper(head, headIndex, adjacentKeys, possibleHeads);

    vector<string> possibleTails;
    allPossibleWordsHelper(tail, index + headIndex, adjacentKeys, possibleTails);

    int pos = str[index] - 'a';

    vector<string>::const_iterator headi;
    vector<string>::const_iterator headi_end = possibleHeads.end();

    vector<string>::const_iterator taili;
    vector<string>::const_iterator taili_end = possibleTails.end();

    vector<char>::const_iterator aki;
    vector<char>::const_iterator aki_end = adjacentKeys[pos].end();

    for(headi = possibleHeads.begin(); headi != headi_end; ++headi)
    {
        for (aki = adjacentKeys[pos].begin(); aki != aki_end; ++aki)
        {
            for (taili = possibleTails.begin(); taili != taili_end; ++taili)
            {
                string suggestedWord = *headi + *aki + *taili;

                results.push_back(suggestedWord);
            }
        }
    }
}