演算法 IP分割問題(python實現)

2022-04-04 19:51:24 字數 3366 閱讀 2030

今天群裡有個朋友出了個題,是一家公司的面試題,題目如下(補充:對於ip0開頭的也是無效的,如分割後001.1.1.1這種是不可以的):

分析:這裡我們舉乙個最簡單的例子1.1.1.12.2.2.2。首先能想到的解決方法肯定是使用迴圈了,我們可以寫2個迴圈巢狀(有點像氣泡排序)從第0個位置擷取1個,從第0個位置擷取2個……直到從第n-1擷取到n個為止(n為字串總長度)。

如從第1個擷取1個我們擷取出來的就是「1」,第1個擷取2個我們擷取出來的就是「1.」,第1個擷取3個我們擷取出來的就是「1.1」……擷取出來後我們可以通過split方法用「.」拆分,然後進行驗證每個元素是否合法,如果合法我們則繼續往後遍歷。

但是這裡使用迴圈就有個問題了,比如我們擷取出來「1.1.1.1」,我們判斷合法,那麼迴圈下次擷取的時候就是1.1.1.12」了,很顯然這個並不是我們希望的結果。我們更希望當有乙個合法的ip出現後,我們從它後面的位置重新開始查詢合法的ip。如後面幾次的遍歷就是"2","2.","2.2"這樣的順序找。所以這裡就想到了使用遞迴的方式來控制搜尋的起始點和結束點。

遞迴解決思路:寫遞迴第一件事就是確定結束條件,因為遞迴寫不好很容易死迴圈或者棧溢位,這裡我們可以很方便的算出結束條件就是起始位置是字串長度-1的位置,結束的位置是字元長度的位置。然後我們將引數一開始的預設值設定成開始位置0,結束位置1(因為我們要將所有的情況都走一遍)。當當前擷取的內容條件不滿足,我們就將結束位置+1再進行擷取,直到有滿足條件的ip出現(我們儲存合法的ip以及當前起始位置和結束位置存到乙個列表裡)我們則修改起始位置為當前結束位置+1的位置,結束位置為當前結束位置加2的位置,或者一直到結束位置到最後乙個位置,我們再將起始位置設定成當前起始位置+1,結束位置為起始位置加2,再進行遞迴,直到遞迴結束。

最後我們就可以獲得乙個類似這樣的資料,上面是ip,下面是當前ip對應的位置。當然你會發現一些重複的資料,因為確實會有重複的計算出現(這裡如果不需要找出全部值的話可以優化)。在這裡我們搜尋最終結果的時候只需要按著順序看位置是不是連續到最後的,如下面的第乙個[0, 7], 第二個[7, 14]是連續到最後的,所以結果就是1.1.1.1和2.2.2.2了。

ips: ['1.1.1.1', '2.2.2.2', '1.1.1.12', '1.1.12.2', '1.12.2.2', '12.2.2.2', '2.2.2.2', '2.2.2.2']

ips_pos: [[0, 7], [7, 14], [0, 8], [2, 10], [4, 12], [6, 14], [7, 14], [7, 14]]

str = "

1.1.1.10050.2.1.1101.2.2.2

"ips = #

記錄的ip

ips_pos = #

當前ip的起始位置

defshowip(str, start, end):

#結束條件

if (start == len(str)-1 and end ==len(str) ):

return

sp = str[start:end].split("."

)

if (len(sp) == 4):

#是否數字都滿足所有轉換規則

flag =true

#是否所有數字都在範圍內1~255

try:

for i in range(0, 4):

if(sp[i].startswith("0"

)): flag=false

break

now =int(sp[i])

if (not (0 < now < 256)):

flag =false

break

if(flag):

#儲存ip

儲存ip的位置

#遞迴計算

if(end + 1 >len(str)):

showip(str, start+1 , start +2)

else

: showip(str, end , end + 1)

except

exception as e:

pass

#遞迴計算

if (end + 1 >len(str)):

showip(str, start + 1, start + 2)

else

: showip(str, start, end + 1)

#獲取最後的結果

defgetresult(str,ips,pos):

length=len(str) #

長度 result= #

最終的結果

#之前的起始和結束為止

prestart=0

preend=0

#所有的起始和結束位置是否全部連續

flag=true

for i, item in

enumerate(ips_pos):

#第一次則儲存為之前的值

if(i==0):

prestart=item[0]

preend=item[1]

continue

#之前結束的值等於現在開始的值則表示連續

if(preend==item[0]):

prestart=item[0]

preend=item[1]

if(item[1]==length and

flag):

print("

最終結果:

",result)

return

#不連續

else

: flag=false

#新的開始則設定為連續值

if(item[0]==0):

flag=true

#清空結果重置之前的值

result.clear()

prestart =item[0]

preend = item[1]

print("

無結果"

)showip(str, 0, 1)

getresult(str,ips,ips_pos)

#執行結果:

#最終結果: ['1.1.1.100', '50.2.1.1', '101.2.2.2']

當然遞迴如果直接滿足條件是不是可以直接顯示結果,不在進行遞迴查詢,這裡大家可以自己修改下看看哈。當然也可以將多種情況都全部顯示出來,如1.1.1.123.2.2.2可以有2種結果1.1.1.1和23.2.2.2以及1.1.1.12和3.2.2.2大家都可以通過修改上面的**實現哦。

Perona Malik 演算法Python實現

最近正好在學習關於影象處理的東西,需要用到pm perona malik 演算法,所以就把自己的一些理解和 貼上來,希望能跟大家一起 pm演算法的具體原理可以網上查閱相關資料或者相關書籍,這裡只是簡要介紹大概的實現思路 一般而言,對乙個影象進行提取特徵之前,需要進行降噪濾波處理。最常用的應該是高斯濾...

Miller Rabin演算法 Python實現

用python實現了miller rabin的素性檢驗演算法 import random deflargeprime generate bit 1024 print generating large prime.i 1while true num random.randrange 2 bit 1 2...

python 關聯規則演算法 apriori實現

coding utf 8 from future import print function import pandas as pd 自定義連線函式,用於實現l 到c k的連線 def connect string x,ms x list map lambda i sorted i.split ms...