国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

前端系列——查找字符串B的字符任意一種組合是否是字符串A的子串

hsluoyz / 1288人閱讀

摘要:例如,,則的其中一種組合是的子串,然后返回。如果從題目給出的例子來窮舉,一共種組合,很容易窮舉出來,但是字符串長度非常大的時(shí)候,怎么辦呢所以,窮舉的辦法被我排除了。

題目要求

這道算法題在前端面試中可能遇到,據(jù)說某條出過這題。

查找字符串B的字符任意一種組合是否是字符串A的子串。
例如 A=abc123,B=cba,則B的其中一種組合abc是A的子串,然后返回true。
算法思路

題目的出處已經(jīng)無從考究,接下來我們從JavaScript的角度來封裝這樣一個(gè)功能函數(shù)。

窮舉

一開始看到這道題,你會(huì)想到什么?
我想到的是先列舉出B的所有排列組合,存到數(shù)組里面,然后遍歷,判斷是否有組合包含在A中,如果有返回true,否則返回false。
如果從題目給出的例子來窮舉,一共6種組合,很容易窮舉出來,但是字符串長度非常大的時(shí)候,怎么辦呢?
所以,窮舉的辦法被我排除了。

標(biāo)記刪除法

這名字聽起來很奇怪,怎么個(gè)思路呢?

1、A的排序肯定是不變的,既然可變的我們很難下手,那么可以從不變的地方入手,以不變應(yīng)萬變。

2、看字符串可能不太習(xí)慣,我把A和B都轉(zhuǎn)換成數(shù)組。

let a = A.split("") // [a, b, c, 1, 2, 3]
let b = B.split("") // [c, b, a]

3、先過濾數(shù)組為空的情況,如果a或者b為空,那么不需要比較,返回false。

if (a.length === 0 || b.length === 0) {
    return false
}

4、只看數(shù)組b,可以有6種排列組合,[c,b,a],[a,b,c],[a,c,b],[b,a,c],[b,c,a],[c,a,b]。還記得第1步說的,我們不管b有多少種組合,都從a入手。

// a = [a, b, c, 1, 2, 3]
for (let j = 0; j < a.length; j++) { 

}

5、遍歷a有什么作用呢?接下來我為大家揭曉何為標(biāo)記刪除法,允許我小小解釋一下該方法,分為2個(gè)核心,“標(biāo)記”和“刪除”,“標(biāo)記”是指標(biāo)記當(dāng)前數(shù)組a遍歷的位置,“刪除”是指刪除數(shù)組b中的元素。

這樣說可能不太懂,先不看代碼,我用數(shù)組來模擬一下執(zhí)行過程。

初始化的值
a = [a, b, c, 1, 2, 3]
b = [c, b, a]
==================================================
當(dāng)遍歷a的時(shí)候,j從0開始,遍歷到a.length-1結(jié)束
==================================================
j = 0 // 給a里的字符加"",做個(gè)標(biāo)記,表示當(dāng)前遍歷的下標(biāo)位置
a = ["a", b, c, 1, 2, 3]
==================================================
然后我們發(fā)現(xiàn)數(shù)組b存在當(dāng)前的字符"a",執(zhí)行刪除操作
b = [c, b]
==================================================
j = 1 // 數(shù)組a遍歷到第二個(gè)字符
a = [a, "b", c, 1, 2, 3] // 標(biāo)記
b = [b] // 刪除
==================================================
j = 1 // 數(shù)組a遍歷到第三個(gè)字符
a = [a, b, "c", 1, 2, 3] // 標(biāo)記
b = [] // 刪除
==================================================
現(xiàn)在我們看到b數(shù)組變成空了,則證明b的任意一種排列存在于a中

6、上一步描述的情況是最簡單的狀態(tài),剛好在A字符中存在不間斷的字符組合。我們把A改一下,變成 A = a1b2c3abc。即使變復(fù)雜了,我們依舊可以使用標(biāo)記刪除發(fā)來做,只是稍微做一點(diǎn)處理。

初始化的值
a = [a, 1, b, 2, c, 3, a, b, c]
b = [c, b, a]
==================================================
當(dāng)遍歷a的時(shí)候,j從0開始,遍歷到a.length-1結(jié)束
==================================================
j = 0 // 給a里的字符加"",做個(gè)標(biāo)記,表示當(dāng)前遍歷的下標(biāo)位置
a = ["a", 1, b, 2, c, 3, a, b, c]
==================================================
然后我們發(fā)現(xiàn)數(shù)組b存在當(dāng)前的字符"a",執(zhí)行刪除操作
b = [c, b]
==================================================
j = 1 // 數(shù)組a遍歷到第二個(gè)字符
a = [a, "1", b, 2, c, 3, a, b, c] // 標(biāo)記
// 突然發(fā)現(xiàn)第2個(gè)字符是1,現(xiàn)在該怎么辦?我們只需要把數(shù)組b恢復(fù)初始狀態(tài)即可

b = [c, b, a] // 恢復(fù)初始狀態(tài) 
==================================================
接下來繼續(xù)遍歷,重復(fù)上面的處理步驟,直到數(shù)組b為空或者數(shù)組a遍歷完成,返回結(jié)果

7、JavaScript代碼實(shí)現(xiàn)
下面是第6步說明的代碼實(shí)現(xiàn),從代碼中可以看到,不管B字符有多少排列組合,我們始終只需要遍歷A的所有字符即可,內(nèi)部實(shí)現(xiàn)也是用空間換時(shí)間。

// 遍歷數(shù)組 a
    for (let j = 0; j < a.length; j++) {
        // 數(shù)組 b不為空,下一步
        if (b.length > 0) {
            // 數(shù)組a存在當(dāng)前遍歷的數(shù)組b的元素
            if (b.indexOf(a[j]) > -1) {
                // 刪除b數(shù)組中匹配到的第一個(gè)對(duì)應(yīng)下標(biāo)的元素
                b.splice(b.indexOf(a[j]), 1)
                if (b.length === 0) {
                    // 如果數(shù)組b全部被刪除了,則證明b是a的子串
                    return true
                }
            } else {
                // 數(shù)組b不存在當(dāng)前遍歷的數(shù)組b的元素,恢復(fù)b數(shù)組
                b = B.split("")
            }
        } else {
            // 數(shù)組 b為空返回true
            return true
        }
    }
總結(jié)

與其他前端工程師的交流中,我還了解到了其他的解題思路,有些很有趣,比如考慮使用Map或Set、滑塊區(qū)間比較等,不過我沒有去用代碼實(shí)現(xiàn)過,如果你有其他的方法,可以在下面留言交流。

完整源碼

評(píng)論區(qū)有人指出不能覆蓋某些場(chǎng)景的測(cè)試用例,所以我對(duì)上面的具體過程做了改進(jìn),下面是改進(jìn)后的源碼。
增加了2個(gè)字段,isBack和isRestart,isRestart用來標(biāo)記是否重新在當(dāng)前位置遍歷,isBack判斷是否對(duì)數(shù)組遍歷的下標(biāo)進(jìn)行回退一個(gè)單位。

var A = "abc123"
  , B = "cba"
function interface(A, B) {
    // 將A和B轉(zhuǎn)成數(shù)組
    let a = A.split("")
    let b = B.split("")
    if (a.length === 0 || b.length === 0) {
        return false
    }
    let isBack = false, isRestart = 0
    // 遍歷數(shù)組 a
    for (let j = 0; j < a.length; j++) {
        // 數(shù)組 b不為空,下一步
        if (b.length > 0) {
            isBack = false
            // 數(shù)組a存在當(dāng)前遍歷的數(shù)組b的元素
            if (b.indexOf(a[j]) > -1) {
                // 刪除b數(shù)組中匹配到的第一個(gè)對(duì)應(yīng)下標(biāo)的元素
                b.splice(b.indexOf(a[j]), 1)
                if (b.length === 0) {
                    // 如果數(shù)組b全部被刪除了,則證明b是a的子串
                    return true
                }
            } else {
                if (isRestart !== 0) {
                    isBack = false
                } else {
                    isBack = true
                }
                // 數(shù)組b不存在當(dāng)前遍歷的數(shù)組b的元素,恢復(fù)b數(shù)組
                b = B.split("")
                if (isBack) {
                    j -= 1
                    isRestart = 0
                }
                isRestart++
            }
        } else {
            // 數(shù)組 b為空返回true
            return true
        }
    }
    return false
}
interface(A, B)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/52996.html

相關(guān)文章

  • 前端系列——查找字符B字符任意一種組合字符A子串

    摘要:例如,,則的其中一種組合是的子串,然后返回。如果從題目給出的例子來窮舉,一共種組合,很容易窮舉出來,但是字符串長度非常大的時(shí)候,怎么辦呢所以,窮舉的辦法被我排除了。 題目要求 這道算法題在前端面試中可能遇到,據(jù)說某條出過這題。 查找字符串B的字符任意一種組合是否是字符串A的子串。例如 A=abc123,B=cba,則B的其中一種組合abc是A的子串,然后返回true。 算法思路 題目的...

    zengdongbao 評(píng)論0 收藏0
  • JavaScript正則表達(dá)式

    摘要:正則表達(dá)式是由普通字符例如字符到以及特殊字符稱為元字符組成的文字模式。方法參數(shù)一個(gè)正則表達(dá)式對(duì)象。如果正則表達(dá)式?jīng)]有標(biāo)志,則會(huì)返回和相同的結(jié)果。其被視為一整個(gè)字符串,而不是一個(gè)正則表達(dá)式。 正則表達(dá)式 正則表達(dá)式(Regular Expression)是一種文本模式,包括普通字符(例如,a 到 z 之間的字母)和特殊字符(稱為元字符)。正則表達(dá)式使用單個(gè)字符串來描述、匹配一系列匹配某個(gè)...

    jsdt 評(píng)論0 收藏0
  • Python中正則表達(dá)式

    摘要:正則表達(dá)式就是用來描述他稱為正則集的代數(shù)的表達(dá)式,因此采用正則表達(dá)式這個(gè)術(shù)語。文本中正則表達(dá)式結(jié)束搜索的索引值與和方法的同名參數(shù)相同。對(duì)象是一個(gè)編號(hào)的正則表達(dá)式通過提供的一系列方法可以對(duì)文本進(jìn)行匹配查找。 一、概述 今天這篇文章帶領(lǐng)大家學(xué)習(xí)一下Python中的正則表達(dá)式,當(dāng)然了,正則表達(dá)式本身的內(nèi)容就足以寫好幾本書了,我們這里列出的內(nèi)容,僅僅是Python中常用的和基礎(chǔ)的一些內(nèi)容。 那...

    Juven 評(píng)論0 收藏0
  • JavaScript必會(huì)技能——正則表達(dá)式

    摘要:語法參數(shù)必填項(xiàng),字符串或正則表達(dá)式,該參數(shù)指定的地方分割可選該參數(shù)指定返回的數(shù)組的最大長度,如果設(shè)置了該參數(shù),返回的子字符串不會(huì)多于這個(gè)參數(shù)指定的數(shù)組。該數(shù)組通過在指定的邊界處將字符串分割成子字符串。把正則表達(dá)式拆分成小表達(dá)式。 正則表達(dá)式是什么 RegExp 對(duì)象表示正則表達(dá)式,它是對(duì)字符串執(zhí)行模式匹配的強(qiáng)大工具。 為什么使用正則表達(dá)式 測(cè)試字符串內(nèi)的模式。例如,可以測(cè)試輸入字符串...

    FrozenMap 評(píng)論0 收藏0
  • JavaScript正則表達(dá)式

    摘要:引用就是允許在同一個(gè)正則表達(dá)式的后部引用前面的子表達(dá)式。這個(gè)數(shù)字制定了帶圓括號(hào)的子表達(dá)式在正則表達(dá)式中的位置。對(duì)正則表達(dá)式中前一個(gè)子表達(dá)式的引用,并不是指對(duì)子表達(dá)式模式的引用,而是指與那個(gè)模式匹配的文本的引用。 前言 本文主要是在讀《JavaScript高級(jí)程序語言設(shè)計(jì)》一書有關(guān)正則表達(dá)式的章節(jié)的知識(shí)點(diǎn)記錄,方便后續(xù)查閱。 什么是正則表達(dá)式 正則表達(dá)式是用來描述字符組合的某種規(guī)則。它可...

    sixleaves 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<