【筆記】Python 從檔案讀入多行測資

【範例】ZeroJudge b147: NOIP2004 2.花生采摘

  • 當範測需讀入的資料「分成多行」的情況,Python無法像C++一樣,透過鍵盤,把多行 sample input 一口氣 copy 再 paste 到 console 供程式讀取。
  • 一行一行地進行 copy 再 paste,不但耗時,也容易出錯。
  • 這時可以改用檔案讀取測資的方式,更方便地測試程式。

【Step-1】把sample input拷貝到一個新的檔案,存成”data.txt”

6 7 21
0 0 0 0 0 0 0
0 0 0 0 13 0 0
0 0 0 0 0 0 7
0 15 0 0 0 0 0
0 0 0 9 0 0 0
0 0 0 0 0 0 0

6 7 20
0 0 0 0 0 0 0
0 0 0 0 13 0 0
0 0 0 0 0 0 7
0 15 0 0 0 0 0
0 0 0 9 0 0 0
0 0 0 0 0 0 0

【Step-2】在原來的程式碼上方,加上下列程式碼:

  • with open(“data.txt”, “r”) as f:
    • 開啟檔案”data.txt”,屬性為”r” (read)
    • f 為一個指向檔案”data.txt”的指標
  • lines = f.readlines()
    • 把整個檔案一次讀入,但維持原來的換行符號
  • lines:為一個存放資料的list,每個元素即為每一行原始資料
#讀入整個檔案,有很多行
with open("data.txt", "r") as f:
    lines = f.readlines()

print(lines)
[
 '6 7 21\n', 
 '0 0 0 0 0 0 0\n', 
 '0 0 0 0 13 0 0\n', 
 '0 0 0 0 0 0 7\n',
 '0 15 0 0 0 0 0\n', 
 '0 0 0 9 0 0 0\n', 
 '0 0 0 0 0 0 0\n', 
 '\n', 
 '6 7 20\n', 
 '0 0 0 0 0 0 0\n', 
 '0 0 0 0 13 0 0\n', 
 '0 0 0 0 0 0 7\n',
 '0 15 0 0 0 0 0\n', 
 '0 0 0 9 0 0 0\n', 
 '0 0 0 0 0 0 0'
]

【Step-3】將原來程式碼中的 input( ) 換成 lines[idx],即可一次讀取一行。

  • idx 代表目前要讀取的行號。每次讀完一行,記得把 idx 加 1。
  • 程式執行後的結果,一樣會顯示在螢幕上。
#讀入整個檔案,有很多行
with open("data.txt", "r") as f:
    lines = f.readlines()

# idx: 指向接著要讀取的行號,從0開始
idx = 0
#原來的程式, 改從檔案(取代鍵盤)輸入測資
while True:
    try:
        #M, N, K = map(int, input().split())
        M, N, K = map(int, lines[idx].split()) #讀入一行,有三個整數
        idx += 1 #行號加1
        v = []
        for i in range(M):
            #tmp = list(map(int, input().split()))
            tmp = list(map(int, lines[idx].split())) #讀入一行,有多個整數
            idx += 1 #行號加1
            for j, z in enumerate(tmp):
                if (z > 0):
                    v.append((z, i+1, j+1))
        v.sort(key=lambda x: -x[0])

        x = 0
        y = 0
        ans = 0
        for z, nx, ny in v:
            if (x == 0):
                dis = nx
            else:
                dis = abs(nx - x) + abs(ny - y)

            if (K - dis > nx):
                K = K - dis - 1
                ans += z
                x = nx
                y = ny
            else:
                break

        print(ans)
        print()
        #_ = input()
        _ = lines[idx] #讀取一個空白行
        idx += 1 #行號加1
    except:
        break

分享本文 Share with friends