算法-數組:找出符合某條件的最大矩形區域

import java.lang.String;

class Point {

    private int x = 0;
    private int y = 0;        //點的(X,y)座標;數組表示爲:arr[y][x]

    Point() {}
    Point(int pX, int pY){ setPoint(pX, pY); }
    Point(Point point){ setPoint(point); }
    public int getX(){ return x; }
    public int getY(){ return y; }
    public void setPoint(int pX, int pY) {
        x = pX;
        y = pY;
    }
    public void setPoint(Point point) {
        x = point.getX();
        y = point.getY();
    }

    public Point right(){ return new Point((x+1),y); }
    public void right(int n){ x = x + n; }
    public Point down(){ return new Point(x,(y+1)); }
    public void down(int n){ y = y + n; }
    public Point rightdown(){ return new Point( (x+1), (y+1) ); }
    public Point newPointBy(int X,int Y){ return new  Point( (x+X), (y+Y) ); }
    public Point newPointBy(Point point){ return newPointBy( point.getX(), point.getY() ); }
}

class Rect {

    private Point pStart;        //矩形的左上座標
    private Point pEnd;                //矩形的右下座標

    Rect() {
        pStart = new Point();
        pEnd   = new Point();
    }
    Rect(int pX, int pY) {
        pStart = new Point(pX,pY);
        pEnd   = new Point(pX,pY);
    }
    Rect(int pSX, int pSY,int pEX, int pEY) {
        pStart = new Point(pSX,pSY);
        pEnd   = new Point(pEX,pEY);
    }
    Rect(Point pS, Point pE) {
        pStart = new Point(pS);
        pEnd   = new Point(pE);
    }

    public Point getStartPoint(){ return pStart; }
    public Point getEndPoint(){ return pEnd; }
    public void setRectStart(Point point){ pStart.setPoint(point); }
    public void setRectStart(int pX,int pY){ pStart.setPoint(pX,pY); }
    public void setRectEnd(Point point){ pEnd.setPoint(point); }
    public void setRectEnd(int pX,int pY){ pEnd.setPoint(pX,pY); }
    public void setRect(Point pS, Point pE){
        pStart.setPoint(pS);
        pEnd.setPoint(pE);
    }

    public int getAcre() {
        return 0;
    }
    public int getRound() {
        return 0;
    }

}

class Method {

    private int[][] ary;
    private int X,Y;

    //綁定Method的操作數組;
    public boolean arrBind(int[][] arrData) {
        if(arrData.length>=2) {
            if(arrData[1].length>=2) {
                ary = arrData;
                return true;
            }
        }
        showFaildString();
        ary = null;
        return false;
    }
    public boolean arrBind(int x, int y) {

        if( (x>20)||(y>20) ) {
            showFaildString();
            return false;
        }
        ary = new int[y][x];
        for(int i=0; i<y; i++) {
            for(int j=0; j<x; j++) {
                ary[i][j] = random_01();
            }
        }
        return true;
    }
    public void arrDisConnect() {
        ary = null;
    }

    public Rect maxArea() {

        if(!checkBind()) return null;
        boolean bFound = false;
        Point pStart = new Point();
        Point pEnd;
        Rect rRetVal = new Rect();

        for(int i=0; i<ary.length; i++) {
            for(int j=0; j<ary[i].length; j++) {
                //如果該點值爲'0',生成最大矩形;
                if(ary[i][j]==0) {
                    pStart.setPoint(j,i);
                    pEnd = getMaxEndPoint(pStart);
                    if(pEnd!=null) {
                        rRetVal.setRect( pStart, pEnd );
                        bFound = true;
                    }
                }
            }
        }
        if(bFound)
            return rRetVal;
        else
            return null;
    }
    public void drawArea(Rect area) {
        if(!checkBind()) return;
        System.out.println("Start---------------------------------------------");
        for(int i=0; i<ary.length; i++) {
            System.out.print("  ");
            for(int j=0; j<ary[i].length; j++){
                if( (area.getStartPoint().getX()<=j)&&(j<=area.getEndPoint().getX())&&(area.getStartPoint().getY()<=i)&&(i<=area.getEndPoint().getY()) )
                    System.out.print(" *");
                else
                    System.out.print(" "+ary[i][j]);
            }
            System.out.println("");
        }
    }
    public void drawArea() {
        if(!checkBind()) return;
        System.out.println("Start---------------------------------------------");
        for(int i=0; i<ary.length; i++) {
            System.out.print("  ");
            for(int j=0; j<ary[i].length; j++){
                System.out.print(" "+ary[i][j]);
            }
            System.out.println("");
        }
    }
    public int getLastMaxAreaSize() {
        if(!checkBind()) return -1;
        return X*Y;
    }
    //形式成最大矩形 返回第1最大矩形面積終點座標
    private Point getMaxEndPoint(Point pStart) {
        boolean bFound = false;
        if(!checkBind()) return null;
        if(!isValidStart(pStart)) return null;
        if(!isZero(pStart.right())) return null;
        if(!isZero(pStart.down())) return null;
        if(!isZero(pStart.rightdown())) return null;

        int x=0,y;
        do {
            x++;
            y=1;
            while((ary.length>(pStart.getY()+y+1))&&appendH(pStart,x,y)) {
                y++;
            }

            if( (x+1)*(y+1)>(X+1)*(Y+1) ) {
                X = x;
                Y = y;
                bFound = true;
            }
        }while((ary[pStart.getY()].length>(pStart.getX()+x+1))&&appendW(pStart,x,1));

        if(bFound)
            return pStart.newPointBy(X,Y);
        else
            return null;
    }
    //橫向(右)追加矩形面積 成功返回true
    private boolean appendW(Point pThis, int X, int Y) {
        int xVal = pThis.getX()+X+1;
        for(int i=0; i<=Y; i++) {
            if(ary[pThis.getY()+i][xVal]==1)
                return false;
        }
        return true;
    }
    //縱向(下)追加矩形面積 成功返回true
    private boolean appendH(Point pThis, int X, int Y) {
        int yVal = pThis.getY()+Y+1;
        for(int i=0; i<=X; i++) {
            if(ary[yVal][pThis.getX()+i]==1)
                return false;
        }
        return true;
    }
    private boolean isZero(int pX,int pY){ return (ary[pY][pX]==0)?true:false; }
    private boolean isZero(Point pStart){ return isZero(pStart.getX(),pStart.getY()); }
    private boolean isValidStart(int pX, int pY){ return isZero(pX,pY)?( (ary.length<=(pY+1))||(ary[pY].length<=(pX+1))?false:true ):false; }
    private boolean isValidStart(Point pStart){ return isValidStart(pStart.getX(),pStart.getY()); }
    private boolean checkBind() {
        if(ary==null) {
            showFaildString();
            return false;
        }

        return true;
    }
    private int random_01(){
        //return 1;
        return (Math.random()*10>7)?1:0;
    }
    private void showFaildString() {
        System.out.println("Method.ary is null;");
    }
}


public class JavaApp {

    public static void main(String[] args) {

        int arr[][] = {
            {1, 1, 1, 1, 0, 0, 1},
            {1, 0, 0, 1, 0, 0, 1},
            {0, 0, 0, 0, 0, 0, 0},
            {1, 0, 1, 0, 1, 0, 1},
            {1, 0, 1, 0, 0, 1, 1},
            {1, 0, 0, 0, 0, 1, 1},
            {1, 0, 0, 0, 0, 1, 0},
        };

        Rect myRect;
        Method meth = new Method();
        Point pStart, pEnd, pTemp;

        switch(args.length) {
            case 1:
                if(!meth.arrBind(Integer.parseInt(args[0]),Integer.parseInt(args[0]))) System.exit(0);
                break;
            case 2:
                if(!meth.arrBind(Integer.parseInt(args[0]),Integer.parseInt(args[1]))) System.exit(0);
                break;
            default:
                if(!meth.arrBind(arr)) System.exit(0);
                break;
        }

        meth.drawArea();

        myRect = meth.maxArea();
        if(myRect==null) {
            System.out.println("not found;");
        }
        else
            meth.drawArea(myRect);

        meth.arrDisConnect();        //System.gc();
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章