C++ 被C+中的矩阵难住+;

C++ 被C+中的矩阵难住+;,c++,algorithm,matrix,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
a
b c
d e f
在这个矩阵中,我们必须找到所有排列,其中第一个字母是‘a’、‘b’或‘c’,第二个字母是‘a’,第三个字母是‘b’或‘c’,第四个字母是‘d’、‘e’或‘f’。在我们的算法中,矩阵的大小在时间之前是未知的。也可能是

a
b
c
d
或者

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

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;
}
int CountTestCases(常量字符串和iTestStr、常量映射和iHashTable)
{
向量矩阵;
string::const_迭代器strIt=iTestStr.begin();
while(strIt!=iTestStr.end())
{
如果(*strIt=='(')
{
++大步走;
字符c=*strIt;
载体tmpVec;
tmpVec.推回(c);
++大步走;
而(*strIt!='))
{
c=*斯特里特;
tmpVec.推回(c);
++大步走;
}
charMatrix.push_back(tmpVec);
}
其他的
{
字符c=*strIt;
载体tmpVec;
tmpVec.推回(c);
charMatrix.push_back(tmpVec);
}
++大步走;
}
返回0;
}

将数据存储为
向量
您始终可以向
向量
添加更多内容,因此您无需事先知道大小

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

以下是伪代码:

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; 
      }
    }     
}
intmain()
{    
向量输出向量;
PassToNextLevel(0,outputVec);
}

函数PassToNextLevel(introwid,vectorWoohoo,我做到了!这是我提出的函数

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);
    }
}
void FindCartisian(常量向量和iCharMatrix、int-iRow、字符串和iWord、向量和iFinalWords)
{
//我们已经到了专栏的末尾,保存成品并返回
如果(iRow+1>iCharMatrix.size())
{
I输入单词。推回(iWord);
返回;
}
//在行中迭代
对于(vector::const_迭代器it=iCharMatrix[iRow]。begin();it!=iCharMatrix[iRow]。end();+it)
{
//附加此位置中的内容
char c=*it;
附加(1,c);
//从这里递归向下钻取
FindCartisian(iCharMatrix、iRow+1、iWord、iFinalWords);
//删除我们最后添加的内容
擦除(iWord.end()-1);
}
}
我突然想到,我可以使用char堆栈而不是字符串,但由于最终产品必须是字符串,因此在最后将堆栈转换为字符串似乎相当麻烦


对于大型数据集,这件事可能会很慢。有什么想法可以让它更快吗?

这正是我所处的位置。这是我无法掌握的递归函数。排列意味着重新排列固定数量的元素。然而,您的示例输出是不同的。您似乎在做笛卡尔积。@M我想OP想这样做通过行上的排列获得与原始矩阵不同的所有矩阵。@JulienLopez如果这是真的,那么第一个答案将是
{acb,a,bc,def}
这与OP的引用不同,
aabd
@M.M我认为
aabd
aabe
,…指的是第一个column@M.M,我当然可能误用了“排列”这个词,如果我误用了,我为我的混淆道歉。但是,我认为你对我要找的东西有正确的想法。太棒了,我想我可以解决这个问题t、 谢谢!我可能遗漏了什么,但我认为这里有一个bug:您应该从“for each”结尾的
outputVec
中删除
currChar
-循环。在代码的当前状态下,所有单词都将始终以
a
开头,因为您永远不会删除它。当您到达输入文件第一行的
b
时,您的
outputVec
中将有
ab
…为什么您要通过值而不是通过引用传递
outputVec
dum,我相信你是对的。如果你看我下面的解决方案,你可以看到我删除了从递归返回后添加的最后一个内容。
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);
    }
}