连接的组件程序产生错误的输出

时间:2018-08-21 15:55:31

标签: c++ c++11 recursion graph connected-components

我正在研究一个程序,该程序接收5x5的字符数组,并找到最长的相同字符列表,连接的意思是相邻的上下左右(意为对角线)。但是,输出关闭1时,输入为6而不是正确的7:

a b c c b
a c b c c
c a a b a
b b a a c
a a a b a

有人可以帮助我找到我的代码中的错误吗? (我的代码在下面)

详细信息:缺少的字符位于索引[3] [3](索引从0开始)。当我测试look()函数时,它正常工作,当我将3传递给row并将2传递给col时,它将[3] [3]添加到要返回的最终向量中,但是我认为确实有不能随便递出。

我已经进行了调试,但没有成功,您可以在我的代码中看到调试打印。

#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
#include <utility>

using namespace std;
char grid[5][5];
bool seen[5][5];
int cnt = 1;
int maxn = 0;

vector<pair<int, int>> look(int row, int col)
{
    //
    vector<pair<int, int >> node_list;
    if (row != 0)
        if (grid[row - 1][col] == grid[row][col])
            if (!seen[row - 1][col])
                node_list.push_back(make_pair(row - 1, col));
    if (row != 4)
        if (grid[row + 1][col] == grid[row][col])
            if (!seen[row+1][col])
                node_list.push_back(make_pair(row + 1, col));
    if (col != 0)
        if (grid[row][col - 1] == grid[row][col])
            if (!seen[row][col-1])
                node_list.push_back(make_pair(row, col - 1));
    if (col != 4)
        if (grid[row][col + 1] == grid[row][col])
            if (!seen[row][col+1])
                node_list.push_back(make_pair(row, col + 1));
    if (binary_search(node_list.begin(), node_list.end(), make_pair(2, 2)))
        cout << "HAPPENED^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" << "\n";
    return node_list;
}

void search(int row, int col)
{
    for (pair<int, int> a : look(row, col))
    {
        if (!seen[a.first][a.second])
        {
            seen[a.first][a.second] = true;
            cnt++;
            cout << "COUNTED and now SEARCHING " << a.first << " " << a.second << "\n";
            cout << "search about to be called on " << a.first << " " << a.second << "\n";
            search(a.first, a.second);
        }
    }
    if (cnt > maxn)
        maxn = cnt;
    cout << "CNT: " << cnt << "\n";
    cnt = 1;
    return;
}

int main()
{
    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            cin >> grid[i][j];
            seen[i][j] = false;
        }
    }

    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            if (!seen[i][j])
            {
                cout << "INITIALLY SEARCHING: " << i << " " << j << "\n";
                seen[i][j] = true;
                cout << "search about to be called on " << i << " " << j << "\n";
                search(i, j);
            }
            else
                cout << "NO INITIAL SEARCH, SEEN: " << i << " " << j << "\n";
        }
    }
    cout << maxn << "\n";
    return 0;
}

1 个答案:

答案 0 :(得分:1)

问题是您正在递归使用search,但在结尾处无条件地重置了cnt

可以在只有3个字符的简单“面板”上演示此问题:

a a a

假设我们从search开始a。它调用look,并被告知检查另外两个地方:左侧的a和右侧的asearch然后自称,例如左边的a。此时的cnt2,左边a和中间seen的{​​{1}}都设置为true。这第二个递归search调用再次要求look查找附近的a,但是这次已经全部看到了。这样第二个search完成了,将maxn设置为2,并将重置cnt设置为1 。现在,我们回到了递归的第一级,并转到右侧的a。不用说,我们已经舍弃了在左侧数a的那一次。

这里的问题是,您没有将“从此处开始搜索”与“递归搜索附近的字段”区分开来。当前search的最后两行属于后者,但不属于前者。我建议:

void searchRecursive(int row, int col)
{
    for (pair<int, int> a : look(row, col))
    {
        if (!seen[a.first][a.second])
        {
            seen[a.first][a.second] = true;
            cnt++;
            searchRecursive(a.first, a.second);
        }
    }
}

void startSearchFrom(int row, int col)
{
    cnt = 1;
    seen[i][j] = true;
    searchRecursive(row, col);
    if (cnt > maxn)
        maxn = cnt;
    cout << "CNT: " << cnt << "\n";
}

这很好地分离了这些问题。

进一步的改进将是摆脱所有的全球状态。尽管seen从未被重置,但并不是立即显而易见的(尽管是正确的)算法仍然可以正常工作,并且要验证cnt的正确使用需要记住 all 的所有位置。用来。如果每个searchRecursive都返回找到的几个看不见的位置,则验证结果正确是不容易的。