1. 程式人生 > >回溯法應用

回溯法應用

問題:設計一個函式,來判斷在一個矩陣中是否存在一條包含某字串所有字元的路徑。路徑可以從矩陣中的任意一格開始,每一步可以在矩陣中向左、右、上、下移動一格。如果一條路徑經過了矩陣的某一格,那麼該路徑就不能再次進入該格。

解題思路:這是一個回溯法的應用。首先,在矩陣中任選一個格子作為路徑的起點,如果矩陣中某個格子的字元為ch,並且這個格子將對應於路徑上的第i個字元。如果路徑上的第i個字元不是ch,那麼這個格子不可能處在路徑上的第i個位置。如果路徑上的第i個字元正好是ch,那麼到相鄰的格子尋找路徑上的第i+1個字元。除了矩陣邊界上的格子外,其他格子都有4個相鄰的格子。重複這個過程,知道路徑上的所有字元都在矩陣中找到相應的位置。路徑可以被看成一個棧,當在矩陣中定位了路徑中前n個字元的位置後,在與第n個字元對應的格子周圍都沒有找到第n+1個字元,這時候就只好回退到路徑的第n-1個字元,重新定位第n個字元。由於不能重複進入一個格子,所以還需要定義和字元矩陣大小一樣的bool值來表示該格子是否可以進入。

bool bPathker(const char *matrix, int row, int col, int i, int j, const char *str, int                   
               &pathlen, bool *isvaliable)
{
    if(str[pathlen] == '\0')
        return true;

    bool hasPath = false;
    if(i >= 0 &&  i < row && j >= 0 && j < col 
        && matrix[i * row + j] == str[pathlen]
        && !isvaliable[i * row + j])
    {
        ++pathlen;
        isvaliable[i * row + j] = true;

        hasPath = bPathker(matrix, row, col, i, j-1, str, pathlen, isvaliable)
               || bPathker(matrix, row, col, i-1, j, str, pathlen, isvaliable)
               || bPathker(matrix, row, col, i, j+1, str, pathlen, isvaliable)
               || bPathker(matrix, row, col, i+1, j, str, pathlen, isvaliable);

        if(!hasPath)
        {
            --pathlen;
            isvaliable[i * row + j] =false;
        }
    }


    return hasPath;
}

bool bPath(char *matrix, int row, int col, char *str)
{
    if(matrix == nullptr || row < 1 || col < 1 || str == nullptr)
        return false;

    bool *isvaliable = new bool[row * col];
    memset(isvaliable, 0, row*col);
    
    int pathlen = 0;
    for(int i = 0; i < row; i++)
    {
        for(int j = 0; j < col; j++)
        {
            if(bPathker(matrix, row, col, i, j, str, pathlen, isvaliable))
            {
                return true;
            }
        }
    }

    delete[] isvaliable;

    return false;
}