Tôi cần tìm chuỗi trong chuỗi lớn khác, ví dụ: {1,3,2,3}
có trong {1,3,2,3,4,3}
và {5,1,3,2,3}
. Có cách nào để thực hiện nhanh chóng với IEnumerable
hoặc bằng cách nào khác không?Tìm một chuỗi trong chuỗi dài hơn
Trả lời
Bạn có thể thử một cái gì đó như thế này để giúp bạn bắt đầu. Một khi bạn đã chuyển đổi danh sách này thành một chuỗi, bạn có thể tìm thấy những chuỗi bằng cách sử dụng chuỗi con:
if (String.Join(",", numericList.ConvertAll<string>(x => x.ToString()).ToArray())
{
//get sequence
}
Phương pháp này sẽ tìm thấy một dãy con trong một chuỗi phụ huynh, của bất kỳ loại có thể được so sánh qua Equals()
:
public static bool ContainsSubequence<T>(this IEnumerable<T> parent, IEnumerable<T> target)
{
bool foundOneMatch = false;
using (IEnumerator<T> parentEnum = parent.GetEnumerator())
{
using (IEnumerator<T> targetEnum = target.GetEnumerator())
{
// Get the first target instance; empty sequences are trivially contained
if (!targetEnum.MoveNext())
return true;
while (parentEnum.MoveNext())
{
if (targetEnum.Current.Equals(parentEnum.Current))
{
// Match, so move the target enum forward
foundOneMatch = true;
if (!targetEnum.MoveNext())
{
// We went through the entire target, so we have a match
return true;
}
}
else if (foundOneMatch)
{
return false;
}
}
return false;
}
}
}
Bạn có thể sử dụng nó như thế này:
bool match = new[] {1, 2, 3}.ContainsSubsequence(new[] {1, 2}); // match == true
match = new[] {1, 2, 3}.ContainsSubsequence(new[] {1, 3}); // match == false
Lưu ý rằng nó giả định trình tự mục tiêu không có người null
yếu tố.
Cập nhật: Cảm ơn upvotes, tất cả mọi người, nhưng có thực sự là một lỗi trong đoạn code trên! Nếu tìm thấy một phần khớp, nhưng sau đó không biến thành một kết hợp đầy đủ, quá trình này là đã kết thúc, thay vì đặt lại (rõ ràng là không được khắc phục khi áp dụng cho một cái gì đó như {1, 2, 1, 2, 3}.ContainsSubsequence({1, 2, 3})
).
Đoạn mã trên hoạt động thực sự tốt cho định nghĩa phổ biến hơn về sau (nghĩa là không cần tiếp giáp) nhưng để xử lý việc cài đặt lại (hầu hết các số IEnumerators
không hỗ trợ), thì chuỗi đích cần được liệt kê phía trước. Điều đó dẫn đến mã sau:
public static bool ContainsSubequence<T>(this IEnumerable<T> parent, IEnumerable<T> target)
{
bool foundOneMatch = false;
var enumeratedTarget = target.ToList();
int enumPos = 0;
using (IEnumerator<T> parentEnum = parent.GetEnumerator())
{
while (parentEnum.MoveNext())
{
if (enumeratedTarget[enumPos].Equals(parentEnum.Current))
{
// Match, so move the target enum forward
foundOneMatch = true;
if (enumPos == enumeratedTarget.Count - 1)
{
// We went through the entire target, so we have a match
return true;
}
enumPos++;
}
else if (foundOneMatch)
{
foundOneMatch = false;
enumPos = 0;
if (enumeratedTarget[enumPos].Equals(parentEnum.Current))
{
foundOneMatch = true;
enumPos++;
}
}
}
return false;
}
}
Mã này không có lỗi, nhưng sẽ không hoạt động tốt cho các chuỗi lớn (hoặc vô hạn).
Bạn đã phạm sai lầm trong ví dụ của bạn? Làm thế nào là 1, 3 một chuỗi trong 1, 2, 3? Cả hai số tồn tại, nhưng không theo thứ tự. Có vẻ như phương pháp của bạn xác định liệu số tồn tại, không liên quan đến thứ tự hoặc chuỗi. –
@James Như tôi đã đề cập ở phần cuối, nó cho phép các chuỗi không tiếp giáp (ví dụ, '{1, 2, 3} .ContainsSubequence ({2, 1, 3}) == false'.) Như tôi cũng đề cập đến ở cuối, điều kiện đó có thể dễ dàng áp đặt, nên điều đó được yêu cầu. Thông thường khi nói về các chuỗi, sự liền kề là * không * bắt buộc (xem, ví dụ, vấn đề sau phổ biến dài nhất.) – dlev
Nó không nên cho phép các chuỗi tiếp giáp không tiếp giáp. – user906763
Tương tự như @ dlev của nhưng điều này cũng xử lý {1,1,1,2}.ContainsSubsequence({1,1,2})
public static bool ContainsSubsequence<T>(this IEnumerable<T> parent, IEnumerable<T> target)
{
var pattern = target.ToArray();
var source = new LinkedList<T>();
foreach (var element in parent)
{
source.AddLast(element);
if(source.Count == pattern.Length)
{
if(source.SequenceEqual(pattern))
return true;
source.RemoveFirst();
}
}
return false;
}
+1 Làm tăng ngắn gọn, metakes, methanks ... –
Một sự tinh tế quan trọng trong việc thực hiện này là nó chỉ liệt kê từng bộ sưu tập được truyền vào một lần, làm cho phương thức nội bộ nhất quán nếu nó được gọi với các bộ sưu tập có thứ tự liệt kê là không xác định. Cũng lưu ý rằng một hàng đợi
này làm việc cho tôi
var a1 = new List<int> { 1, 2, 3, 4, 5 };
var a2 = new List<int> { 2, 3, 4 };
int index = -1;
bool res = a2.All(
x => index != -1 ? (++index == a1.IndexOf(x)) : ((index = a1.IndexOf(x)) != -1)
);
Giải pháp của bạn có vẻ thanh lịch nhất nhưng hãy thử với 'a1 = new List
Hàm này kiểm tra liệu Danh sách parent
chứa Danh sách target
sử dụng một số LINQ:
public static bool ContainsSequence<T>(this List<T> parent, List<T> target)
{
for (int fromElement = parent.IndexOf(target.First());
(fromElement != -1) && (fromElement <= parent.Count - target.Count);
fromElement = parent.FindIndex(fromElement + 1, p => p.Equals(target.First())))
{
var comparedSequence = parent.Skip(fromElement).Take(target.Count);
if (comparedSequence.SequenceEqual(target)) return true;
}
return false;
}
Nếu bạn đang xử lý đơn giản serializable loại, bạn có thể làm điều đó khá dễ dàng nếu bạn chuyển đổi các mảng chuỗi:
public static bool ContainsList<T>(this List<T> containingList, List<T> containedList)
{
string strContaining = "," + string.Join(",", containingList) + ",";
string strContained = "," + string.Join(",", containedList) + ",";
return strContaining.Contains(strContained);
}
Lưu ý đó là một phương pháp khuyến nông, vì vậy bạn sẽ có thể gọi nó là thích:
if (bigList.ContainsList(smallList))
{
...
}
- 1. tìm ra "chuỗi dài" của một int
- 2. Chuỗi con chung dài nhất từ hơn hai chuỗi - Python
- 3. heightForRowAtIndexPath cho chuỗi dài hơn NSStrings
- 4. cách tìm chuỗi dài nhất trong một chuỗi [] bằng cách sử dụng LINQ
- 5. Cách tìm chiều dài của một chuỗi trong R?
- 6. Kiểm tra chuỗi con/chuỗi con gần đúng tồn tại trong một chuỗi dài hơn, bằng Python?
- 7. tách một chuỗi dài thành chuỗi nhỏ
- 8. Tìm chuỗi lặp đi lặp lại dài nhất trong một chuỗi
- 9. Tìm tất cả các vị trí của chuỗi con trong một chuỗi lớn hơn trong C#
- 10. Tìm dài nhất không giảm chuỗi
- 11. tìm số chuỗi trong một chuỗi các chuỗi trong C
- 12. Làm cách nào để tìm chuỗi dài nhất trong Python?
- 13. tìm chiều dài của chuỗi số liên tiếp dài nhất
- 14. Tìm biên giới dài nhất của một chuỗi
- 15. Thuật toán nhanh nhất để tìm một chuỗi trong một chuỗi các chuỗi?
- 16. Tìm một chuỗi chung trong danh sách các chuỗi
- 17. Tìm chuỗi các chuỗi trong các chuỗi
- 18. tìm vị trí của một chuỗi con trong một chuỗi
- 19. Chiều dài chuỗi bash
- 20. Lệnh shell để tìm chuỗi con dài nhất của hai chuỗi trong unix là gì?
- 21. Sử dụng Java để tìm chuỗi con của một chuỗi lớn hơn sử dụng Regular Expression
- 22. Chuỗi con trong Java - dài tới một giá trị
- 23. Độ dài của một chuỗi theo pixel
- 24. Chuỗi con không hoạt động như mong đợi nếu chiều dài lớn hơn chiều dài của chuỗi
- 25. tìm tất cả chuỗi trong một mảng
- 26. Cắt chuỗi dựa trên độ dài chuỗi
- 27. Độ dài chuỗi động C
- 28. tìm kiếm các bản lặp dài lặp đi lặp lại trong một chuỗi lớn
- 29. Tìm xem chuỗi con có tồn tại trong một chuỗi
- 30. cách tìm trước và sau chuỗi con trong một chuỗi
là chuỗi trong một int mảng, hoặc chỉ là một chuỗi phân tách bằng dấu phẩy? –
Trong thực tế, nó là một danh sách có thể được chuyển đổi thành mảng. –
user906763
Bạn có muốn kiểm tra xem chuỗi có nằm trong chuỗi không và trả về true/false? – BoltClock