今天刷到了一道華為的機考題——密碼驗證。題目描述如下:
密碼要求:
1.長度超過8位
2.包括大小寫字母.數字.其它符號,以上四種至少三種
3.不能有相同長度大於2的子串重複
輸入描述:
一組或多組長度超過2的子符串。每組佔一行
輸出描述:
如果符合要求輸出:ok,否則輸出ng
輸入示例:
021abc9000
021abc9abc1
21abc9000
021$bc9000
輸出示例:
okng
ngok
這道題乍一看沒什麼特別的,但是今天自己做的時候發現裡面真的暗藏玄機(也是因為個人水平有限hh)。接下來就簡單說下自己在做這道題遇到的困惑和解決方法。
看他的輸入輸出示例,並沒有像之前做過的題一樣,有乙個固定的可輸入輸入行數,當時第一反應就是是不是題出錯了hh...
後來通過看別人的**,才知道原來還有標準輸入輸出這一說。。。
具體而言,我們可以用標準輸入來解決這一問題:
importsysfor line in
sys.stdin:
line = line.strip()
其中的line就是輸入的每行字串。但是還有個問題就是,不知道怎麼去停止輸入過程?
自己查了下可以用ctrl+d來停止輸入過程。
我們可以看到密碼要求的前兩個(1.長度超過8位,2.包括大小寫字母.數字.其它符號,以上四種至少三種)還是比較容易實現的。
**如下:
for line insys.stdin:
line =line.strip()
#1if len(line) <= 8:
print("ng"
)
continue#2
count =0
if re.search('
[0-9]
',line): count += 1
if re.search('
[a-z]
',line): count += 1
if re.search('
[a-z]
',line): count += 1
if re.search('
[^a-za-z0-9]
',line): count += 1
if count < 3:
print("ng"
)
continue
注意這裡不能用w來匹配除了大小寫字母.數字的其他符號,因為w還把下劃線去掉了。
這道題的關鍵在於如何判斷第三個密碼要求(不能有相同長度大於2的子串重複)。
這裡比較容易實現和理解的就是用迴圈判斷的方法來判斷是否有子串重複:
defpasswd_rep(str):
#一次拿出乙個長度為3的子串,則只需迴圈len(str)-3+1次即可遍歷完字串
for i in range(len(str)-2):
#如果相同子串的數量大於1,即子串重複,返回false
if str.count(str[i:i+3]) > 1:
return
false
return true
但是同樣的我看到有人用正規表示式來判斷:
re.search(r'.*(...)(.*\1)
', line)
乍一看還是很漂亮的。
但是這是我第一次接觸到正規表示式用『\1』的方法。。。好吧我確實太菜了。
\1是用來匹配第乙個分組即第乙個括號裡面匹配的內容,利用這個特性可以查詢是否有重複元素。
推而廣之,\1 \2 ... \9 分別是用來匹配第1,2,...,9個分組裡面的內容。
另外,關於匹配時是否用括號,也是一門學問,有興趣的同學可以看這篇博文:
後續有機會的話我也會自己寫一篇總結。
標準輸入與標準輸出
輸入cat 命令時,他會從stdin 對通斷介面來說,標準輸入就是鍵盤 接受輸入,cat testfile 現在cat命令會用testfile檔案中的行為作為輸入,可以使用這種技術將資料輸入到任何能從stdin接受資料的shell命令 stdout 在終端介面上,標準輸出就是終端顯示器。ls l t...
easy UI的密碼長度以及重複輸入驗證
自己些專案的時候找的時候也找了一會,所以存下來下次用的時候可以直接用了。話不多說,直接上 1 2密碼 3class easyui validatebox easyui textbox id pwd type password name userinfo.pwd 4 data options icon...
標準輸入流
get 從流中提取字元,包括空格 read 無格式輸入指定位元組數 getline 從流中提取一行字元 ignore 提取並丟棄流中指定字元 peek 返回流中下乙個字元,但不從流中刪除 gcount 統計最後輸入的字元個數 seekg 移動輸入流指標 int get cin.get char rc...