我有一個包含單列整數的檔案。我想從此文件中提取所有連續子序列(即以連續順序出現的子序列)的列表,這些子序列連續兩次以相同的數字開頭,長度為 12 個整數(包括重疊子序列)。
此外,文件中的任何非整數行都應被忽略/刪除,並且如果任何序列在達到 12 個整數之前到達輸入的末尾,則仍應輸出縮短的序列。
例如,假設我的輸入檔包含以下資料:
1
junk
1
1
2
3
4
4
5
6
7
8
9
10
11
12
13
14
15
15
16
那麼該解決方案應產生以下輸出:
1 1 1 2 3 4 4 5 6 7 8 9
1 1 2 3 4 4 5 6 7 8 9 10
4 4 5 6 7 8 9 10 11 12 13 14
15 15 16
請注意,該junk
行和空白行被忽略,因此前三1
行被視為連續的。
答案1
這是一個可以執行您想要的操作的 Python 腳本:
#!/usr/bin/env python2
# -*- coding: ascii -*-
"""extract_subsequences.py"""
import sys
import re
# Open the file
with open(sys.argv[1]) as file_handle:
# Read the data from the file
# Remove white-space and ignore non-integers
numbers = [
line.strip()
for line in file_handle.readlines()
if re.match("^\d+$", line)
]
# Set a lower bound so that we can output multiple lists
lower_bound = 0
while lower_bound < len(numbers)-1:
# Find the "start index" where the same number
# occurs twice at consecutive locations
start_index = -1
for i in range(lower_bound, len(numbers)-1):
if numbers[i] == numbers[i+1]:
start_index = i
break
# If a "start index" is found, print out the two rows
# values and the next 10 rows as well
if start_index >= lower_bound:
upper_bound = min(start_index+12, len(numbers))
print(' '.join(numbers[start_index:upper_bound]))
# Update the lower bound
lower_bound = start_index + 1
# If no "start index" is found then we're done
else:
break
假設您的資料位於名為data.txt
.然後你可以像這樣執行這個腳本:
python extract_subsequences.py data.txt
假設您的輸入檔data.txt
如下所示:
1
1
1
2
3
4
5
6
7
8
9
10
11
12
那麼你的輸出將如下所示:
1 1 1 2 3 4 5 6 7 8 9 10
1 1 2 3 4 5 6 7 8 9 10 11
若要將輸出儲存到文件,請使用輸出重定向:
python extract_subsequences.py data.txt > output.txt
答案2
AWK
方法:
僅考慮首先遇到的2個相同的連續數字,即適合多次提取,但不考慮2個相同的連續數字可能進入處理後的切片下的後續10個數字序列的情況。
awk 'NR==n && $1==v{ print v ORS $1 > "file"++c; tail=n+11; next }
{ v=$1; n=NR+1 }NR<tail{ print > "file"c }' file
答案3
第一個變體 - O(n)
awk '
/^[0-9]+$/{
arr[cnt++] = $0;
}
END {
for(i = 1; i < cnt; i++) {
if(arr[i] != arr[i - 1])
continue;
last_element = i + 11;
for(j = i - 1; j < cnt && j < last_element; j++) {
printf arr[j] " ";
}
print "";
}
}' input.txt
第二種變體 - O(n * n)
awk '
BEGIN {
cnt = 0;
}
/^[0-9]+$/{
if(prev == $0) {
arr[cnt] = prev;
cnt_arr[cnt]++;
cnt++;
}
for(i = 0; i < cnt; i++) {
if(cnt_arr[i] < 12) {
arr[i] = arr[i] " " $0;
cnt_arr[i]++;
}
}
prev = $0;
}
END {
for(i = 0; i < cnt; i++)
print arr[i];
}' input.txt
輸出
1 1 1 2 3 4 4 5 6 7 8 9
1 1 2 3 4 4 5 6 7 8 9 10
4 4 5 6 7 8 9 10 11 12 13 14
15 15 16