最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

javascript算法解數(shù)獨(dú)實(shí)現(xiàn)方案示例

 更新時間:2023年08月10日 09:48:59   作者:zhoutk  
這篇文章主要為大家介紹了javascript算法解數(shù)獨(dú)實(shí)現(xiàn)方案示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

解數(shù)獨(dú)

看《算法的樂趣》,試著用非遞歸窮舉來解數(shù)獨(dú),看效率如何!

數(shù)獨(dú)規(guī)則

數(shù)獨(dú)游戲,經(jīng)典的為9×9=81個單元格組成的九宮格,同時也形成了3×3=9個小九宮格,要求在81個小單元格中填入數(shù)字1~9,并且數(shù)字在每行每列及每個小九宮格中都不能重復(fù)。

數(shù)獨(dú)技巧

  • 直觀法
  • 候選數(shù)法
  • 相關(guān)二十格:一個數(shù)字只與其所在行列及小九宮格的二十格相關(guān)

我的思路

  • 精心設(shè)計了有效性判定函數(shù),最多一次遍歷81個小單元格就能做出方案的有效性判定。
  • 同理設(shè)計了相關(guān)20格判定,一次0~9的循環(huán)就完成有效性判定。
  • 用數(shù)組模擬堆棧,為搜索提供回溯信息。
  • 利用對象具有map性質(zhì),來輔助判斷方案的有效性,大大簡化了算法。

方案設(shè)計與實(shí)現(xiàn)

只用了一個二維數(shù)組存儲數(shù)獨(dú)方案,一個一維數(shù)組作堆棧,一個布爾變量作回溯標(biāo)識。

變量定義

var problem = [                //這是書上提到的難度10.7的題
    [8,0,0,0,0,0,0,0,0],
    [0,0,3,6,0,0,0,0,0],
    [0,7,0,0,9,0,2,0,0],
    [0,5,0,0,0,7,0,0,0],
    [0,0,0,0,4,5,7,0,0],
    [0,0,0,1,0,0,0,3,0],
    [0,0,1,0,0,0,0,6,8],
    [0,0,8,5,0,0,0,1,0],
    [0,9,0,0,0,0,4,0,0]
]
var stack = [],flag = false;

方案有效性判定

充分利用了javascript對象的哈希特性,為了方便調(diào)試,判定有效時函數(shù)的返回值為0,無效時分三種情況,行沖突、列沖突、小九宮格沖突,分別返回1,2,3。前期判定用了它,后來增加了相關(guān)二十格判定,在找答案時這個函數(shù)就用不上了。

function checkValid(sudo){
    let subSudo = {}                        //輔助變量,用來判定小九宮格是否沖突
    for(let i = 0; i<9; i++){
        let row = {}, col = {}              //輔助變量,用來判定行、列是否沖突
        for(let j = 0; j<9; j++){
            let cur1 = sudo[i][j], cur2 = sudo[j][i]            //一次內(nèi)循環(huán)同時完成行列的判定
            if(row[cur1])                    //當(dāng)前元素已經(jīng)在行中出現(xiàn),優(yōu)化掉零的判斷,key為0時值為0,不需要額外判斷
                return 1;                    //返回錯誤代碼
            else
                row[cur1] = cur1            //當(dāng)前元素未在行中出現(xiàn),存入輔助變量中   
            if(col[cur2])                    //列的判定與行類似,優(yōu)化掉零的判斷,key為0時值為0,不需要額外判斷
                return 2;
            else
                col[cur2] = cur2;
            let key = Math.floor(i/3)+'-'+Math.floor(j/3)        //為不同的小九宮格生成不同的key
            if(subSudo[key]){                 //小九宮格中已經(jīng)有元素,優(yōu)化掉零的判斷,key為0時值為0,不需要額外判斷
                if(subSudo[key][cur1])        //對某一個小九宮格的判定與行類似
                    return 3
                else
                    subSudo[key][cur1] = cur1
            }else{                            //這是某小九宮格中的第一個元素
                subSudo[key] = {}             //為小九宮格新建一個輔助變量,并將第一個元素存入其中
                subSudo[key][cur1] = cur1
            }                  
        }
    }
    return 0;                                //程序能運(yùn)行到這,說明方案有效
}

相關(guān)二十格判定

原理同整體判定,亮點(diǎn)在小九宮格的定位上。

function check20Grid(sudo,i,j){                
    let row = {}, col = {}, subSudo = {}                //輔助變量
    for(let k = 0; k < 9; k++){
        let cur1 = sudo[i][k], cur2 = sudo[k][j]
        if(cur1){                                        //當(dāng)前元素已經(jīng)在行中出現(xiàn),優(yōu)化掉零的判斷,key為0時值為0,不需要額外判斷
            if(row[cur1])
                return 1;                                //返回錯誤代碼
            else
                row[cur1] = cur1                        //當(dāng)前元素未在行中出現(xiàn),存入輔助變量中
        }
        if(cur2){                                        //列的判定與行類似,優(yōu)化掉零的判斷,key為0時值為0,不需要額外判斷
            if(col[cur2])
                return 2;
            else
                col[cur2] = cur2;
        }
        //轉(zhuǎn)化循環(huán)變量到小九宮格的坐標(biāo)
        let key = sudo[Math.floor(i/3)*3 + Math.floor(k/3)][Math.floor(j/3)*3+Math.floor(k%3)]
        if(subSudo[key])                                //九宮格判定與行類似,優(yōu)化掉零的判斷,key為0時值為0,不需要額外判斷
            return 3
        else
            subSudo[key] = key
    }
    return 0;
}

遍歷求解

利用元素狀態(tài)初值為零的元素即為待定的特性,并加上堆棧的輔助,沒有再開辟額外的存儲空間。

function findAnswer(){
    for(let i = 0; i<9; i++){
        for(let j = 0; j<9; ){
            if(problem[i][j] === 0 || flag){              //當(dāng)前位置為待定元素的首次處理或回溯到當(dāng)前位置,兩種情況看似不同,其實(shí)處理相同,自加1即可
                flag = false;
                let k = problem[i][j] + 1;                //搜索向下一個合法值邁進(jìn)
                while(k<10){                              //循環(huán)找到下一個合法值
                    problem[i][j] = k;                    //填值
                    if(check20Grid(problem,i,j) == 0){    //判定合法,相關(guān)二十格判定
                        stack.push([i,j++])               //存儲回溯點(diǎn),并步進(jìn)
                        break;
                    }
                    k++;
                }
                if(k>9){                                  //當(dāng)前位置找不到合法值,回溯
                    problem[i][j] = 0;                    //回溯前歸零
                    let rt = stack.pop();                 //堆棧中取回溯信息
                    if(!rt)                               //無解判斷,返回0
                        return 0;    
                    i=rt[0]                               //穿越
                    j=rt[1]
                    flag = true;
                }
            }else{                                        //當(dāng)前位置數(shù)字為題目給定
                j++;
            }
        }
    }
    return 1;                                            //成功找到一組解
}

完整代碼

代碼托管在開源中國,其中的sudoku.js即數(shù)獨(dú)解法。

https://git.oschina.net/zhoutk/test.git

答案

書上提到的難度為10.7的題目的答案,1秒內(nèi)解決,效率還行。

[ [ 8, 1, 2, 7, 5, 3, 6, 4, 9 ],
  [ 9, 4, 3, 6, 8, 2, 1, 7, 5 ],
  [ 6, 7, 5, 4, 9, 1, 2, 8, 3 ],
  [ 1, 5, 4, 2, 3, 7, 8, 9, 6 ],
  [ 3, 6, 9, 8, 4, 5, 7, 2, 1 ],
  [ 2, 8, 7, 1, 6, 9, 5, 3, 4 ],
  [ 5, 2, 1, 9, 7, 4, 3, 6, 8 ],
  [ 4, 3, 8, 5, 2, 6, 9, 1, 7 ],
  [ 7, 9, 6, 3, 1, 8, 4, 5, 2 ] ]

以上就是javascript算法解數(shù)獨(dú)實(shí)現(xiàn)方案示例的詳細(xì)內(nèi)容,更多關(guān)于javascript算法解數(shù)獨(dú)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • uni-app?app引入天地圖簡單代碼示例

    uni-app?app引入天地圖簡單代碼示例

    uni-app是一種基于Vue.js的跨平臺開發(fā)框架,允許開發(fā)者使用統(tǒng)一的代碼編寫多端應(yīng)用,這篇文章主要給大家介紹了關(guān)于uni-app?app引入天地圖的相關(guān)資料,需要的朋友可以參考下
    2024-02-02
  • js判斷數(shù)據(jù)類型如判斷是否為數(shù)組是否為字符串等等

    js判斷數(shù)據(jù)類型如判斷是否為數(shù)組是否為字符串等等

    js判斷數(shù)據(jù)類型如判斷是否為數(shù)組類型、判斷是否為字符串類型、判斷是否為數(shù)值類型等等,本文有幾個不錯的示例,大家可以學(xué)習(xí)下
    2014-01-01
  • mpvue實(shí)現(xiàn)小程序簽到金幣掉落動畫(api實(shí)現(xiàn))

    mpvue實(shí)現(xiàn)小程序簽到金幣掉落動畫(api實(shí)現(xiàn))

    這篇文章主要介紹了mpvue實(shí)現(xiàn)小程序簽到金幣掉落動畫,這里使用小程序自帶的api來實(shí)現(xiàn),文中通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2019-10-10
  • js實(shí)現(xiàn)不提交表單獲取單選按鈕值的方法

    js實(shí)現(xiàn)不提交表單獲取單選按鈕值的方法

    這篇文章主要介紹了js實(shí)現(xiàn)不提交表單獲取單選按鈕值的方法,涉及javascript鼠標(biāo)事件及頁面元素屬性操作的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08
  • 微信小程序中的behaviors

    微信小程序中的behaviors

    behaviors是用于組件間代碼共享的特性, 類似一些編程語言中的'mixin'或者'traits',這篇文章主要介紹了微信小程序中的behaviors,需要的朋友可以參考下
    2024-08-08
  • JS實(shí)現(xiàn)上下左右對稱的九九乘法表

    JS實(shí)現(xiàn)上下左右對稱的九九乘法表

    九九乘法表使用很多種語言都可以實(shí)現(xiàn),本文給大家介紹js使用for、while循環(huán)來完成四種對稱的九九乘法表,對九九乘法表需要的朋友參考下
    2016-02-02
  • JavaScript監(jiān)測ActiveX控件是否已經(jīng)安裝過的代碼

    JavaScript監(jiān)測ActiveX控件是否已經(jīng)安裝過的代碼

    這是通用的方法,只需要把唯一的Activex的clsid和任意一個屬性或方法名傳進(jìn)來就可以判斷了。(找了兩個小時才找到 -_-!)
    2008-09-09
  • JavaScript使用BigInt處理超大數(shù)值全指南

    JavaScript使用BigInt處理超大數(shù)值全指南

    在JavaScript開發(fā)中,數(shù)值處理看似簡單,卻隱藏著一個容易被忽視的陷阱 —— 數(shù)值精度限制,面對超過安全整數(shù)范圍的超大數(shù)值時,傳統(tǒng)的 Number 類型往往力不從心,而BigInt的出現(xiàn)正是為了解決這一痛點(diǎn),本文將深入探討JavaScript數(shù)值處理的困境、BigInt的應(yīng)用場景及最佳實(shí)踐
    2025-07-07
  • 淺談JavaScript中內(nèi)存泄漏的幾種情況

    淺談JavaScript中內(nèi)存泄漏的幾種情況

    本文主要介紹了淺談JavaScript中內(nèi)存泄漏的幾種情況,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 一步一步教你寫帶圖片注釋的淡入淡出插件(三)

    一步一步教你寫帶圖片注釋的淡入淡出插件(三)

    接上一文,我們已經(jīng)實(shí)現(xiàn)了圖片的自動淡入淡出播放。接下來需要加入控制器。
    2010-10-10

最新評論

雷山县| 杭锦旗| 古浪县| 湖南省| 治县。| 石林| 丹寨县| 布拖县| 二连浩特市| 驻马店市| 洛川县| 临潭县| 黎城县| 平原县| 宿迁市| 沙洋县| 建宁县| 长海县| 鄢陵县| 康定县| 达尔| 清原| 璧山县| 闵行区| 化州市| 弥勒县| 内乡县| 满城县| 阿拉尔市| 全州县| 施秉县| 红桥区| 赤壁市| 即墨市| 松原市| 余庆县| 安顺市| 肥东县| 安康市| 台前县| 潼南县|