挑战编程 程序设计竞赛训练手册-1.6.5 图形化编辑器(Graphical Editor)

来源:互联网 发布:定额编号查询软件 编辑:程序博客网 时间:2024/05/15 04:12

挑战编程 程序设计竞赛训练手册-1.6.5 图形化编辑器(Graphical Editor)

public class problem_Graphical_Editor {/** * @param args *//*个人认为此程序难点在于  * 1、操作字符 F ,即填充某一个区域,需要算法支持,其中越界处理和全面覆盖处理需注意。 * 2、代码块之间的变量不能互传,需要设计一个全局变量来存储更新 * (第一次我把方法都写在case中,然后运算的结果就是穿不出去,非常蛋疼! * 更改代码后,只利用case来判断操作符,判断完成立刻并转入方法进行操作, * 并适当加入全局变量,以保证数值的成功传递)*/public static void main(String[] args) {// TODO Auto-generated method stubString[] str = { "I 5 6", //设定字符串"C", "L 2 3 A", //"K 4 5 4 5 I",//测试K操作"S one.bmp", //"C",    //测试清空操作"G 2 3 J",// 不在指令范围,应无操作/*"H 3 5 2 Z","L 1 2 Z",//测试F操作*/"F 3 3 J", //"F 4 4 K",//再次测试F操作"V 2 3 4 W", "H 3 4 2 Z", "S two.bmp", "X" };String get="";//定义截取字符数组的字符串变量为空,等待截取输入内容int Row = 0;//定义图片列数int Line = 0;//定义图片行数char[][] pic = null;//新建二维字符空图片for (int i=0;i<str.length;i++){//逐一截取字符串变量get = str[i];char R = get.substring(0).charAt(0);// 截取首字母,判断操作switch (R) { //判断操作符,顺便准备下将传入方法的变量case 'I':System.out.println("新建一个Line×Row的图像——所有像素为白色(-null符号-)");/*截取列和行的大小*/  Row = Integer.parseInt(get.substring(get.indexOf(' ') + 1,get.lastIndexOf(' '))); Line = Integer.parseInt(get.substring(get.lastIndexOf(' ') + 1,get.length())); /*新建一个空图像*/ pic = new char[Line][Row];break;case 'C':System.out.println("清除所有图像——所有像素涂成白色(O),大小不变");/*清除图像=新建空图像,长宽为更新的Line和Row*/pic = new char[Line][Row];break;case 'L':System.out.println("像素(X,Y)涂成颜色(C)");/*截取涂色的X,Y坐标和颜色C*/int Ly = Integer.parseInt(get.substring(get.indexOf(' ')+1,get.indexOf(' ',get.indexOf(' ')+1)));/*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ * 第一个空格位置为初始位置 , 结束位置为 从第一个空格的后面一个位置开始算起的第一个空格 * 然后截断字符↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓去掉第一个空格之前的所有,继续上述操作,直到截完整个字符串。*/get = get.substring(get.indexOf(' ')+1,get.length());//截断字符串,为2 3 A/*这样一次次截断有点二,可以写个方法调用下~~~~~~~~~~~~~~懒得更新了*/int Lx = Integer.parseInt(get.substring(get.indexOf(' ')+1,get.indexOf(' ',get.indexOf(' ')+1)));get = get.substring(get.indexOf(' ')+1,get.length());//再次截断字符串,为3 Achar LC = get.substring(get.indexOf(' ')+1,get.length()).toCharArray()[0];/*最后一个是字符,表示颜色,截取后可以用toCharArray()转换为字符数组。 * 因为只有一个字符,所以果断toCharArray()[0] * 由于操作符后面跟进的数字和字符的数量(不是数字的位数)是限定的,因此可以用上述方法依次截取和判断 * 下面的方法都是这个思路,不再重复说明*/System.out.println(Ly+" "+Lx+" "+LC);/*进行涂色操作,并返回图像*/pic = paintLG(pic,Ly,Lx,LC);break;case 'V':System.out.println("画一条竖线段——颜色为(C),列号为X,从第Y1行到第Y2行(包括Y1和Y2行)");/*截取涂色竖直线段的X,Y坐标和颜色C,截取算法参考case 'L'*/int Vy = Integer.parseInt(get.substring(get.indexOf(' ')+1,get.indexOf(' ',get.indexOf(' ')+1)));//X行在y轴上get = get.substring(get.indexOf(' ')+1,get.length());//继续二int Vx1 = Integer.parseInt(get.substring(get.indexOf(' ')+1,get.indexOf(' ',get.indexOf(' ')+1)));//Y列在x轴上get = get.substring(get.indexOf(' ')+1,get.length());int Vx2 = Integer.parseInt(get.substring(get.indexOf(' ')+1,get.indexOf(' ',get.indexOf(' ')+1)));//Y列在x轴上get = get.substring(get.indexOf(' ')+1,get.length());char VC = get.substring(get.indexOf(' ')+1,get.length()).toCharArray()[0];System.out.println(Vy+" "+Vx1+" "+Vx2+" "+VC);/*进行竖直线段的涂色操作,并返回图像*/pic = paintVG(pic,Vy,Vx1,Vx2,VC);break;case 'H':System.out.println("画一条水平线段——颜色为(C),行号为Y,从第X1行到第X2行(包括X1和X2行)");/*截取涂色水平线段的X,Y坐标和颜色C,截取算法参考case 'L'*/int Hy1 = Integer.parseInt(get.substring(get.indexOf(' ')+1,get.indexOf(' ',get.indexOf(' ')+1)));//X行在y轴上get = get.substring(get.indexOf(' ')+1,get.length());//还是二int Hy2 = Integer.parseInt(get.substring(get.indexOf(' ')+1,get.indexOf(' ',get.indexOf(' ')+1)));//Y列在x轴上get = get.substring(get.indexOf(' ')+1,get.length());int Hx = Integer.parseInt(get.substring(get.indexOf(' ')+1,get.indexOf(' ',get.indexOf(' ')+1)));//Y列在x轴上get = get.substring(get.indexOf(' ')+1,get.length());char HC = get.substring(get.indexOf(' ')+1,get.length()).toCharArray()[0];System.out.println(Hy1+" "+Hy2+" "+Hx+" "+HC);/*进行竖直线段的涂色操作,并返回图像*/pic = paintHG(pic,Hy1,Hy2,Hx,HC);break;case 'K':System.out.println("画一个实心矩形——颜色为(C),左上角为(X1,Y1),右下角为(X2,Y2)");/*截取涂色实心矩形的X,Y坐标和颜色C,截取算法参考case 'L'*/int Ky1 = Integer.parseInt(get.substring(get.indexOf(' ')+1,get.indexOf(' ',get.indexOf(' ')+1)));//X行在y轴上get = get.substring(get.indexOf(' ')+1,get.length());//………………弱爆了,有时间的话把它改写成方法……重复的那么多显得没水准int Ky2 = Integer.parseInt(get.substring(get.indexOf(' ')+1,get.indexOf(' ',get.indexOf(' ')+1)));//Y列在x轴上get = get.substring(get.indexOf(' ')+1,get.length());int Kx1 = Integer.parseInt(get.substring(get.indexOf(' ')+1,get.indexOf(' ',get.indexOf(' ')+1)));//Y列在x轴上get = get.substring(get.indexOf(' ')+1,get.length());int Kx2 = Integer.parseInt(get.substring(get.indexOf(' ')+1,get.indexOf(' ',get.indexOf(' ')+1)));//Y列在x轴上get = get.substring(get.indexOf(' ')+1,get.length());char KC = get.substring(get.indexOf(' ')+1,get.length()).toCharArray()[0];System.out.println(Ky1+" "+Ky2+" "+Kx1+" "+Kx2+" "+KC);/*进行实心矩形的涂色操作,并返回图像*/pic = paintKG(pic,Ky1,Ky2,Kx1,Kx2,KC);break;case 'F':System.out.println("把区域R填充为颜色(C)——R定义如下:若像素(X,Y)属于R,则所有与(X,Y)有公共边且颜色相同的像素也属于R");/*截取涂色的X,Y坐标和颜色C*/int Fy = Integer.parseInt(get.substring(get.indexOf(' ')+1,get.indexOf(' ',get.indexOf(' ')+1)));get = get.substring(get.indexOf(' ')+1,get.length());int Fx = Integer.parseInt(get.substring(get.indexOf(' ')+1,get.indexOf(' ',get.indexOf(' ')+1)));get = get.substring(get.indexOf(' ')+1,get.length());char FC = get.substring(get.indexOf(' ')+1,get.length()).toCharArray()[0];System.out.println(Fy+" "+Fx+" "+FC);/*进行区域X,Y的填充,并返回图像*/char color = getColor(pic,Fy,Fx);pic = paintFG(pic,Fy,Fx,FC,Row,Line,color);break;case 'S':String picName = get.substring(2, get.length());// 截取文件名System.out.println("原样输出文件名以及整幅图像的像素矩阵");System.out.println(picName);// 直接输出文件名/* 输出图像 */showG(pic);break;case 'X':System.out.println("退出程序");break;default:break;}}}/*获取指定位置字符(即颜色,下文的字符即表示颜色) * 传入 二维char图片,指定位置行号,指定位置列号 * return 颜色字符*/private static char getColor(char[][] pic, int fy, int fx) {// TODO Auto-generated method stubchar color= pic[fy-1][fx-1];return color;}/*下列方法的 命名规则 paint+操作字符代码+G */ /*此方法传入 二维char图片,指定位置行号,指定位置列号,替代字符,列数,行数,等待变换的字符 * 返回更新后的二维字符组成的图片*/private static char[][] paintFG(char[][] pic, int fy, int fx, char fC,int Row,int Line,char color) {// TODO Auto-generated method stub//定义--若像素(X,Y)属于R,则所有与(X,Y)有公共边且颜色相同的像素也属于R/*采用递归算法: * 大致思路: *从判断指定位置开始, *由getcolor记录待更改的颜色, *在改变当前位置字符后, *用getcolor记录到的字符判断上下左右相邻的四个字符 *如果某一位置的字符和getcolor获取的一样, *则递归,以此类推 *————————————分割线———————— *较繁琐的是越界问题, *如果某一位置的周围字符超出了图片范围, *不能对其进行修改,否则报越界错误。 *我的程序是在图片的四个顶角处完全停止递归 *因为能完全覆盖图片 *详情见↓下方代码↓ */if(fy<=1||fy>=Line){//如果贴上边和下边(其实直接等于就够了,程序是达不到越界范围的。//只是习惯了加上大于小于的范围判断,不知是否会影响性能??)if(fx<=1||fx>=Row){//如果贴左边和右边,即到顶,直接判断此框,停止递归if(pic[fy-1][fx-1]==color){ //更新(字符)颜色pic[fy-1][fx-1]=fC;}}else{//否则左右移动(只是贴于上下边,则进行左右位置的递归)if(pic[fy-1][fx-1]==color){//更新(字符)颜色pic[fy-1][fx-1]=fC;paintFG(pic,fy,fx-1,fC,Row,Line,color);//向左递归paintFG(pic,fy,fx+1,fC,Row,Line,color);//向右递归}}}else{//如果没有在上边和下边if(fx<=1||fx>=Row){//如果贴左边和右边,则上下移动if(pic[fy-1][fx-1]==color){//更新(字符)颜色pic[fy-1][fx-1]=fC;paintFG(pic,fy-1,fx,fC,Row,Line,color);//向上递归paintFG(pic,fy+1,fx,fC,Row,Line,color);//向下递归}}else{//否则上下左右移动if(pic[fy-1][fx-1]==color){//更新(字符)颜色pic[fy-1][fx-1]=fC;paintFG(pic,fy,fx-1,fC,Row,Line,color);//向上下左右四格递归paintFG(pic,fy,fx+1,fC,Row,Line,color);paintFG(pic,fy-1,fx,fC,Row,Line,color);paintFG(pic,fy+1,fx,fC,Row,Line,color);}}}return pic;}/*以下算法非常简单,不再过多注释*/private static char[][] paintKG(char[][] pic, int ky1, int ky2, int kx1,int kx2, char kC) {// TODO Auto-generated method stubfor (int i=ky1-1;i<=ky2-1;i++){for(int j=kx1-1;j<=ky2-1;j++){pic[i][j] = kC;}}return pic;}private static char[][] paintHG(char[][] pic, int hy1, int hy2, int hx,char hC) {// TODO Auto-generated method stubfor (int i=hy1-1;i<=hy2-1;i++){pic[hx-1][i] = hC;}return pic;}private static char[][] paintVG(char[][] pic, int vy, int vx1, int vx2,char vC) {// TODO Auto-generated method stubfor (int i=vx1-1;i<=vx2-1;i++){pic[i][vy-1] = vC;}return pic;}private static char[][] paintLG(char[][] pic,int Line,int Row,char c) {// TODO Auto-generated method stubpic[Line-1][Row-1] = c;return pic;}private static void showG(char[][] pic) {// TODO Auto-generated method stubfor( int i=0;i<pic.length;i++){for (int j=0;j<pic[i].length;j++){System.out.print(pic[i][j]);}System.out.println("");}}}


原创粉丝点击