如何将函数返回返回特定计数

时间:2016-11-03 05:50:09

标签: c++ arrays c++11 for-loop methods

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

{{1}}

4 个答案:

答案 0 :(得分:0)

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

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

并使用此return语句:

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语句:

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

答案 1 :(得分:0)

虽然你的问题不明确,但我假设你想要在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 创建一个数组,该数组将保存每个字符的计数并使您的函数返回一个数组。

答案 2 :(得分:0)

也许你可以使用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/

的示例

答案 3 :(得分:0)

如果使用无效参数调用,您的函数将返回什么,例如, row > N-2?这个例子表明,你的功能可能会失败,应该有办法说出来。

如果您的函数必须报告成功/失败以及某些结果值,则通常会使用函数返回值报告成功/失败信息。结果值通过OUT参数报告。

这导致了以下代码,我使用struct来聚合结果值。

#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:语句暗示的所有低级内存泄漏检查代码。