js实现动漫拼图1.0版

news2024/12/24 10:02:02

文章目录

  • 1 实现效果视频
  • 2 功能实现思路
  • 3代码实现

1 实现效果视频

在这里插入图片描述

拼图1.0

2 功能实现思路

布局忽略(小白学前端,不献丑了)

左侧拼图格
左侧4*4的拼图小格子

利用表格实现,规划好td的大小,给每个格子加上背景图片(将完整的图片裁剪为16张,命名规则为数字.png(1-16),利用二维数组存放四行四列的值从1-16,在遍历数组时,给他动态加上背景图片即可)item就是二维数组存的值,动态拼接上;photo是文件夹的名字images_1(或2,3,4)实现动态切换拼图图片
在这里插入图片描述

  let print = [
            [1, 2, 3, 4],
            [5, 6, 7, 8],
            [9, 10, 11, 12],
            [13, 14, 15, 16]
        ]
function updateUI() {
            print.forEach((subArr, i) => {
                subArr.forEach((item, j) => {
                    tds[i * 4 + j].style.backgroundImage = "url(./images/" + photo + "/" + item +".png)";
                    if (isStart && i == x0 && j == y0) {
                        tds[i * 4 + j].style.border = "3px solid red";
                    } else {
                        tds[i * 4 + j].style.border = "";
                    }
                })
            })
       

更换拼图图片

先获取元素,给其绑定单击事件。产生随机[1-4]的索引值(我当前有image_x文件四个,命名从_1到_4所以我需要的索引是1-4),获取当前展示的拼图的_x,确保产生的随机值与上次不同,不同之后就动态拼接新的src,在调用上面实现的ui函数,实现切换背景。

changeBtn.onclick = function () {
            isStart = false;
            print = [
                [1, 2, 3, 4],
                [5, 6, 7, 8],
                [9, 10, 11, 12],
                [13, 14, 15, 16]
            ]
            step=0;
            let index = parseInt(Math.random() * 4) + 1;
            let photo_id = look.src.split('/')[look.src.split('/').length - 2].split('_')[1];
            while (index == photo_id) {
                index = parseInt(Math.random() * 4) + 1;
            }
            photo = 'images_' + index;
            look.src = "./images/" + photo + "/canzhaotu.png";
            updateUI();
        }

重置功能(开始游戏或者打乱拼图)
随机交换打乱顺序(1.0版)

随机索引,实现随机的交换,调用自实现ui函数动态拼接,达到背景的更换,实现打乱拼图效果。
获取对应元素,绑定点击事件,点击调用之后,完成相应的初始化,此时给求助按钮绑定点击事件,开始播放背景音乐。

let restBtn = document.getElementById('rest');
        restBtn.onclick = function () {
            step = 0;
            isStart = true;
            shuffle();
            updateUI();
            initEvent();
            helpBtn.onclick = helpBake;
            bgMusic.play();
        }
// 打乱图片
        function shuffle() {
            print.forEach((subArr, i) => {
                subArr.forEach((item, j) => {
                    let x = parseInt(Math.random() * 4);
                    let y = parseInt(Math.random() * 4);
                    let temp = print[i][j];
                    print[i][j] = print[x][y];
                    print[x][y] = temp;
                })
            })
        }

initEvent函数(给每一个td加点击事件)
1.0版本玩法不同,可以任意更换原始块(想要控制移动的块)

给每一个td也帮上点击事件,在点击时计算出对应的二维数组的i(行)和j(列)。tds是一维数组索引值从0-16,print二维数组,行索引0-3,列索引0-3。可以根据二维行列推出对应的移位tds中的索引位置,也可以反过来。
例如:
如果 是二维的第三行第三列(对应的行列索引是2,2),此时对应的td索引应该是10=24+2;index=i(每一行的长度)+j;反过来就是i=向下取整[index/每行的长度],j=[index%每行的长度]

// 选择初始化位置
        function initEvent() {
            tds.forEach((td, index) => {
                td.onclick = function () {
                    let x = parseInt(index / 4);
                    let y = parseInt(index % 4);
                    x0 = x;
                    y0 = y;
                    updateUI();
                }
            })
        }

给移动按钮加点击事件
当然,也加了键盘监听事件,监听上下左右键

 leftBtn.onclick = function () {
            if (isStart) {
                direction = 'left';
                move(direction);
            }
        }
        rightBtn.onclick = function () {
            if (isStart) {
                direction = 'right';
                move(direction);
            }
        }
        upBtn.onclick = function () {
            if (isStart) {
                direction = 'up';
                move(direction);
            }
        }
        downBtn.onclick = function () {
            if (isStart) {
                direction = 'down';
                move(direction);
            }
        }
         window.onkeyup = function (e) {
            if (isStart) {
                if (e.keyCode == 37) {
                    direction = 'left';
                    move(direction);
                } else if (e.keyCode == 38) {
                    direction = 'up';
                    move(direction);
                } else if (e.keyCode == 39) {
                    direction = 'right';
                    move(direction);
                } else if (e.keyCode == 40) {
                    direction = 'down';
                    move(direction);
                }
            }
        }

move函数

定义一个direction全局变量,记录方向,判断向那个方向移动,在边界位置时需要注意越界,下一步如果是越界的情况,就直接return,不进行交换了(也就是不移动),也不执行step++(此时不算步数)。step记录移动步数,而一直出现的x0,y0是为了记录原始块(正在操控移动的块,在updateUi中给其加个边框,与其他做区分)
在这里插入图片描述

 // 移动交换图片
        function move(direction) {
            let x, y;
            if (direction == 'left') {
                if (y0 - 1 < 0) {
                    console.log("左边到边界了");
                    return;
                } else {
                    x = x0;
                    y = y0 - 1;
                }
            } else if (direction == 'right') {
                if (y0 + 1 > 3) {
                    console.log("右边到边界了");
                    return;
                } else {
                    x = x0;
                    y = y0 + 1;
                }
            } else if (direction == 'up') {
                if (x0 - 1 < 0) {
                    console.log("上边到边界了");
                    return;
                } else {
                    x = x0 - 1;
                    y = y0;
                }
            } else if (direction == 'down') {
                if (x0 + 1 > 3) {
                    console.log("下边到边界了");
                    return;
                } else {
                    x = x0 + 1;
                    y = y0;
                }
            }
            step++;
            let temp = print[x][y];
            print[x][y] = print[x0][y0];
            print[x0][y0] = temp;
            // 更新坐标位置
            x0 = x;
            y0 = y;
            updateUI();
        }

判断输赢

同时定义一个victory二维数组,记录下正确顺序,当移动到最后print数组的元素重新排序正确时,就游戏结束了。

let print = [
            [1, 2, 3, 4],
            [5, 6, 7, 8],
            [9, 10, 11, 12],
            [13, 14, 15, 16]
        ]
let victory = [
            [1, 2, 3, 4],
            [5, 6, 7, 8],
            [9, 10, 11, 12],
            [13, 14, 15, 16]
        ];
// 判断是否胜利
        function judgeVictory() {
            for (let i = 0; i < 4; i++) {
                for (let j = 0; j < 4; j++) {
                    if (print[i][j] != victory[i][j]) {
                        return false;
                    }
                }
            }
            return true;
        }

重点(难点)

求助按钮(实现提示)

思路:首先我们知道二维数组正确的顺序是1-16按序的,在打乱之后(其实就是这些值被打乱了),我们要还原,【在这个版本里是可以任意更换原始块的(我们移动操作的块)】,所以应该遍历这个print二维数组。去挨个检查里面存放的值的顺序,第一个位置的值应该是1,不是1就是需要被还原,那么再去遍历找寻那个块上的值是1,找到之后,让其和第一个位置的块实现交换,但是不能直接交换,那样就是显得很突兀,直接翻山越海了,应该让其有依据的一步一步归位。那就是找到num,根据num在找到对应的块的i和j,将i,j分别赋值给x0和y0,调用ui实现找到应该归位的那个原始块。
在这里插入图片描述

这个时候就用到了print二维数组的行列,利用destX记录绿色块的行坐标(i),利用destY记录绿色块的列坐标(j),用x0和y0记录原始块(红色块)的行和列坐标 (规定先横向移动,在纵向移动,这样就不会影响前面已经正确归位的块【当前num值之前的块】)

比较红色块和绿色块的横坐标(若y0<destY),说明红色块在绿色快的左边,那么应该右移;
比较红色块和绿色块的横坐标(若y0>destY),说明红色块在绿色快的右边,那么应该左移;
当y0=destY时,说明二者在同一列上,此时开始上移或下移(同理)
比较红色块和绿色块的纵坐标(若x0<destX),说明红色块在绿色快的上边,那么应该下移;
比较红色块和绿色块的纵坐标(若x0>destX),说明红色块在绿色快的下边,那么应该上移;
最后,当x0=destX时,说明这个红色块已经移动到了正确位置(绿色块的地方)。
清楚定时器(用定时器实现的循环,for循环太快,体现不出归位的过程)
在这里插入图片描述

 // 求助按钮
        function helpBake() {
            let destX;
            let destY;
            let num;
            //遍历寻找那个块的位置不对,找到不对的那个,返回这个位置正确的值应该是那个num
            wc: for (let i = 0; i < print.length; i++) {
                for (let j = 0; j < print[i].length; j++) {
                    let index = i * 4 + j;
                    if (print[i][j] != index + 1) {
                        destX = i;
                        destY = j;
                        num = index + 1;
                        break wc;
                    }
                }
            }
            let bakeX;
            let bakeY;
            //遍历数组,去看当前那个块身上的值是num
            wc: for (let i = 0; i < print.length; i++) {
                for (let j = 0; j < print[i].length; j++) {
                    if (print[i][j] == num) {
                        bakeX = i;
                        bakeY = j;
                        break wc;
                    }
                }
            }
            x0 = bakeX;
            y0 = bakeY;
            updateUI();
            // 开启自动巡航
            // 先横向移动,在纵向移动(必须得这样,不然就是bug)
            helpBtn.onclick = 'none';
            let timeId = setInterval(() => {
                // 先比较y0和destY
                if (y0 < destY) {
                    direction = "right";
                    move(direction);
                } else if (y0 > destY) {
                    direction = "left";
                    move(direction);
                } else {
                    if (x0 > destX) {
                        direction = "up";
                        move(direction);
                    } else if (x0 < destX) {
                        direction = "down";
                        move(direction);
                    } else {
                        // 归位了
                        clearInterval(timeId);
                        if (isStart) {
                            helpBtn.onclick = helpBake;
                        }
                    }
                }
            }, 800)
        }

剩余的就是各种测试,找bug,改逻辑。

3代码实现

代码下载:https://www.alipan.com/s/WrkusEaP8Uq

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            background-image: url('./images/background.png');
        }

        .first {
            text-align: center;
            margin-top: 20px;
            margin-bottom: 20px;
        }

        td {
            width: 100px;
            height: 100px;
            background-image: url('./images/1.png');
            background-size: 100% 100%;
            background-repeat: no-repeat;
        }

        .second {
            width: 60%;
            margin: 0 auto;
            display: flex;
        }

        .second_right {
            margin-left: 200px;
        }

        .third {
            margin-top: 20px;
            text-align: center;
        }

        #step {
            font-size: 30px;
            color: red;
            display: inline-block;
            width: 80px;
            box-sizing: border-box;
            text-align: center;
        }

        .change {
            width: 100px;
            height: 40px;
            font-size: 20px;
            background-color: #da3c24;
            border-radius: 10px;
            color: #fedcdc;
        }

        #look {
            width: 200px;
            height: 200px;
            background-repeat: no-repeat;
            background-size: 100% 100%;
            border: 4px solid white;
        }
    </style>
</head>

<body>
    <audio src="./audio/bg.mp3" id="bgMusic"></audio>
    <div class="first">
        <button class="change">更换图片</button>
        <img src="./images/title.png" alt="">
    </div>
    <div class="second">
        <div class="second_left">
            <table>
                <tr>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>
                <tr>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>
                <tr>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>
                <tr>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>
            </table>
        </div>
        <div class="second_right">
            <div style="margin-bottom: 40px;">
                <img src="" id="look">
            </div>
            <div style="margin-bottom: 30px; font-size: 25px; color:aliceblue">
                已经走了
                <span id="step">0</span></div>
            <div>
                <div style="text-align: center;">
                    <img src="./images/shang.png" id="up">
                </div>
                <div style="text-align: center;">
                    <img src="./images/zuo.png" id="left">
                    <img src="./images/xia.png" id="down">
                    <img src="./images/you.png" id="right">
                </div>
            </div>
        </div>
    </div>
    <div class="third">
        <img src="./images/chongzhi.png" id="rest">
        <img src="./images/qiuzhu.png" id="help">
        <div style="color: aliceblue;">点击重置按钮(开始游戏或者重新打乱顺序)</div>
    </div>
    <script>
        let print = [
            [1, 2, 3, 4],
            [5, 6, 7, 8],
            [9, 10, 11, 12],
            [13, 14, 15, 16]
        ]
        let victory = [
            [1, 2, 3, 4],
            [5, 6, 7, 8],
            [9, 10, 11, 12],
            [13, 14, 15, 16]
        ];
        let tds = document.querySelectorAll('td');
        let isStart = false;
        let x0 = 0;
        let y0 = 0;
        let direction = '';
        let step = 0;
        let photo = 'images_1';
        let leftBtn = document.getElementById('left');
        let rightBtn = document.getElementById('right');
        let upBtn = document.getElementById('up');
        let downBtn = document.getElementById('down');
        let stepSpan = document.getElementById('step');
        let helpBtn = document.getElementById('help');
        let changeBtn = document.querySelector('.change');
        let look = document.getElementById('look');
        look.src = './images/images_1/canzhaotu.png';
        let bgMusic = document.getElementById('bgMusic');
        window.onkeyup = function (e) {
            if (isStart) {
                if (e.keyCode == 37) {
                    direction = 'left';
                    move(direction);
                } else if (e.keyCode == 38) {
                    direction = 'up';
                    move(direction);
                } else if (e.keyCode == 39) {
                    direction = 'right';
                    move(direction);
                } else if (e.keyCode == 40) {
                    direction = 'down';
                    move(direction);
                }
            }
        }
        let restBtn = document.getElementById('rest');
        restBtn.onclick = function () {
            step = 0;
            isStart = true;
            shuffle();
            updateUI();
            initEvent();
            helpBtn.onclick = helpBake;
            bgMusic.play();
        }
        leftBtn.onclick = function () {
            if (isStart) {
                direction = 'left';
                move(direction);
            }
        }
        rightBtn.onclick = function () {
            if (isStart) {
                direction = 'right';
                move(direction);
            }
        }
        upBtn.onclick = function () {
            if (isStart) {
                direction = 'up';
                move(direction);
            }
        }
        downBtn.onclick = function () {
            if (isStart) {
                direction = 'down';
                move(direction);
            }
        }

        changeBtn.onclick = function () {
            isStart = false;
            print = [
                [1, 2, 3, 4],
                [5, 6, 7, 8],
                [9, 10, 11, 12],
                [13, 14, 15, 16]
            ]
            step=0;
            let index = parseInt(Math.random() * 4) + 1;
            let photo_id = look.src.split('/')[look.src.split('/').length - 2].split('_')[1];
            while (index == photo_id) {
                index = parseInt(Math.random() * 4) + 1;
            }
            photo = 'images_' + index;
            look.src = "./images/" + photo + "/canzhaotu.png";
            updateUI();
        }
        updateUI();
        // 更新UI
        function updateUI() {
            print.forEach((subArr, i) => {
                subArr.forEach((item, j) => {
                    tds[i * 4 + j].style.backgroundImage = "url(./images/" + photo + "/" + item +
                        ".png)";
                    if (isStart && i == x0 && j == y0) {
                        tds[i * 4 + j].style.border = "3px solid red";
                    } else {
                        tds[i * 4 + j].style.border = "";
                    }
                })
            })
            stepSpan.innerHTML = step;
            if (isStart) {
                let flag = judgeVictory();
                if (flag) {
                    alert("恭喜你,成功通关!");
                    isStart = false;
                }
            }
        }
        // 打乱图片
        function shuffle() {
            print.forEach((subArr, i) => {
                subArr.forEach((item, j) => {
                    let x = parseInt(Math.random() * 4);
                    let y = parseInt(Math.random() * 4);
                    let temp = print[i][j];
                    print[i][j] = print[x][y];
                    print[x][y] = temp;
                })
            })
        }
        // 选择初始化位置
        function initEvent() {
            tds.forEach((td, index) => {
                td.onclick = function () {
                    let x = parseInt(index / 4);
                    let y = parseInt(index % 4);
                    x0 = x;
                    y0 = y;
                    updateUI();
                }
            })
        }
        // 移动交换图片
        function move(direction) {
            let x, y;
            if (direction == 'left') {
                if (y0 - 1 < 0) {
                    console.log("左边到边界了");
                    return;
                } else {
                    x = x0;
                    y = y0 - 1;
                }
            } else if (direction == 'right') {
                if (y0 + 1 > 3) {
                    console.log("右边到边界了");
                    return;
                } else {
                    x = x0;
                    y = y0 + 1;
                }
            } else if (direction == 'up') {
                if (x0 - 1 < 0) {
                    console.log("上边到边界了");
                    return;
                } else {
                    x = x0 - 1;
                    y = y0;
                }
            } else if (direction == 'down') {
                if (x0 + 1 > 3) {
                    console.log("下边到边界了");
                    return;
                } else {
                    x = x0 + 1;
                    y = y0;
                }
            }
            step++;
            let temp = print[x][y];
            print[x][y] = print[x0][y0];
            print[x0][y0] = temp;
            // 更新坐标位置
            x0 = x;
            y0 = y;
            updateUI();
        }
        // 判断是否胜利
        function judgeVictory() {
            for (let i = 0; i < 4; i++) {
                for (let j = 0; j < 4; j++) {
                    if (print[i][j] != victory[i][j]) {
                        return false;
                    }
                }
            }
            return true;
        }
        // 求助按钮
        function helpBake() {
            let destX;
            let destY;
            let num;
            wc: for (let i = 0; i < print.length; i++) {
                for (let j = 0; j < print[i].length; j++) {
                    let index = i * 4 + j;
                    if (print[i][j] != index + 1) {
                        destX = i;
                        destY = j;
                        num = index + 1;
                        break wc;
                    }
                }
            }
            let bakeX;
            let bakeY;
            wc: for (let i = 0; i < print.length; i++) {
                for (let j = 0; j < print[i].length; j++) {
                    if (print[i][j] == num) {
                        bakeX = i;
                        bakeY = j;
                        break wc;
                    }
                }
            }
            x0 = bakeX;
            y0 = bakeY;
            updateUI();
            // 开启自动巡航
            // 先横向移动,在纵向移动(必须得这样,不然就是bug)
            helpBtn.onclick = 'none';
            let timeId = setInterval(() => {
                // 先比较y0和destY
                if (y0 < destY) {
                    direction = "right";
                    move(direction);
                } else if (y0 > destY) {
                    direction = "left";
                    move(direction);
                } else {
                    if (x0 > destX) {
                        direction = "up";
                        move(direction);
                    } else if (x0 < destX) {
                        direction = "down";
                        move(direction);
                    } else {
                        // 归位了
                        clearInterval(timeId);
                        if (isStart) {
                            helpBtn.onclick = helpBake;
                        }
                    }
                }
            }, 800)
        }
    </script>
</body>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1415974.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Gin 框架之jwt 介绍与基本使用

文章目录 一.JWT 介绍二.JWT认证与session认证的区别2.1 基于session认证流程图2.2 基于jwt认证流程图 三. JWT 的构成3.1 header : 头部3.2 payload : 负载3.2.1 标准中注册的声明 (建议但不强制使用)3.2.2 公共的声明3.2.3 私有的声明3.2.4 定义一个payload 3.3 signatrue : …

使用Python和ffmpeg旋转WebM视频并保存为MP4文件

简介: 在本篇博客中&#xff0c;我们将介绍如何使用Python编写一个程序&#xff0c;结合wxPython和ffmpeg模块&#xff0c;来旋转WebM视频文件并将其保存为MP4格式。我们将使用wxPython提供的文件选择对话框来选择输入和输出文件&#xff0c;并使用ffmpeg库来进行视频旋转操作。…

206. 反转链表(力扣LeetCode)

文章目录 206. 反转链表题目描述双指针递归 206. 反转链表 题目描述 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 示例 2&#xff1a; 输入&am…

第八篇【传奇开心果系列】beeware的toga开发移动应用示例:实现消消乐安卓手机小游戏

传奇开心果博文系列 系列博文目录beeware的toga开发移动应用示例系列博文目录一、项目目标二、安装依赖三、初步实现四、扩展思路五、实现游戏逻辑示例代码六、实现界面设计示例代码七、实现增加关卡和难度示例代码八、实现存档和排行榜示例代码九、实现添加特殊方块和道具示例…

(五)流程控制switchcase

文章目录 switch case用法全配套break示例演示 不全配套break不怎么常规的写法常规的写法示例1演示1示例2演示2 经典成绩分类案例代码演示 switch case 相对于ifelse的嵌套&#xff0c;switch case 有点像并列的感觉 用法 switch (一定要放整数类型&#xff0c;int 型变量、c…

ubuntu 22 安装 node,npm,vue

1:安装 nodejs sudo apt update curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt update && sudo apt install -y nodejs node -v 2:安装npm sudo npm install n -g npm -v 3:安装vite npm install vite -g 4:运行vue 把项目拷贝到…

「 典型安全漏洞系列 」06.路径遍历(Path Traversal)详解

引言&#xff1a;什么是路径遍历&#xff1f;如何进行路径遍历攻击并规避常见防御&#xff1f;如何防止路径遍历漏洞。 1. 简介 路径遍历&#xff08;Path Traversal&#xff09;是一种安全漏洞&#xff0c;也被称为目录遍历或目录穿越、文件路径遍历。它发生在应用程序未正确…

Tomcat10安装报错Unknown module: java.rmi specified to --add-opens

错误原因需要根据自己的tomcat的版本查看 需要根据自己的tomcat找到对应安装的java版本(查看版本网址)https://tomcat.apache.org/whichversion.html 将电脑当中的环境变量JRE_HOME变量删除即可&#xff08;具体如下图&#xff09;

LeetCode 热题 100 | 矩阵

目录 1 73. 矩阵置零 2 54. 螺旋矩阵 3 48. 旋转图像 4 240. 搜索二维矩阵 II 菜鸟做题第二周&#xff0c;语言是 C 1 73. 矩阵置零 解题思路&#xff1a; 遍历矩阵&#xff0c;寻找等于 0 的元素&#xff0c;记录对应的行和列将被记录的行的元素全部置 0将被记录的…

redis-4 搭建redis集群

1.为什么需要redis集群&#xff1f; Redis 集群提供了高可用性、横向扩展和数据分片等功能&#xff0c;使得 Redis 能够应对大规模的数据存储和高并发访问的需求。以下是一些需要使用 Redis 集群的常见情况&#xff1a; 高可用性&#xff1a;通过在多个节点之间进行数据复制和…

网络编程1

什么是网络编程 ⽹络编程&#xff0c;指⽹络上的主机&#xff0c;通过不同的进程&#xff0c;以编程的⽅式实现⽹络通信&#xff08;或称为⽹络数据传输&#xff09;。 当然&#xff0c;我们只要满⾜进程不同就⾏&#xff1b;所以即便是同⼀个主机&#xff0c;只要是不同进程…

【服务器Midjourney】创建部署Midjourney网站

目录 🌺【前言】 🌺【准备】 🌺【宝塔搭建MJ】 🌼1. 给服务器添加端口 🌼2. 使用Xshell连接服务器 🌼3. 安装docker 🌼4. 安装Midjourney程序 🌼5. 绑定域名+申请SSL证书 🌼6. 更新网站

数据结构.双链表循环链表

一、1.双链表的初始化 void InitLNode(LinkList& L)//双链表的初始化 {L (LNode*)malloc(sizeof(LNode));L->prior NULL;L->next NULL;} 2.双链表的插入 void DInsert(LNode* p,LNode*s)//在p结点后面插入s结点 {s->next p->next;s->next->prior s;…

支持向量机(SVM)详解

支持向量机&#xff08;support vector machines&#xff0c;SVM&#xff09;是一种二分类模型。它的基本模型是定义在特征空间上的间隔最大的线性分类器&#xff0c;间隔最大使它有别于感知机。 1、线性可分支持向量机与硬间隔最大化 1.1、线性可分支持向量机 考虑一个二分…

数据结构篇-03:堆实现优先级队列

本文着重在于讲解用 “堆实现优先级队列” 以及优先级队列的应用&#xff0c;在本文所举的例子中&#xff0c;可能使用优先级队列来解并不是最优解法&#xff0c;但是正如我所说的&#xff1a;本文着重在于讲解“堆实现优先级队列” 堆实现优先级队列 堆的主要应用有两个&…

MySQL索引类型及数据结构【笔记】

1 索引类型 返回面试宝典 主键索引&#xff08;PRIMARY&#xff09;:数据列不允许重复&#xff0c;不允许为NULL&#xff0c;一个表只能有一个主键。 唯一索引&#xff08;UNIQUE&#xff09;:数据列不允许重复&#xff0c;允许为NULL&#xff0c;一个表允许多个列创建唯一索引…

【Go】深入理解 Go map:赋值和扩容迁移 ①

文章目录 map底层实现hmapbmap map hash冲突了怎么办&#xff1f; map扩容触发扩容时机扩容小结为什么map扩容选择增量&#xff08;渐进式扩容&#xff09;&#xff1f;迁移是逐步进行的。那如果在途中又要扩容了&#xff0c;怎么办&#xff1f; map翻倍扩容原理 map写入数据内…

Easysearch:语义搜索、知识图和向量数据库概述

什么是语义搜索&#xff1f; 语义搜索是一种使用自然语言处理算法来理解单词和短语的含义和上下文以提供更准确的搜索结果的搜索技术。旨在更好地理解用户的意图和查询内容&#xff0c;而不仅仅是根据关键词匹配&#xff0c;还通过分析查询的语义和上下文来提供更准确和相关的…

Spring与Redis集成

1.引入RedisTemplate 据以前的情况&#xff0c;我们在Java中使用Redis时一般是使用Jedis来操作的&#xff0c;大致的一段代码如下所示 Overridepublic User findUserById(Integer id) {User user null;Jedis jedis null;try {jedis jedisPool.getResource();String userStr…

【YOLO系列算法俯视视角下舰船目标检测】

YOLO系列算法俯视视角下舰船目标检测 数据集和模型YOLO系列算法俯视视角下舰船目标检测YOLO系列算法俯视视角下舰船目标检测可视化结果 数据集和模型 数据和模型下载&#xff1a; YOLOv6俯视视角下舰船目标检测训练好的舰船目标检测模型舰船目标检测数据YOLOv7俯视视角下舰船…