[英]How to find N longest lines in a text file
編寫一個程序來讀取多行文本文件並將“N”個最長的行寫入標准輸出。
有一個類似的問題,但我並不真正理解它,因為它涉及使用最小堆,並且由於我必須創建一個最小堆數據結構,這會產生更多的工作。
我試圖創建一個大小為 n 的數組。 然后對其進行排序,但每次在數組中插入新行時,我都必須對其進行排序。 我想知道什么是簡單的方法,什么是最佳方法。
創建一個包含 N 個字符串的數組。
循環瀏覽文件。
如果數組中的項目數 < N 則只需將其添加到末尾。
在所有情況下,將最短的行存儲在數組中。 如果數組已滿,則與最短的行進行比較,如果新行>則該行,替換並找到最短的行。
重復循環。
打印字符串。
假設不允許多條相同長度的行。 這是算法:
如果允許具有相同長度的多行,則必須修改 Dictionary 以包含 List 作為值。 這是代碼:
SortedDictionary> 已處理 = 新的 SortedDictionary>();
int N;
StreamReader reader = File.OpenText(args[0]);
N = int.Parse(reader.ReadLine());
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
if (string.IsNullOrWhiteSpace(line) || string.IsNullOrEmpty(line))
continue;
line.Trim();
if (processed.ContainsKey(line.Length))
{
processed[line.Length].Add(line);
}
else
{
processed.Add(line.Length, new List<string> { line });
}
}
while(N != 0)
{
foreach (KeyValuePair<int, List<string>> kvp in processed.Reverse())
{
kvp.Value.ForEach(c => Console.WriteLine(c));
if (--N == 0)
break;
}
}
編輯:正如其他人提到的,我的第一個解決方案不適用於相同長度的行。 更好的方法是使用java.util.PriorityQueue<Line>
並像這樣定義 object Line:
class Line {
private final String line;
public Line(String line) {
this.line = line;
}
public int getLen() {
return line.length();
}
public String getLine() {
return line;
}
}
然后實例化一個PriorityQueue
並使用Comparator
指定順序。
PriorityQueue<E>
: PriorityQueue(int initialCapacity, Comparator<? super E> comparator)
創建一個具有指定初始容量的 PriorityQueue,它根據指定的比較器對其元素進行排序。
這是一個使用單元測試的實驗。
int n = 1;
PriorityQueue<Line> queue = new PriorityQueue<Line>(n, new Comparator<Line>() {
@Override
public int compare(Line a, Line b) {
return a.getLen() - b.getLen();
}
});
queue.add(new Line("abcd"));
queue.add(new Line("abcde"));
queue.add(new Line("abc"));
assertEquals(queue.poll().getLine(), "abc");
assertEquals(queue.poll().getLine(), "abcd");
assertEquals(queue.poll().getLine(), "abcde");
在這個例子中,我們看到 poll remove 首先刪除列表中的最小元素。 如果queue.size() > n
在每行插入后,您可以簡單地調用queue.poll()
。
這是我的解決方案
使用樹形圖的原因是為了處理具有相同長度的多行,在這種情況下,所有行將被添加到同一個 ArrayList
public class DataCollector {
private int size;
private TreeMap<Integer, List<String>> data = new TreeMap<Integer, List<String>>();
public DataCollector(int nthLargest) {
if (nthLargest < 1) {
throw new IllegalArgumentException("can not be smaller than 1");
}
this.size = nthLargest;
}
public void feed(String line) {
int length = line.length();
if (data.size() > 0 && length < data.firstKey()) {
return;
}
getList(length).add(line);
if (data.size() > size) {
data.remove(data.firstKey());
}
}
private List<String> getList(int key) {
if (!data.containsKey(key)) {
data.put(key, new ArrayList<String>());
}
return data.get(key);
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
for (Entry<Integer, List<String>> entry : data.entrySet()) {
builder.append(entry.getKey()).append("=").append(entry.getValue()).append("\r\n");
}
return builder.toString();
}
public List<String> getResult() {
if (data.isEmpty()) {
return Collections.EMPTY_LIST;
}
return data.firstEntry().getValue();
}
public static void main(String[] args) {
DataCollector co = new DataCollector(1);
co.feed("b");
co.feed("abc");
co.feed("abc1");
co.feed("abc2");
co.feed("abc33");
co.feed("abc34");
co.feed("abc23");
co.feed("abc23b");
co.feed("abc23b");
co.feed("abc23c");
co.feed("abc23dd");
co.feed("abc23ee");
co.feed("a");
System.out.println(co);
System.out.println(co.getResult());
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.