Эффективно удалить последние нули в списке целых чисел (C# или vb.net)
Я удаляю самые правые нули в списке целых чисел (они могут быть только 0 или 1) следующим образом:
For i As Integer = Product.Count - 1 To 0 Step -1
If Product(i) = 0 Then
Product.RemoveAt(i)
Else
Exit For
End If
Next
Не могли бы вы предложить решение, которое было бы менее неудобным и, возможно, более эффективным из того, что я сейчас делаю?
Если возможно, я хотел бы также увидеть альтернативное решение для сохранения 1 нуля, если список содержит только 1 ноль и 1 ноль. Спасибо (язык, C# из vb.net не имеет значения).
(PS. Обратите внимание, что "эффективность", которая является частью вопроса, является объективным критерием, не основанным на мнениях.)
4 ответа
Я бы сделал это:
public void RemoveTrailingZeros( List<int> digits )
{
int i = digits.Count ;
while ( --i >= 0 && digits[i] == 0 )
{
digits.RemoveAt(i) ;
}
return ;
}
Еще аккуратнее:
static void RemoveTrailingZeroes( List<int> digits )
{
int i = 1 + digits.FindLastIndex( x => x != 0 ) ;
digits.RemoveRange(i,digits.Count-i) ;
return ;
}
Если значения могут быть только 0 или 1, вы можете найти последнюю 1 и удалить все после этого.
Dim index As Integer
index = Product.LastIndexOf(1) + 1
Product.RemoveRange(index, Product.Count - index)
Если список содержит только 0, индекс будет равен 0, поэтому вы можете добавить if if прямо перед RemoveRange.
Dim index As Integer
index = Product.LastIndexOf(1) + 1
If index = 0 Then index = 1
Product.RemoveRange(index, Product.Count - index)
(Может произойти сбой, если в списке нет элементов)
Обновить
Поскольку он ищет 1, индексом первого 0 будет индекс, возвращаемый +1. Это также решает проблему с функцией, возвращающей -1, когда все нули.
Я не уверен, что это более элегантно, но он использует LINQ!
int lastOne = i.IndexOf(i.Last(n => n == 1));
List<int> trimmedList = i.Take(lastOne + 1); //Account for zero-based index
Чтобы получить один ноль, я бы использовал LastOrDefault
int lastOne = i.IndexOf(i.LastOrDefault(n => n == 1));
List<int> trimmedList = i.Take(lastOne + 1); //Account for zero-based index
Безусловно, самый "крутой" метод LINQ, предложенный Алексеем Левенковым:
Reverse().SkipWhile(i=> i==0).Reverse();
Это удалит один нулевой случай, в этом случае я бы использовал троичный:
i.All(n => n == 0) ? i.Take(1) : i.Reverse().SkipWhile(i=> i==0).Reverse();