在C ++中被Matrix难倒

时间:2016-05-24 08:00:10

标签: c++ algorithm matrix

我有一个看似简单的问题,但对于我的生活,我无法弄明白。基本上,我正在寻找的是如何找到非对称矩阵的所有排列,其中某些值必须保持在某些位置。解释这个的最简单方法是用一个例子......

我们说我们有以下内容......

a b c
a
b c
d e f

在此矩阵中,我们必须找到所有排列,其中第一个字母是' a',' b'或' c',第二个字母是' a',第三个字母是' b'或者' c',第四个字母是' d'' e'或者' f'。在我们的算法中,矩阵的大小不是提前知道的。它也可以......

a
b
c
d

...或

a b c d
e f g h
i j k l
m n o p

在我的第一个例子中,我可以通过观察看到可能性是:

aabd
aabe
aabf
aacd
aace
aacf
babd
babe
babf
bacd
bace
bacf
cabd
cabe
cabf
cacd
cace
cacf

但是,我无法弄清楚算法。任何人都可以帮助我解决这个问题吗?如果我提前知道尺寸,我可以做到,但我不知道。我觉得递归函数就是答案,但我无法看到它。

编辑:这是我到目前为止将代码值放入矩阵的代码。在某些情况下,价值是独立的,而在其他情况下,它是由多个值组成的,用括号括起来......

int CountTestCases(const string &iTestStr, const map<string::size_type, string::size_type> &iHashTable)
{
    vector<vector<char>> charMatrix;

    string::const_iterator strIt = iTestStr.begin();

    while(strIt != iTestStr.end())
    {
        if(*strIt == '(')
        {
            ++strIt;
            char c = *strIt;
            vector<char> tmpVec;
            tmpVec.push_back(c);
            ++strIt;

            while(*strIt != ')')
            {
                c = *strIt;
                tmpVec.push_back(c);
                ++strIt;
            }

            charMatrix.push_back(tmpVec);
        }

        else
        {
            char c = *strIt;
            vector<char> tmpVec;
            tmpVec.push_back(c);
            charMatrix.push_back(tmpVec);
        }

        ++strIt;
    }

    return 0;
}

3 个答案:

答案 0 :(得分:2)

这是伪代码:

int main()
{    
  vector<char> outputVec;
  PassToNextLevel(0, outputVec); 
}


function PassToNextLevel(int rowId, vector<char) outputVec)
{
    for each char 'currChar' in the 'charMatrix[rowId]'
    { 
      outputVec.push_back(currChar);
      PassToNextLevel(rowId++, outputVec); // recursive call, pass by value

      if(rowId == rowSize-1) { // last row
        print outputVec; 
      }
    }     
}

答案 1 :(得分:1)

将数据存储为vector<vector<char>>,您始终可以向vector添加更多内容,因此您无需知道之前的尺寸。

是的,你需要做一个递归。在每个级别,您从对应于该级别的向量中选择一个元素,并递归调用下一级别。当你用完向量时,你就有了解决方案。

答案 2 :(得分:0)

哇哇,我做到了!这是我想出的功能......

void FindCartisian(const vector<vector<char>> &iCharMatrix, int iRow, string &iWord, vector<string> &iFinalWords)
{
    //We've reached the end of the column, save the finished product and return
    if(iRow + 1 > iCharMatrix.size())
    {
        iFinalWords.push_back(iWord);
        return;
    }

    //Iterate across the row
    for(vector<char>::const_iterator it = iCharMatrix[iRow].begin(); it != iCharMatrix[iRow].end(); ++it)
    {
        //Append what is in this position
        char c = *it;
        iWord.append(1, c);

        //Drill down recursively from here
        FindCartisian(iCharMatrix, iRow + 1, iWord, iFinalWords);

        //Erase the last thing we added
        iWord.erase(iWord.end() - 1);
    }
}

我想到我可以使用char堆栈而不是字符串,但由于最终产品必须是一个字符串,所以在最后将堆栈转换为字符串似乎相当麻烦。

对于大型数据集,这件事虽然很慢但是很慢。关于如何加快速度的任何想法?