找出二维数组里某一个元素周围的最大值(或最小值),有没有什么高效的方法

woyaoxcode 2014-05-06 06:51:51
小弟不才,写了一个一百行的函数,完全就是if else搭配比较。
虽然问题解决了,但是我在想有没有什么高效的方法?
解释下问题:比如一个3*3的数组

int a[3][3] = {{2, 4, 6}
{1, 3, 5}
{0, 9, 8 }}

找到元素a[1][0]上下左右(只要上下左右)元素中最大的元素是哪个。
考虑到该元素周围某个方向上可能没有元素,我重载了()运算符,用来取二维数组中的值来比较。
拿这个例子来说,结果就是a[1][1]。
我的一百行函数就不贴了,解决方法太不优雅,有没有好的方法呢,求各位指导
...全文
1003 24 打赏 收藏 举报
写回复
24 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
赵4老师 2014-05-12
  • 打赏
  • 举报
回复
仅供参考
//地上一大块由长M米,宽N米共M×N个小块组成的高低不平的区域,地面高度为0,每小块内部是平的,其高度为0~9米不等.
//一场大雨过后,这块区域的积水共多少立方米?
//假设水只会流到正东、正南、正西、正北相邻的且高度较低的小块里;
//而不会流到东北、东南、西北、西南相邻的且高度较低的小块里。
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define M 10
#define N 10
int a[M+4][N+4];//地面高度
int w[M+4][N+4];//水面高度
int sp=0;
int xs[(M+4)*(N+4)];
int ys[(M+4)*(N+4)];
int xx,yy;
int x,y;
int i,h;
int tw;
void push(int py,int px) {
//  printf("%03d %d,%d\n",sp,py,px);
    ys[sp]=py;
    xs[sp]=px;
    if (sp<(M+4)*(N+4)-1) {
        sp=sp+1;
    } else {
        printf("stack overflow!\n");
        exit(1);
    }
}
void pop(void) {
    sp=sp-1;
    yy=ys[sp];
    xx=xs[sp];
}
int check(int cy,int cx,int ch) {
    if (a[cy][cx]<=ch && w[cy][cx]>ch) return 1;
    else return 0;
}
void floodfilling(int hh) {
    push(1,1);
    while (1) {
        if (sp<=0) break;//
        pop();
        if (check(yy,xx,hh)) {
            w[yy][xx]=hh;
            if (check(yy-1,xx  ,hh)) push(yy-1,xx  );
            if (check(yy  ,xx+1,hh)) push(yy  ,xx+1);
            if (check(yy  ,xx-1,hh)) push(yy  ,xx-1);
            if (check(yy+1,xx  ,hh)) push(yy+1,xx  );
        }
    }
    for (y=0;y<=M+3;y++) {
        for (x=0;x<=N+3;x++) {
            printf("%d%d ",a[y][x],w[y][x]);
        }
        printf("\n");
    }
    for (x=0;x<=N+3;x++) printf("---");
    printf("hh=%d\n",hh);
}
void main() {
    //最外圈增加一圈高度9的小块
    for (i=0;i<=M+3;i++) {a[i][0]=9;a[i][N+3]=9;}
    for (i=0;i<=N+3;i++) {a[0][i]=9;a[M+3][i]=9;}

    //次外圈增加一圈高度0的小块
    for (i=1;i<=M+2;i++) {a[i][1]=0;a[i][N+2]=0;}
    for (i=1;i<=N+2;i++) {a[1][i]=0;a[M+2][i]=0;}

    srand(time(NULL));
    for (y=2;y<=M+1;y++) {
        for (x=2;x<=N+1;x++) {
            a[y][x]=rand()%10;//初始地面高度
        }
    }

    for (y=0;y<=M+3;y++) {
        for (x=0;x<=N+3;x++) {
            w[y][x]=9;//初始水面高度9
        }
    }

    printf("当前每小块地面高度水面高度\n",tw);
    for (y=0;y<=M+3;y++) {
        for (x=0;x<=N+3;x++) {
            printf("%d%d ",a[y][x],w[y][x]);
        }
        printf("\n");
    }
    for (x=0;x<=N+3;x++) printf("---");
    printf("hh=9\n");

    for (h=8;h>=0;h--) floodfilling(h);//检查水面高度8到0

    tw=0;
    for (y=2;y<=M+1;y++) {
        for (x=2;x<=N+1;x++) {
            tw+=(w[y][x]-a[y][x]>0)?w[y][x]-a[y][x]:0;
        }
    }
    printf("共积水%d立方米\n",tw);
}
//当前每小块地面高度水面高度
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 09 09 09 09 09 09 09 09 09 09 09 09 99
//99 09 89 49 39 79 79 69 49 79 09 69 09 99
//99 09 19 29 59 39 39 99 09 59 49 79 09 99
//99 09 09 39 59 79 99 29 39 09 69 39 09 99
//99 09 79 59 89 59 09 39 09 49 79 49 09 99
//99 09 09 69 19 99 39 39 19 59 99 29 09 99
//99 09 29 19 39 99 79 29 39 89 79 99 09 99
//99 09 29 29 39 29 89 69 19 89 39 99 09 99
//99 09 99 99 89 79 49 79 89 69 39 09 09 99
//99 09 29 19 29 69 39 89 39 39 99 19 09 99
//99 09 79 39 19 39 19 29 19 89 69 79 09 99
//99 09 09 09 09 09 09 09 09 09 09 09 09 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=9
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 08 08 08 08 08 08 08 08 08 08 08 08 99
//99 08 88 48 38 78 78 68 48 78 08 68 08 99
//99 08 18 28 58 38 38 99 08 58 48 78 08 99
//99 08 08 38 58 78 99 28 38 08 68 38 08 99
//99 08 78 58 88 58 08 38 08 48 78 48 08 99
//99 08 08 68 18 99 38 38 18 58 99 28 08 99
//99 08 28 18 38 99 78 28 38 88 78 99 08 99
//99 08 28 28 38 28 88 68 18 88 38 99 08 99
//99 08 99 99 88 78 48 78 88 68 38 08 08 99
//99 08 28 18 28 68 38 88 38 38 99 18 08 99
//99 08 78 38 18 38 18 28 18 88 68 78 08 99
//99 08 08 08 08 08 08 08 08 08 08 08 08 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=8
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 07 07 07 07 07 07 07 07 07 07 07 07 99
//99 07 88 47 37 77 77 67 47 77 07 67 07 99
//99 07 17 27 57 37 37 99 07 57 47 77 07 99
//99 07 07 37 57 77 99 27 37 07 67 37 07 99
//99 07 77 57 88 57 07 37 07 47 77 47 07 99
//99 07 07 67 17 99 37 37 17 57 99 27 07 99
//99 07 27 17 37 99 77 27 37 88 77 99 07 99
//99 07 27 27 37 27 88 67 17 88 37 99 07 99
//99 07 99 99 88 77 47 77 88 67 37 07 07 99
//99 07 27 17 27 67 37 88 37 37 99 17 07 99
//99 07 77 37 17 37 17 27 17 88 67 77 07 99
//99 07 07 07 07 07 07 07 07 07 07 07 07 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=7
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 06 06 06 06 06 06 06 06 06 06 06 06 99
//99 06 88 46 36 77 77 66 46 77 06 66 06 99
//99 06 16 26 56 36 36 99 06 56 46 77 06 99
//99 06 06 36 56 77 99 26 36 06 66 36 06 99
//99 06 77 56 88 56 06 36 06 46 77 46 06 99
//99 06 06 66 16 99 36 36 16 56 99 26 06 99
//99 06 26 16 36 99 77 26 36 88 77 99 06 99
//99 06 26 26 36 26 88 66 16 88 36 99 06 99
//99 06 99 99 88 77 46 77 88 66 36 06 06 99
//99 06 26 16 26 66 36 88 36 36 99 16 06 99
//99 06 77 36 16 36 16 26 16 88 66 77 06 99
//99 06 06 06 06 06 06 06 06 06 06 06 06 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=6
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 05 05 05 05 05 05 05 05 05 05 05 05 99
//99 05 88 45 35 77 77 66 45 77 05 66 05 99
//99 05 15 25 55 35 35 99 05 55 45 77 05 99
//99 05 05 35 55 77 99 25 35 05 66 35 05 99
//99 05 77 55 88 55 05 35 05 45 77 45 05 99
//99 05 05 66 15 99 35 35 15 55 99 25 05 99
//99 05 25 15 35 99 77 25 35 88 77 99 05 99
//99 05 25 25 35 25 88 66 15 88 35 99 05 99
//99 05 99 99 88 77 45 77 88 66 35 05 05 99
//99 05 25 15 25 66 35 88 35 35 99 15 05 99
//99 05 77 35 15 35 15 25 15 88 66 77 05 99
//99 05 05 05 05 05 05 05 05 05 05 05 05 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=5
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 04 04 04 04 04 04 04 04 04 04 04 04 99
//99 04 88 44 34 77 77 66 44 77 04 66 04 99
//99 04 14 24 55 35 35 99 04 55 44 77 04 99
//99 04 04 34 55 77 99 24 34 04 66 34 04 99
//99 04 77 55 88 55 04 34 04 44 77 44 04 99
//99 04 04 66 14 99 34 34 14 55 99 24 04 99
//99 04 24 14 34 99 77 24 34 88 77 99 04 99
//99 04 24 24 34 24 88 66 14 88 34 99 04 99
//99 04 99 99 88 77 44 77 88 66 34 04 04 99
//99 04 24 14 24 66 34 88 34 34 99 14 04 99
//99 04 77 34 14 34 14 24 14 88 66 77 04 99
//99 04 04 04 04 04 04 04 04 04 04 04 04 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=4
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 03 03 03 03 03 03 03 03 03 03 03 03 99
//99 03 88 44 33 77 77 66 44 77 03 66 03 99
//99 03 13 23 55 35 35 99 04 55 44 77 03 99
//99 03 03 33 55 77 99 24 34 04 66 33 03 99
//99 03 77 55 88 55 04 34 04 44 77 44 03 99
//99 03 03 66 13 99 34 34 14 55 99 23 03 99
//99 03 23 13 33 99 77 24 34 88 77 99 03 99
//99 03 23 23 33 23 88 66 14 88 33 99 03 99
//99 03 99 99 88 77 44 77 88 66 33 03 03 99
//99 03 23 13 23 66 33 88 33 33 99 13 03 99
//99 03 77 33 13 33 13 23 13 88 66 77 03 99
//99 03 03 03 03 03 03 03 03 03 03 03 03 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=3
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 02 02 02 02 02 02 02 02 02 02 02 02 99
//99 02 88 44 33 77 77 66 44 77 02 66 02 99
//99 02 12 22 55 35 35 99 04 55 44 77 02 99
//99 02 02 33 55 77 99 24 34 04 66 33 02 99
//99 02 77 55 88 55 04 34 04 44 77 44 02 99
//99 02 02 66 13 99 34 34 14 55 99 22 02 99
//99 02 22 12 33 99 77 24 34 88 77 99 02 99
//99 02 22 22 33 23 88 66 14 88 33 99 02 99
//99 02 99 99 88 77 44 77 88 66 33 02 02 99
//99 02 22 12 22 66 33 88 33 33 99 12 02 99
//99 02 77 33 12 33 12 22 12 88 66 77 02 99
//99 02 02 02 02 02 02 02 02 02 02 02 02 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=2
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 01 01 01 01 01 01 01 01 01 01 01 01 99
//99 01 88 44 33 77 77 66 44 77 01 66 01 99
//99 01 11 22 55 35 35 99 04 55 44 77 01 99
//99 01 01 33 55 77 99 24 34 04 66 33 01 99
//99 01 77 55 88 55 04 34 04 44 77 44 01 99
//99 01 01 66 13 99 34 34 14 55 99 22 01 99
//99 01 22 12 33 99 77 24 34 88 77 99 01 99
//99 01 22 22 33 23 88 66 14 88 33 99 01 99
//99 01 99 99 88 77 44 77 88 66 33 01 01 99
//99 01 22 12 22 66 33 88 33 33 99 11 01 99
//99 01 77 33 11 33 11 22 11 88 66 77 01 99
//99 01 01 01 01 01 01 01 01 01 01 01 01 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=1
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 00 00 00 00 00 00 00 00 00 00 00 00 99
//99 00 88 44 33 77 77 66 44 77 00 66 00 99
//99 00 11 22 55 35 35 99 04 55 44 77 00 99
//99 00 00 33 55 77 99 24 34 04 66 33 00 99
//99 00 77 55 88 55 04 34 04 44 77 44 00 99
//99 00 00 66 13 99 34 34 14 55 99 22 00 99
//99 00 22 12 33 99 77 24 34 88 77 99 00 99
//99 00 22 22 33 23 88 66 14 88 33 99 00 99
//99 00 99 99 88 77 44 77 88 66 33 00 00 99
//99 00 22 12 22 66 33 88 33 33 99 11 00 99
//99 00 77 33 11 33 11 22 11 88 66 77 00 99
//99 00 00 00 00 00 00 00 00 00 00 00 00 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=0
//共积水40立方米
sniffer12345 2014-05-12
  • 打赏
  • 举报
回复
引用 21 楼 woyaoxcode 的回复:
[quote=引用 18 楼 dianyancao 的回复:] 是不是处理图像,如果元素是整数,并且值域在[0,255] 那么可以用直方图统计,然后新建一副图像,从最大的值开始填充该图像 填充完毕,新建图像即是最大值结果
不是,我只是找一个元素上下左右四个方向上相邻的元素(也就是4个元素)中的最大,而且要的是最大值的位置,并不是要最大值[/quote] 我觉得 你还是说出你想做什么的目的吧,说不定有更好的方式。听你这么讲怎么看起来是想寻找边界啊?
dianyancao 2014-05-11
  • 打赏
  • 举报
回复
求出最大值,最大值的位置也相应的求出了 如果只求一个元素周围的最大值位置 你可以建一个偏移表{{-1,0},{1,0},{0,1},{0,-1}} 然后循环遍历该偏移表将当前元素位置的x,y值分别加上偏移值 在其中用判断,记录最大值和最大值的位置即可
woyaoxcode 2014-05-11
  • 打赏
  • 举报
回复
引用 18 楼 dianyancao 的回复:
是不是处理图像,如果元素是整数,并且值域在[0,255] 那么可以用直方图统计,然后新建一副图像,从最大的值开始填充该图像 填充完毕,新建图像即是最大值结果
不是,我只是找一个元素上下左右四个方向上相邻的元素(也就是4个元素)中的最大,而且要的是最大值的位置,并不是要最大值
woyaoxcode 2014-05-11
  • 打赏
  • 举报
回复
引用 15 楼 FancyMouse 的回复:
根据你查询之间有多少修改,可以有不同程度的优化。
请问您说的查询是什么意思?
woyaoxcode 2014-05-11
  • 打赏
  • 举报
回复
引用 14 楼 ilikehigame 的回复:
[quote=引用 楼主 woyaoxcode 的回复:] 小弟不才,写了一个一百行的函数,完全就是if else搭配比较。 虽然问题解决了,但是我在想有没有什么高效的方法? 解释下问题:比如一个3*3的数组

int a[3][3] = {{2, 4, 6}
               {1, 3, 5}
               {0, 9, 8 }}
找到元素a[1][0]上下左右(只要上下左右)元素中最大的元素是哪个。 考虑到该元素周围某个方向上可能没有元素,我重载了()运算符,用来取二维数组中的值来比较。 拿这个例子来说,结果就是a[1][1]。 我的一百行函数就不贴了,解决方法太不优雅,有没有好的方法呢,求各位指导
用一个循环就行了,循环里面去寻找最大的数[/quote] 我只是找一个元素上下左右四个方向上相邻的元素(也就是4个元素)中的最大,并返回位置
FancyMouse 2014-05-09
  • 打赏
  • 举报
回复
根据你查询之间有多少修改,可以有不同程度的优化。
  • 打赏
  • 举报
回复
引用 楼主 woyaoxcode 的回复:
小弟不才,写了一个一百行的函数,完全就是if else搭配比较。 虽然问题解决了,但是我在想有没有什么高效的方法? 解释下问题:比如一个3*3的数组

int a[3][3] = {{2, 4, 6}
               {1, 3, 5}
               {0, 9, 8 }}
找到元素a[1][0]上下左右(只要上下左右)元素中最大的元素是哪个。 考虑到该元素周围某个方向上可能没有元素,我重载了()运算符,用来取二维数组中的值来比较。 拿这个例子来说,结果就是a[1][1]。 我的一百行函数就不贴了,解决方法太不优雅,有没有好的方法呢,求各位指导
用一个循环就行了,循环里面去寻找最大的数
Symfund 2014-05-09
  • 打赏
  • 举报
回复
哈:从八个随机数当中找出最大的那一个,目前世界上最优的算法是什么?
woyaoxcode 2014-05-09
  • 打赏
  • 举报
回复
引用 10 楼 lm_whales 的回复:
假设数据是 第1个窗口 中心元素 第2个窗口 中心元素 012 34 012 123 123 45 123 2 234 3 345 67 345 345 列因为变了一列所以直接重算 4>3,2>1 所以这一行最小值变大,最大值也变大, 需要重算最小,最大值直接替换为4 即可。 还可以看看,被换掉的元素,是否最大最小,从而优化比较次数。 PS: 如果只有3*3个元素,不做这个优化也问题不大。 如果有5*5 或者更多,那这么处理还是要快一点的
不太懂八叉树,回头我再仔细看一看,谢谢你
dianyancao 2014-05-09
  • 打赏
  • 举报
回复
是不是处理图像,如果元素是整数,并且值域在[0,255] 那么可以用直方图统计,然后新建一副图像,从最大的值开始填充该图像 填充完毕,新建图像即是最大值结果
l_journey_91 2014-05-09
  • 打赏
  • 举报
回复
其实很多STL类都有排序功能,稍微变换一下就可以为你自己排序了
l_journey_91 2014-05-09
  • 打赏
  • 举报
回复
不知道你做的是c还是c++ 如果是c的话,可以分别求出每一列的最值,然后求这些最值的最大最小值. 如果是c++的话 就简单多了. 教你一个最简单的: std::map<int,int> my_map; for(int i = 0; i <row; ++i) { for(int j = 0 ;j<col; ++j) if(my_map.find( a[i][j] ) == m_map.end() ) my_map.insert(std::makepare(a[i][j],0) ); } my_map.begin().left 就是最小值; (--my_map.end() ).left 就是最大值.
lm_whales 2014-05-08
  • 打赏
  • 举报
回复
假设数据是 第1个窗口 中心元素 第2个窗口 中心元素 012 34 012 123 123 45 123 2 234 3 345 67 345 345 列因为变了一列所以直接重算 4>3,2>1 所以这一行最小值变大,最大值也变大, 需要重算最小,最大值直接替换为4 即可。 还可以看看,被换掉的元素,是否最大最小,从而优化比较次数。 PS: 如果只有3*3个元素,不做这个优化也问题不大。 如果有5*5 或者更多,那这么处理还是要快一点的
幻夢之葉 2014-05-08
  • 打赏
  • 举报
回复
用索引的方法,就是找出你当前索引的周围元素的索引(要判断是否边界)
woyaoxcode 2014-05-07
  • 打赏
  • 举报
回复
引用 8 楼 lm_whales 的回复:
每次一行更新的数据里,看看有没有更新最大最小值就行了,更新了就重算, 没更新,只需要比较新数据 和最值就可以了 垂直直接计算,如果窗口开成N行所有列数据,那么列数据也可以这样处理 边界特殊处理一下就行了
没太懂啊,能麻烦您举个例子吗
lm_whales 2014-05-06
  • 打赏
  • 举报
回复
每次一行更新的数据里,看看有没有更新最大最小值就行了,更新了就重算, 没更新,只需要比较新数据 和最值就可以了 垂直直接计算,如果窗口开成N行所有列数据,那么列数据也可以这样处理 边界特殊处理一下就行了
lm_whales 2014-05-06
  • 打赏
  • 举报
回复
8叉树,或者维持一个9元素窗口
woyaoxcode 2014-05-06
  • 打赏
  • 举报
回复
引用 5 楼 mujiok2003 的回复:
[quote=引用 3 楼 woyaoxcode 的回复:] [quote=引用 1 楼 merlinfang 的回复:] 这有啥高效的,算法复杂度很明显就是4次比较
而且每增加一维,增加一个外层if会增加很多行[/quote] 不是二维吗?[/quote] 不好意思,我说错了,是一行一列,我的意思是不要最大值,而是要最大的位置,不过这个方法给了我一点启发,可以给不存在的位置的tmp[ ]赋个-65535,然后tmp[ ]中一定是按顺序的上下左右四个数,找到最大的,比较之后判断i的值,就能判断位置了,但是还是不优雅啊,还有其他方法吗,先谢谢您了
mujiok2003 2014-05-06
  • 打赏
  • 举报
回复
引用 3 楼 woyaoxcode 的回复:
[quote=引用 1 楼 merlinfang 的回复:] 这有啥高效的,算法复杂度很明显就是4次比较
而且每增加一维,增加一个外层if会增加很多行[/quote] 不是二维吗?
加载更多回复(4)
发帖
C++ 语言

6.3w+

社区成员

C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
帖子事件
创建了帖子
2014-05-06 06:51
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下