如何返回一个函数返回特定的计数

How to a function return return specific counts

本文关键字:返回 函数 何返回 一个      更新时间:2023-10-16

下面是计算网格中每个字符的函数。我想让这个函数返回每个字符的计数,但我卡住了。请,我如何改进下面的函数,以便我可以返回我需要处理我的其他方法的每个计数。

int getNeighborhood(const char** grid, int N, int row, int col, int& bCount, int& fCount, int& rCount, int& gCount){
   int currRow;
   int currCol;
   int countB = 0;
   int countF = 0;
   int countR = 0;
   int countG = 0;
   //loop through all 8 grids surrounding the current row and column.
   for(int i = -1; i < 2; i++)            
   {
      for(int j = -1; j < 2; j++){
         currRow = row + i;               //current row.
         currCol = col + i;               //current column.
         if(currRow >= 0 && currRow < N && currCol >= 0 && currCol < N){
            if(grid[row][col] == 'B')
            {
               ++countB;
            }
            if(grid[row][col] == 'F')
            {
               ++countF;
            }
            if(grid[row][col] == 'R')
            {
               ++countR;
            }
            if(grid[row][col] == 'G')
            {
               ++countG;
            }
         }
      }
   //return statement required
   }

也许你可以使用std::map

std::map<char,int> getNeighborhood(const char** grid, int N, int row, int col){
    int currRow;
    int currCol;
    //contain all character to count
    std::string chElementToCount = "BFGR"; 
    //The frequency is a map <char,int> correspond to <character to count, frequency>
    std::map<char, int> frequency; 
    // intialize all frequency by 0
    for (auto& ch: chElementToCount) {
        frequency.insert(std::make_pair(ch,0));
    }
    for(int i = -1; i < 2; i++)            
    {
        for(int j = -1; j < 2; j++){
            currRow = row + i;               //current row.
            currCol = col + i;               //current column.
            // just get value of current char for easier later access
            auto ch = grid[row][col];
            if(currRow >= 0 && currRow < N && currCol >= 0 && currCol < N){
                // the current char is a desired-to-count character then increase it frequency
                if (chElementToCount.find(ch) != std::string::npos)
                    frequency[ch]++;
            }
        }
    }
    return frequency;
}

这是一个使用std::map http://www.cplusplus.com/reference/map/map/map/

的例子

虽然你的问题不清楚,我假设你想在bCount, fCount, rCount, gCount中获得字符计数。有两种可能的解决方案

解决方案1 使用指针获取计数,不返回任何值

void getNeighborhood(const char** grid, int N, int row, int col, int *countB , int *countF , int *countR, int *countG ) {
int currRow;
int currCol;
*countB = 0;
*countF = 0;
*countR = 0;
*countG = 0;
for(int i = -1; i < 2; i++)            
{
   for(int j = -1; j < 2; j++){
     currRow = row + i;              
     currCol = col + i;               
     if(currRow >= 0 && currRow < N && currCol >= 0 && currCol < N){
        if(grid[row][col] == 'B')
        {
           ++*countB;
        }
        if(grid[row][col] == 'F')
        {
           ++*countF;
        }
        if(grid[row][col] == 'R')
        {
           ++*countR;
        }
        if(grid[row][col] == 'G')
        {
           ++*countG;
        }
     }
  }
}

现在调用函数,为它传递每个字符计数的指针

解决方案2 创建一个数组来保存每个字符的计数,并使函数返回一个数组。

一个可能的解决方案是使用std::tuple。首先将函数签名更改为:

std::tuple<int,int,int,int> getNeighborhood(const char** grid, int N, int row, int col) 

并使用这个返回语句:

return std::make_tuple(countB,countF,countR,countG);

由于它们都是相同的类型,您也可以使用std::array:

std::array<int,4> getNeighborhood(const char** grid, int N, int row, int col) 

并使用这个返回语句:

return std::array<int,4>{{countB,countF,countR,countG}};

如果使用无效参数调用,例如row > N-2,您的函数将返回什么?这个例子表明,您的函数可能会失败,并且应该有一种方式来说明它。

在函数必须报告成功/失败和一些结果值的情况下,成功/失败信息通常与函数返回值一起报告。结果值通过OUT参数报告。

这导致了下面的代码,其中我使用了一个结构体来聚合结果值。

#include <cstdint>
#include <iostream>
//#include <vector>
struct CountResult
{
    size_t B;
    size_t F;
    size_t R;
    size_t G;
    CountResult()
        : B(0)
        , F(0)
        , R(0)
        , G(0)
    {}
    void Reset()
    {
        B = 0; F = 0; R = 0; G = 0;
    }
};
std::ostream& operator<<(std::ostream& stm, const CountResult& x)
{
    stm << "{ B = " << x.B << ", F = " << x.F << ", R = " << x.R << ", G = " << x.G << "}";
    return stm;
}
bool GetNeighborhood(const char * const * const grid, size_t N, size_t row, size_t col, CountResult & result)
{
    if (nullptr == grid)
        return false;
    // Range check. Operation only allowed for squares with a full border.
    if (row > (N - 2) || row < 1 || col > (N - 2) || col < 1)
        return false;
    result.Reset();
    for(int16_t r = -1; r < 2; r++)
        for (int16_t c = -1; c < 2; c++)
        {
            if (!(r == 0 && c == 0))
            {
                switch (grid[row + r][col + c])
                {
                case 'B': result.B++; break;
                case 'F': result.F++; break;
                case 'R': result.R++; break;
                case 'G': result.G++; break;
                default: // illegal value in grid!
                    return false;
                }
            }
        }
    return true;
}
int main(int argc, const char *argv[])
{
    const size_t N = 11;
    char **grid = new char *[N]; // TODO: check for nullptr (out of memory)
    for (size_t r = 0; r < N; r++)
    {
        grid[r] = new char[N]; // TODO: check for nullptr (out of memory)
        for (size_t c = 0; c < N; c++)
            grid[r][c] = 'G';
    }
    CountResult result;
    if (GetNeighborhood(grid, N, 5, 5, result))
    {
        std::cout << "Result = " << result << std::endl;
    }
    else
    {
        std::cout << "GetNeighborhood() returned false." << std::endl;
    }
    // TODO: delete[] the rows and the grid itself.
    return 0;
}

由于这段代码在main中运行,所以我没有费心为堆分配的网格编写清理代码。通常,应该这样做。

说到通常,通常您会使用std::vector< std::vector<char> >或类似的方法来避免我在TODO:语句中暗示的所有低级内存泄漏检查代码。