【问题标题】:How to use std::find() with a 2d std: array?如何将 std::find() 与 2d std: 数组一起使用?
【发布时间】:2020-05-22 20:31:42
【问题描述】:

我正在编写一个函数CreateGrid(),它试图将std::string 和二维std::array 作为参数,并将std::string 中的各个字符放入数组中。数组的其余部分(如果有空格)应按字母顺序填充字母字符 A-Y(含),前提是它们尚未出现在 std::string 中。每个字符在最终返回的数组中只能出现一次。

所以输入string keyword = "HELO";

输出将是:

赫尔 ○○○○ C D F

注意字符“E”只出现一次。

我正在尝试使用std::find() 来测试字母 AY(故意排除 Z)中的所有字符是否已经在数组中,由于关键字,如果不是,则在插入它之前没有重复.我收到一个编译错误。

代码:

array<array<char,3>,3> CreateGrid(std::string keyword, array<array<char,3>,3> myArray)
{
  char letterToFind = 'A';

  for (int row = (keywordLength/3); row < 3; row++ )
  {
    for (int column = (keywordLength % 3); column < 3; column++)
    {
      auto it = std::find(begin(myArray), end(myArray), letterToFind);
      if ( it == end(myArray) ) // value not in array
      {
        myArray[row][column] = letterToFind;  //insert
      }
      letterToFind++;
    }
  }

  return myArray;
}

int main()
{
  array<array<char,3>,3> myArray = { {'H','E','L'}, {'O','+','+'}, {'+','+','+'} };
  CreateGrid("HELO", myArray);

  return 0;
}

我收到此行的编译错误:

auto it = std::find(begin(myArray), end(myArray), letterToFind);
消息:请参阅使用 [_InIt=std::_Array_iterator,char>(_InIt,const _InIt,const char &)' 的参考::array3>,_Ty=std::array]

如何检查 char 是否已经在数组中,如果没有,则添加它?

【问题讨论】:

    标签: c++


    【解决方案1】:

    这通常不是微不足道的,因为您有嵌套数组。 std::find 只能返回一个指向外层数组的迭代器,如果你需要改变内层数组中的值,这是没有用的。

    但是, 我注意到您实际上并没有使用 it,而是查看是否找到了寻找的元素。因此,我们可以重新定义操作:与其在包含该值的内部数组中查找元素,不如找到包含您要查找的值的任何内部数组:

    auto it = std::find(
        begin(myArray), end(myArray),
        [letterToFind](array<char,3> const & inner) {
            return std::find(begin(inner), end(inner), letterToFind) != end(inner);
        }
    );
    

    如果你找到了这样一个内部数组,那么你就知道该值存在于二维数组中并且可以继续。

    由于您不需要迭代器,您也可以使用 std::any_of 代替:

    bool found = std::any_of(
        begin(myArray), end(myArray),
        [letterToFind](array<char,3> const & inner) {
            return std::find(begin(inner), end(inner), letterToFind) != end(inner);
        }
    );
    

    【讨论】:

      【解决方案2】:

      您的myArray 参数是一个包含array&lt;char,3&gt; 元素的数组。您正在使用 find() 仅搜索该外部数组。所以begin(myArray) 将返回一个枚举array&lt;char,3&gt; 元素的迭代器,并且您无法将单个char 与整个array&lt;char,3&gt; 进行比较,这就是您的find() 调用无法编译的原因。您必须在每个内部数组上循环调用 find() 的外部数组。

      实现这一点的更简单方法是使用查找表来跟踪您已经看到的字符,例如:

      const size_t MaxRows = 3;
      const size_t MaxColumns = 3;
      const size_t MaxCells = MaxRows * MaxColumns;
      
      using gridRow = std::array<char, MaxColumns>;
      using grid = std::array<gridRow, MaxRows>;
      
      grid CreateGrid(const std::string &keyword)
      {
          grid g;
          std::array<bool, 256> lookup{};
          size_t numFilled = 0;
      
          for(size_t i = 0; (i < keyword.size()) && (numFilled < MaxCells); ++i)
          {
              if (!lookup[static_cast<unsigned char>(keyword[i])])
              {
                  lookup[static_cast<unsigned char>(keyword[i])] = true;
                  g[numFilled / 3][numFilled % 3] = keyword[i];
                  ++numFilled;
              }
          }
      
          for(char ch = 'A'; (ch <= 'Y') && (numFilled < MaxCells); ++ch)
          {
              if (!lookup[static_cast<unsigned char>(ch)])
              {
                  g[numFilled / 3][numFilled % 3] = ch;
                  ++numFilled;
              }
          }
      
          return g;
      }
      
      int main()
      {
          grid myArray = CreateGrid("HELO");
          ...
          return 0;
      }
      

      Live Demo

      或者,您可以使用std::setstd::unordered_set 进行查找:

      #include <unordered_set>
      
      const size_t MaxRows = 3;
      const size_t MaxColumns = 3;
      const size_t MaxCells = MaxRows * MaxColumns;
      
      using gridRow = std::array<char, MaxColumns>;
      using grid = std::array<gridRow, MaxRows>;
      
      grid CreateGrid(const std::string &keyword)
      {
          grid g;
          std::unordered_set<char> lookup;
          size_t numFilled = 0;
      
          for(size_t i = 0; (i < keyword.size()) && (numFilled < MaxCells); ++i)
          {
              if (lookup.insert(keyword[i]).second)
              {
                  g[numFilled / 3][numFilled % 3] = keyword[i];
                  ++numFilled;
              }
          }
      
          for(char ch = 'A'; (ch <= 'Y') && (numFilled < MaxCells); ++ch)
          {
              if (lookup.insert(ch).second)
              {
                  g[numFilled / 3][numFilled % 3] = ch;
                  ++numFilled;
              }
          }
      
          return g;
      }
      
      int main()
      {
          grid myArray = CreateGrid("HELO");
          ...
          return 0;
      }
      

      Live Demo

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-10-19
        • 2010-12-20
        • 1970-01-01
        • 1970-01-01
        • 2015-06-21
        • 2014-08-29
        • 1970-01-01
        相关资源
        最近更新 更多