zoukankan      html  css  js  c++  java
  • homework-09

    概要:

    这次作业老师要求我们做一个算法演示程序。演示求子矩阵,使得总和最大。

    关于这次程序的要求,做网页版能够有更高的评价,所以我就果断做了网页版。并且,可能很多人觉得服务器、客户端是最有效的手段。可是,我这一次使用了纯html+css+javascript实现,不需要任何的服务器端,只要有一个稳定的浏览器,就可以进行算法演示,页面加载完后,即使断开网络,也能继续完整地进行算法演示。

    另外,作业中有个10分附加部分,录制屏幕作演示,这个我也完成了。使用windows自带的步骤记录器,psr.exe。上传到了百度云盘上:

    http://pan.baidu.com/s/1pbAtZ

    首先是主界面:

    (这个程序符合w3c规范,在mac系统下的safari、firefox,windows系统下的IE、firefox都完整地测试通过,本次演示使用mac下的firefox)

    从中,我们可以大概看到程序的功能,以下是其特性:
    1.点击行数以后,文本框中文字会自动消失,让用户进行登录,更加直观

    2.根据输入的行数和列数,矩阵文本区域会自动放大、缩小,以给用户一个适合的文本区域进行输入

    3.能够选择连通性,根据不同的连通方法进行不同的计算。

    4.能够根据当前的行和列,生成随机输入

    当输入完成后,我们就能进入到计算过程了:

    其中,红色区域是当前正在计算的区域,蓝色区域是目前已找到的和最大的区域,紫色就是红色和蓝色的重叠。

    本算法使用的是积分图进行求和运算,理所当然,应该要有个显示积分图的功能:

    从中,我们看到功能区的功能是根据当前情况动态变化的。

    算法中,我们设左上角的点为P1,右下角的点为P2。在这个算法调试中,我们需要3种功能:

    1.单步执行

    2.设置断点

    3.自动执行

    首先是单步执行,这又分为两种情况,第一种是让P1向下移动1格,第二种是让p2向下移动一格。这理所当然地都被支持了:

    另外就是自动执行,下方就可以输入每步间隔,支持暂停与继续,点击开始就行(执行时候也能修改间隔时间也能自动调整)。算法结束时,也会自动给出提示:

    另外一个功能就是设置断点,经过努力,这个演示程序提供了极其简洁易懂地方式。可以直接用鼠标选择运行到地位置:

    鼠标点击后,类似右键菜单,可以选择P1或者P2移动到当前位置,并且这个界面当鼠标移走后会自动消失,十分美观、实用。

    关于代码实现:

    本程序地所有动态效果都是纯javascript实现。并且整个运算过程都是javascript动态生成的。本程序在单页面上实现了这所有的工作,不需要服务器支持。对于我来说是一次挑战,做出这个的时候我也感到成就感十足。

    运算过程其实是一次迭代。输入期望停止的点,然后循环开始,到期望点后自动退出循环:

    function step(t_x1, t_y1, t_x2, t_y2)    //参数是希望停止的位置
    {
        for (; x1<=maxx; x1++) {
            if (y1>maxy) {
                y1 = 1;
            }
            for (; y1<=maxy; y1++) {
                if (x2==tx && y2==ty) {
                    x2 = x1;
                    y2 = y1;
                }
                if (hflag) {                    //hflag是纵向连通标记
                    tx = x1+maxx-1;
                } else {
                    tx = maxx;
                }
                if (vflag) {                    //vlag是横向连通标记
                    ty = y1+maxy-1;
                } else {
                    ty = maxy;
                }
                if (x2>tx) {
                    x2 = x1;
                }
                for (; x2<=tx; x2++) {
                    
                    if (y2>ty) {
                        y2 = y1;
                    }
                    for (; y2<=ty; y2++) {
                        tmax = inte[x2][y2]+inte[x1-1][y1-1]
                        tmax = tmax-inte[x2][y1-1]-inte[x1-1][y2]
                        if (tmax > res_max)                //找到更优解
                        {
                            res_x1 = (x1-1)%maxx+1;
                            res_y1 = (y1-1)%maxy+1;
                            res_x2 = (x2-1)%maxx+1;
                            res_y2 = (y2-1)%maxy+1;
                            res_max = tmax;
                        }
                        if (x1==t_x1&&y1==t_y1&&x2==t_x2&&y2==t_y2) {  //如果到达了停止点
                            showAll();
                            if (y2==ty&&x2==tx&&y1==maxy) {
                                x1 = x1 + 1;
                                y1 = 1;
                                x2 = x1;
                                y2 = y1;
                            }
                            if (y2==ty&&x2==tx) {
                                y1 = y1 + 1;
                                x2 = x1;
                                y2 = y1;
                            }
                            if (y2==ty) {
                                x2 = x2+1;
                                y2 = y1;
                            }
                            return;
                        }
                    }
                }
            }
        }
        showAll();  //如果全都运行完了,也需要刷新一下。
    }

    程序的流程。首先显示的输入页面,是一个html页面,加上各种javascript效果。主要处理的是文本框的输入、矩阵文本区域大小的自动调整、随机矩阵的生成。

    随机矩阵生成也十分简单,代码如下:

        $("#random").click(function () {
            var x = $("#x").val();
            var y = $("#y").val();
            s = "";
            var i, j, t;
            for (i=1;i<=x;i++) {
                for(j=1;j<=y;j++) {
                    t = Math.round(Math.random()*200)-100;
                    s = s + t + "	";
                }
                s = s + '
    ';
            }
            $("#m").val(s);
        })

    将待生成的矩阵变成一个字符串重写文本区域内容即可。

    点击提交按钮后,程序自动算出演示算法需要区域的大小,以及对应矩阵、积分图数据,供下面算法部分使用。代码如下:

        $("#calc").click(function () {
            var i, j, s;
            maxx = parseInt($("#x").val());
            maxy = parseInt($("#y").val());
            s = $("#m").val();
            s = s.replace(new RegExp('	', 'g'), " ");
            s = s.replace(new RegExp('
    ', 'g'), " ");
            s = s.split(" ")
            var sArray = new Array()
            for (i=0; i<s.length;i++) {
                if (s[i]!="") {
                    sArray.push(s[i]);
                }
            }
            for (i=0;i<=2*maxx;i++) {
                m[i] = new Array();
                inte[i] = new Array();
                for (j=0;j<=2*maxy+1;j++) {
                    if (i==0||j==0) {
                        m[i][j]=0;
                        inte[i][j]=0;
                    } else {
                        if (i>maxx || j>maxy) {
                            m[i][j] = m[(i-1)%maxx+1][(j-1)%maxy+1];
                        } else {
                            m[i][j] = parseInt(sArray[maxy*(i-1)+j-1]);
                        }
                        inte[i][j] = m[i][j]+inte[i-1][j]+inte[i][j-1]-inte[i-1][j-1];
                    }
                }
            }
            $(document.body).html("");
            init();
        
        draw();
        
        showAll();
        showTools();
        })

    至于算法页面,就是一个javascript函数画出来的,每个功能都是动态修改页面得到的效果。一下是初始化页面内容函数:

    function draw()
    {
        var tstr="";
        tstr = tstr + ("<div id=data>")
        tstr = tstr + ("<div id=m><h1>数据矩阵</h1><table border=1>")
        for (i=0;i<=maxx;i++) {
            tstr = tstr + ("<tr>
    ");
            for (j=0;j<=maxy;j++) {
                var t_id = i*(maxy+1)+j
                if (i==0&&j==0) {
                    tstr = tstr + ("<th class=tHead>")
                    tstr = tstr + ("行\列");
                    tstr = tstr + ("</th>
    ");
                } else if (i==0 || j==0){
                    tstr = tstr + ("<th class=tIndex>")
                    if (i == 0) {
                        tstr = tstr + (j);
                    } else {
                        tstr = tstr + (i);
                    }
                    tstr = tstr + ("</th>
    ");
                } else {
                    tstr = tstr + ("<td id="mat"+t_id+"" onclick="showPopUp(event, "+t_id+")">")
                    tstr = tstr + (m[i][j]);
                    tstr = tstr + ("</td>
    ");
                }
            }
            tstr = tstr + ("</tr>
    ");
        }
        tstr = tstr + ("</table></div>")
        tstr = tstr + ("<div id=inte><h2>积分图</h2><table border=1>")
        for (i=0;i<=maxx;i++) {
            tstr = tstr + ("<tr>
    ");
            for (j=0;j<=maxy;j++) {
                var t_id = i*(maxy+1)+j
                if (i==0&&j==0) {
                    tstr = tstr + ("<th class=tHead>")
                    tstr = tstr + ("行\列");
                    tstr = tstr + ("</th>
    ");
                } else if (i==0 || j==0){
                    tstr = tstr + ("<th class=tIndex>")
                    if (i == 0) {
                        tstr = tstr + (j);
                    } else {
                        tstr = tstr + (i);
                    }
                    tstr = tstr + ("</th>
    ");
                } else {
                    tstr = tstr + ("<td id="inte"+t_id+"" onclick="showPopUp(event, "+t_id+")">")
                    tstr = tstr + (inte[i][j]);
                    tstr = tstr + ("</td>
    ");
                }
            }
            tstr = tstr + ("</tr>
    ");
        }
        
        tstr = tstr + ("</table></div>");
        tstr = tstr + ("</div><div id=vars>")
        tstr = tstr + ("<div id=current><p>当前考察区域</p>");
        tstr = tstr + ("<p id=x1>1</p>");
        tstr = tstr + ("<p id=y1>2</p>");
        tstr = tstr + ("<p id=x2>3</p>");
        tstr = tstr + ("<p id=y2>4</p>");
        tstr = tstr + ("<p id=tmax>10</p>");
        tstr = tstr + ("</div>");
        tstr = tstr + ("<div id=current><p>目前最优区域</p>")
        tstr = tstr + ("<p id=res_x1>5</p>");
        tstr = tstr + ("<p id=res_y1>6</p>");
        tstr = tstr + ("<p id=res_x2>7</p>");
        tstr = tstr + ("<p id=res_y2>8</p>");
        tstr = tstr + ("<p id=res_max>9</p>");
        tstr = tstr + ("</div>");
        tstr = tstr + ("<p id=hflag>10</p>");
        tstr = tstr + ("<p id=vflag>10</p>");
        tstr = tstr + ("<div id=panel><h2>操作区</h2><div id=tools></div></div>");
        tstr = tstr + ("</div>");
        $(document.body).html(tstr);
        $("#inte").hide();          //默认隐藏积分图
    }

    以上就是核心思想,具体代码及完整注释都已签入github。

    助教辛苦了!

  • 相关阅读:
    [蓝桥杯] 第39级台阶
    [蓝桥杯] 马虎的算式
    POJ 1142 Smith Numbers(史密斯数)
    HDU 1181 变形课
    HDU 1728 逃离迷宫
    HDU 2188 悼念512汶川大地震遇难同胞――选拔志愿者 巴什博奕
    HDU 2177 取(2堆)石子游戏 (威佐夫博弈)
    HDU 1847 Good Luck in CET-4 Everybody! 博弈
    HDU 1525 Euclid's Game
    HDU 1517 A Multiplication Game 博弈
  • 原文地址:https://www.cnblogs.com/yzong/p/3464561.html
Copyright © 2011-2022 走看看