我無法確定在 Dart 中執行此操作的最有效方法。
如果有兩個按降序排列的串列,
List<int> messages = [10, 5, 4, 1];
List<int> newMessages = [5, 3, 2];
我怎樣才能添加newMessages到messages現在messages看起來像
messages = [10, 5, 5, 4, 3, 2, 1];
uj5u.com熱心網友回復:
如果兩個串列都很長,并且使用默認串列實作,則基于其他兩個串列創建新串列可能更有效。原因是在現有串列中插入元素需要將該插入索引之后的所有元素向前移動。此外,當串列增長時,它需要分配一個更大的串列并將所有元素移入其中。
如果我們改為創建一個新串列,我們可以告知 Dart 這個串列的確切大小,并且我們可以防止移動元素:
void main() {
List<int> messages = [10, 5, 4, 1];
List<int> newMessages = [5, 3, 2];
// The compare argument is given since both lists are sorted in reverse order
print(newSortedListBasedOnTwoAlreadySortedLists<int>(
messages, newMessages, (a, b) => b.compareTo(a)));
// [10, 5, 5, 4, 3, 2, 1]
}
List<E> newSortedListBasedOnTwoAlreadySortedLists<E>(
List<E> l1,
List<E> l2, [
int Function(E a, E b)? compare,
]) {
Iterator<E> i1 = l1.iterator;
Iterator<E> i2 = l2.iterator;
if (!i1.moveNext()) {
if (!i2.moveNext()) {
return [];
} else {
return l2.toList();
}
}
if (!i2.moveNext()) {
return l1.toList();
}
bool i1alive = true;
bool i2alive = true;
return List.generate(l1.length l2.length, (_) {
if (i1alive && i2alive) {
E v1 = i1.current;
E v2 = i2.current;
int compareResult = (compare == null)
? Comparable.compare(v1 as Comparable, v2 as Comparable)
: compare(v1, v2);
if (compareResult > 0) {
i2alive = i2.moveNext();
return v2;
} else {
i1alive = i1.moveNext();
return v1;
}
} else if (i1alive) {
E v1 = i1.current;
i1alive = i1.moveNext();
return v1;
} else {
E v2 = i2.current;
i2alive = i2.moveNext();
return v2;
}
});
}
注意:該方法理論上可以使用兩個Iterable作為引數,只要我們確定呼叫.length不會產生任何負面后果,例如需要迭代整個結構(例如映射)。為了防止這個問題,我最終宣告了List作為引數的方法,因為我們確定這.length在這里沒有問題。
uj5u.com熱心網友回復:
這聽起來像您需要合并兩個串列。如其他地方所述,創建新串列比在現有串列中移動元素更有效。
合并可以相當簡單地撰寫:
/// Merges two sorted lists.
///
/// The lists must be ordered in increasing order according to [compare].
///
/// Returns a new list containing the elements of both [first] and [second]
/// in increasing order according to [compare].
List<T> merge<T>(List<T> first, List<T> second, int Function(T, T) compare) {
var result = <T>[];
var i = 0;
var j = 0;
while (i < first.length && j < second.length) {
var a = first[i];
var b = second[j];
if (compare(a, b) <= 0) {
result.add(a);
i ;
} else {
result.add(b);
j ;
}
}
while (i < first.length) {
result.add(first[i ]);
}
while (j < second.length) {
result.add(second[j ]);
}
return result;
}
(在這種情況下,串列是降序的,所以它們需要一個比較函式來反轉順序,比如(a, b) => b.compareTo(a))
uj5u.com熱心網友回復:
您可以使用二分查找以排序的方式將所有新訊息一一插入,同時保持效率。
void main() {
List<int> messages = [10, 5, 4, 1];
List<int> newMessages = [5, 3, 2];
for (final newMessage in newMessages) {
final index = binarySearchIndex(messages, newMessage);
messages.insert(index, newMessage);
}
print(messages); // [10, 5, 5, 4, 3, 2, 1]
}
int binarySearchIndex(
List<int> numList,
int value, [
int? preferredMinIndex,
int? preferredMaxIndex,
]) {
final minIndex = preferredMinIndex ?? 0;
final maxIndex = preferredMaxIndex ?? numList.length - 1;
final middleIndex = ((maxIndex - minIndex) / 2).floor() minIndex;
final comparator = numList[middleIndex];
if (middleIndex == minIndex) {
return comparator > value ? maxIndex : minIndex;
}
return comparator > value ?
binarySearchIndex(numList, value, middleIndex, maxIndex):
binarySearchIndex(numList, value, minIndex, middleIndex);
}
uj5u.com熱心網友回復:
void main() {
List<int> messages = [10, 5, 4, 1];
List<int> newMessages = [5, 3, 2];
messages = [...messages, ...newMessages]..sort((b, a) => a.compareTo(b));
print(messages); // [10, 5, 5, 4, 3, 2, 1]
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/488085.html
上一篇:檢查物件?為空
