661.图片平滑器

题目:[https://leetcode-cn.com/problems/image-smoother/description/]
思路:一道直接模拟题目,计算图片的灰度,注意边界控制。
代码:

class Solution {
public:
    int step(int x,int y,string &where,vector<vector<int>> &map){//走路模拟
        if (where=="w") {
            ++x;
        }
        if (where=="s") {
            --x;
        }
        if (where=="d") {
            ++y;
        }
        if (where=="a") {
            --y;
        }
        if (where=="wa") {
            ++x;--y;
        }
        if (where=="wd") {
            ++x;++y;
        }
        if (where=="sa") {
            --x;--y;
        }
        if (where=="sd") {
            --x;++y;
        }
        if (where=="stop") {
            return map[x][y];
        }
        if (x>=0&&x<map.size()&&y>=0&&y<map[0].size()) {//移动合法
            return map[x][y];
        }
        return -1;
    }
    int avg_grayscale(int i,int j,vector<vector<int>> &map){//计算平均灰度
        vector<string> go{"w","s","a","d","wa","wd","sd","sa","stop"};//方向控制
        int sum=0,time=0,temp=0;
        for (string &v:go) {
            temp=step(i, j, v,map);
            if (temp!=-1) {
                sum+=temp;
                ++time;
            }
            
        }
        return sum/time;
    }
    vector<vector<int>> imageSmoother(vector<vector<int>>& M) {
        int row_max=M.size(),col_max=M[0].size();
        vector<int> line(col_max);//初始化行
        vector<vector<int>> ans(row_max,line);//由line初始化矩阵
        for (int i=0; i!=row_max; ++i) {//第i行(i纵向)
            for (int j=0;j!= col_max; ++j) {//第i行第j列(j横向)
                ans[i][j]=avg_grayscale(i, j, M);
            }
        }
        return ans;
    }
};

讨论区[https://leetcode.com/problems/image-smoother/discuss/]
反思:1、多维情况一定要对每个维度对范围熟悉,避免越界产生未定义行为
2、讨论区:可以考虑由于数值只用到0~255即是8位二进制,可以考虑利用原位置中未利用对空间上进行优化,讨论区代码如下

vector<vector<int>> imageSmoother(vector<vector<int>>& M) {
        int m = M.size(), n = M[0].size();
        if (m == 0 || n == 0) return {{}};
        vector<vector<int>> dirs = {{0,1},{0,-1},{1,0},{-1,0},{-1,-1},{1,1},{-1,1},{1,-1}}//方向数组
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                int sum = M[i][j], cnt = 1;
                for (int k = 0; k < dirs.size(); k++) {
                    int x = i + dirs[k][0], y = j + dirs[k][1];
                    if (x < 0 || x > m - 1 || y < 0 || y > n - 1) continue;//越界判定
                    sum += (M[x][y] & 0xFF);//&运算取后8位,中间8位用来保存平均值
                    cnt++;
                }
                M[i][j] |= ((sum / cnt) << 8);//与运算形成平均值(8位)+原始值(8位)的结构
            }
        }
         for (int i = 0; i < m; i++) {//遍历数组,输出中8位平均值
            for (int j = 0; j < n; j++) {
                M[i][j] >>= 8;
            }
         }
        return M;
    }

3、方向数组能极好对简化代码,增加可读性和结构

posted @ 2018-09-19 02:14  Kipper  阅读(409)  评论(0编辑  收藏  举报