프론트엔드와 다소 관련이 있고 흥미로운 알고리즘 질문에 대해 이야기해보겠습니다.
아래 그림과 같이 비행기에는 불특정 도형이 여러 개 있습니다. 물체의 개수와 서로 다른 물체의 면적을 구하는 프로그램을 작성해 보세요.
그래픽이 몇 개인지 알고 싶다면 먼저 사진의 각 픽셀을 가져온 다음 픽셀의 배경색(RGBA)을 결정하는 것이 좋습니다. 그림의 모든 픽셀을 얻으려면 h5 캔버스를 사용하는 것을 고려해 볼 수 있습니다.
다음과 같습니다:
초보 튜토리얼에서 캔버스의 getimagedata 메소드
html 태그 작성.
<canvas id="canvas" height="200" width="350">对不你,你的浏览器不支持Canvas</canvas>
js는 캔버스 객체를 가져옵니다.
let ctxt = canvas.getContext('2d');
js는 이미지 객체를 생성합니다.
let img = new Image; img.src = './image.png'; //图片路径 img.onload = function(){} //加载成功后的执行函数,之后的代码就写在其中
이미지의 픽셀을 저장하는 2차원 배열을 생성합니다.
let coordinates = [];for(let i=0; i<200; i++){ coordinates[i] = []; }
픽셀을 가져옵니다. getimagedata 메소드를 사용합니다.
ctxt.drawImage(img, 0, 0); //将图片画如canvas let data = ctxt.getImageData(0, 0, 350, 200).data;//读取整张图片的像素。
픽셀을 2차원 배열로 저장
let x=0,y=0; //二维数组的行和列, x:列 y:行 for(let i =0,len = data.length; i<len;i+=4){ let red = data[i],//红色色深 green = data[i+1],//绿色色深 blue = data[i+2],//蓝色色深 alpha = data[i+3];//透明度 //把每个像素点,以二位数组的形式展开 if(`${red} ${green} ${blue}` === '210 227 199'){ coordinates[y][x] = 0; }else{ coordinates[y][x] = 1; } x++; if(x >= 350){ x = 0; y++; } }
현재 코드는 다음과 같습니다.
(function(){ let ctxt = canvas.getContext('2d'); let img = new Image; let coordinates = []; let h = 200, w = 350; for(let i=0; i<200; i++){ coordinates[i] = []; } img.src = './image.png'; //图片路径 img.onload = function(){ ctxt.drawImage(img, 0, 0); let data = ctxt.getImageData(0, 0, 350, 200).data;//读取整张图片的像素。 let x=0,y=0; for(let i =0,len = data.length; i= 350){ x = 0; y++; } } console.log(coordinates); } })();
그림과 같습니다.
그런 다음 1의 연속 블록이 몇 개 있는지 알아야 합니다. 2차원 배열을 이용하면 그림 속 모양을 알 수 있고, 블록에 1이 몇 개 있는지, 블록의 면적이 1의 개수가 됩니다.
재귀적 역추적 알고리즘
//计算连续的面积和个数 const linkSum = (i,j,num)=>{//走过的路就置0 coordinates[i][j] = 0; num++; //向上 if((i+1 < h) && coordinates[i+1][j] == 1){ num = linkSum(i+1 , j , num); } //向下 if((j+1 < w) && coordinates[i][j+1] == 1){ num = linkSum(i , j+1 , num); } //向左 if((i-1 >= 0) && coordinates[i-1][j] == 1){ num = linkSum(i-1 , j , num); } //向右 if((j-1 >= 0) && coordinates[i][j-1] == 1){ num = linkSum(i , j-1 , num); } return num; }
const getCountAndArea = () =>{let sum = [];let count = 0;for(let i = 0; i < h; i++) //遍历二维数组 { for(let j = 0; j < w; j++) { //连续1的个数 if(coordinates[i][j] == 1) {let buf = 0; //连续1的个数 buf = linkSum(i,j,buf);count++; //形状的总数 sum.push({ index: count, //第几个形状 area: buf //形状的面积 }); } } }return {count, sum }; }최종 코드
(function(){ let ctxt = canvas.getContext('2d'); let img = new Image; let coordinates = []; let h = 200, w = 350; for(let i=0; i<200; i++){ coordinates[i] = []; } img.src = './image.png'; //图片路径 img.onload = function(){ ctxt.drawImage(img, 0, 0); let data = ctxt.getImageData(0, 0, 350, 200).data;//读取整张图片的像素。 let x=0,y=0; for(let i =0,len = data.length; i실행 결과: 학습 과정에서 문제가 발생하거나 학습 리소스를 얻고 싶다면 학습 교류 그룹에 오신 것을 환영합니다= 350){ x = 0; y++; } } // console.log(coordinates); let rst = getCountAndArea(); // console.log(rst); console.log('个数: ' + rst.count); for(let i=0; i { let sum = []; let count = 0; for(let i = 0; i < h; i++) { for(let j = 0; j < w; j++) { //连续1的个数 if(coordinates[i][j] == 1) { let buf = 0; buf = linkSum(i,j,buf); count++; sum.push({ index: count, area: buf }); } } } return { count, sum }; } //计算连续的面积和个数 const linkSum = (i,j,num)=>{ //走过的路就置0 coordinates[i][j] = 0; num++; //向上 if((i+1 < h) && coordinates[i+1][j] == 1){ num = linkSum(i+1 , j , num); } //向下 if((j+1 < w) && coordinates[i][j+1] == 1){ num = linkSum(i , j+1 , num); } //向左 if((i-1 >= 0) && coordinates[i-1][j] == 1){ num = linkSum(i-1 , j , num); } //向右 if((j-1 >= 0) && coordinates[i][j-1] == 1){ num = linkSum(i , j-1 , num); } return num; } })();
위 내용은 프론트엔드 관련 알고리즘 질문 공유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!