【问题标题】:Find in Custom Class Vector在自定义类向量中查找
【发布时间】:2016-11-21 13:13:50
【问题描述】:


我正在练习这段代码(来自 LeetCode),以便在 C++ 中做得更好。不幸的是,我无法让“find”正常工作。
此代码用于从 char 类型的向量(即 board)中搜索 word,而无需两次访问同一个字母(visitedSoFar跟踪字母visitSoFar的x,y位置)。
Node 类的向量用于存储到目前为止访问过的位置。
这是我写的sn-p代码:

class Node{
    private:
        int x;
        int y;

    public:
        Node(int a, int b):x(a),y(b){};
        bool operator==(Node newNode){
            if(this->x == newNode.x && this->y == newNode.y)
                return true;
            else 
                return false;
        }
};

class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
        vector <Node> visitedSoFar;

        for(int r =0; r< board.size(); r++){
            for(int c=0; c<board[r].size(); c++){
                if(board[r][c] == word.at(0)){

                if(search(board, word, visitedSoFar, board[r].size(), r, c))
                    return true;
                }
            }
        }
        return false;
    }

    private:
    bool search(vector<vector<char>>& board, string word, vector<Node>& visitedSoFar, int size, int r, int c){
        Node newNode(r,c);
        visitedSoFar.push_back(newNode);

        if(word.size() == 1)
            return true;

        Node toSearch1(r-1,c);
        if(r-1 >= 0 && find(visitedSoFar.begin(), visitedSoFar.end(), toSearch1) == visitedSoFar.end()){
            if(board[r-1][c] == word.at(1))
                if(search(board, word.substr(1), visitedSoFar, size, r-1, c))
                    return true;
        }

        Node toSearch2(r+1,c);
        if(r+1 < size && find(visitedSoFar.begin(), visitedSoFar.end(), toSearch2) == visitedSoFar.end()){
            if(board[r+1][c] == word.at(1))
                if(search(board, word.substr(1), visitedSoFar, size, r+1, c))
                    return true;
        }

        Node toSearch3(r,c-1);
        if(c-1 >= 0 && find(visitedSoFar.begin(), visitedSoFar.end(), toSearch3) == visitedSoFar.end()){
            if(board[r][c-1] == word.at(1))
                if(search(board, word.substr(1), visitedSoFar, size, r, c-1))
                    return true;
        }

        Node toSearch4(r,c+1);
        if(c+1 < size && find(visitedSoFar.begin(), visitedSoFar.end(), toSearch4) == visitedSoFar.end()){
            if(board[r][c+1] == word.at(1))
                if(search(board, word.substr(1), visitedSoFar, size, r, c+1))
                    return true;
        }
        visitedSoFar.pop_back();
        return false;
    }
};

如果我对 find 发表评论,我会得到正确的输出,但这不适用于所有测试用例。

谢谢。

编辑
在方法搜索中,更正了 if 语句以检查 (r+1) 和 (c+1) 的大小。

编辑
单词可以由顺序相邻单元格的字母构成,其中“相邻”单元格是水平或垂直相邻的单元格。同一个字母单元格不能多次使用。

编辑
设计错误:查找操作应该无法找到(表明该节点到目前为止尚未访问过)然后继续在其中进行搜索。因此将 find 更改为 ==visitedSoFar.end() 而不是 !=visitedSoFar.end()。

【问题讨论】:

  • 您没有给我们main 程序、您正在测试的数据或预期的输出。 -- 我正在练习这段代码(来自 LeetCode)以更好地使用 C++ -- 并且要“更好地使用 C++”需要你通过学习如何使用调试器来获得调试技能,而不仅仅是写个程序,希望能行,不行就去SO。
  • 建议:Solution 类没有多大意义,它不存储任何状态。它的方法看起来几乎像 C 代码。我会将class 更改为namespace,或者使boardvisitedSoFar 班级成员
  • 您确定要检查 c+1 和 r+1 >=0 吗?不应该检查是否超过了电路板的尺寸?类似 c+1
  • @PaulMcKenzie 我来自 C 的背景,因此我的代码编写风格类似于 C。
  • @PrameetSinghKohli -- 我从未提到过C 编程,但更重要的是,您仍然没有提供minimal reproducible example,强调完成

标签: c++ class vector stl iterator


【解决方案1】:

我认为您应该使用更简单的解决方案设计。 检查每个板点背后的想法很可能是不必要的工作,对吧?使用您的方法,您会不断检查工作是否已经完成。此检查包括对每个搜索步骤的板进行线性搜索(每个节点将在某个时间保存)。这意味着您几乎可以避免检查它,因为要完成的工作几乎相同。

因此,一个快速编码的解决方案应该是这样的。

bool row_contains_word(vector<char> const& row, string word)
{
  if(word.size() > row.size())
    throw std::invalid_argument("Word is longer then the row!!");

  // linear search for the word in board
  for(int i = 0; i < row.size() - word.size(); ++i) // start point
  {
    // check realtive to the start point if its the word there
    for(int j = 0; j < word.size(); ++j) 
    {
      if(row[i+j] != word[j])
        break; // we can continue to check the next position
      // last position we check here, and match means its the word
      else if(j == (word.size() - 1) && row[i+j] == word[j])
        return true;
    }
  }
  return false;

使用这个函数(我不认为它是一个很好的方法来完成它,只是举个例子)你可以简单地循环:

for(int r = 0; r < board.size(); ++r)
{
  if(row_contains_word(board[r], word))
     return true;
}
// and same with colums as well

正如 cmets 中所述,Solution 不是一个类的候选者。 可以这样写:

namespace Solution
{
  bool search(vector<vector<char>> const& board, string word); // implementaion follows

  namespace // anonymous namespace, not accessible from the outside world, but only this compilation unit(.cpp file)
  {
    bool row_contains_word(vector<char> const& row, string word);
    bool col_contains_word(/*vector<char> const& row,*/ string word); // this needs more work, since the col is a little different
  }
}

这可以将实现隐藏在决定是否包含在板中的单词的界面中的搜索。

【讨论】:

  • 感谢 Black Moses 和 @jonas_toth 将我引向命名空间。事实上,这是维护代码而不是使用“类解决方案”的正确方法。但是,由于我正在使用一个网站来练习 C++ 编码,所以在已经给我练习的模板中我几乎没有发言权。现在,我正在集中精力为什么 find 是否正确实施或者我在这里遗漏了什么?
猜你喜欢
  • 1970-01-01
  • 2015-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多