2017-12-14 139 views
5

Có một danh sách các giá trị nhị phân: lây nhiễm truyền giá trị cho các mục liền kề của danh sách, trong C#

List<bool> myList = new List<bool>(){true, true, false, false, true, false, false, false, true, true, true, false, false}; 

thuật toán của tôi nhằm mục đích để chuyển đổi bất kỳ mục false thành true, nếu họ tiếp giáp với một sự thật giá trị:

result = {true, true, true, true, true, true, false, true, true, true, true, true, false} 

Giải pháp của tôi hoạt động, như bạn sẽ thấy. Tôi có thể thực hiện điều đó thông qua hai vòng khác nhau và sau đó nén hai danh sách:

List<bool> firstList = new List<bool>(); 
List<bool> secondList = new List<bool>(); 
for(int i=0; i<myList.Count()-1; i++){ 
    if(myList[i]==true){ 
    firstList[i]=true; 
    firstList[i+1]=true; 
    } 
} 

for(int i=1; i<myList.Count(); i++){ 
    if(myList[i]==true){ 
    secondList[i]=true; 
    secondList[i-1]=true; 
    } 
} 

List<bool> finalList = firstList.Zip(secondList, (a,b)=>a||b).ToList(); 

Tuy nhiên, đây không phải là giải pháp tốt nhất vì vấn đề trông rất dễ dàng. Bất kỳ ý tưởng để làm điều đó thông qua một vòng lặp hoặc tốt hơn bằng cách sử dụng LINQ?

Trả lời

6

Dưới đây là một phương pháp LINQ

Về cơ bản nó có hành vi tương tự như cách tiếp cận của bạn - những yếu tố tự x, trước .ElementAtOrDefault(i - 1) hoặc các yếu tố .ElementAtOrDefault(i + 1) tiếp theo có đến mức khó tin.

List<bool> result = myList.Select((x, i) => x || myList.ElementAtOrDefault(i - 1) || myList.ElementAtOrDefault(i + 1)).ToList(); 
+0

tại sao không sử dụng tổng hợp? –

6

Bạn có thể làm điều đó trong một vòng lặp:

List<bool> result = myList.Select((b, index) => 
        b || 
        (index > 0 && myList[index-1]) || 
        (index < (myList.Count - 1) && myList[index+1])).ToList(); 

này có tất cả các b trong myList và séc của bạn (thông qua index) nếu tự làm việc này hoặc các giá trị adjacting là true. Tất nhiên chúng ta phải kiểm tra index cho các ranh giới danh sách.

+0

@Cảm ơn bạn đã giải pháp thông minh. đập lên nhưng nếu bạn không nhớ, tôi chấp nhận giải pháp của fubo. Tôi thích cách anh ta sử dụng phương pháp ElementAtOrDefault. –

+2

@AryanFirouzyan Đó là tốt, chấp nhận một trong những phù hợp với nhu cầu của bạn. 'ElementAtOrDefault()' thực sự đẹp hơn. –

1

Tôi không nghĩ rằng điều này đặc biệt có thể đọc được, nhưng:

var indexesToChange = 
    Enumerable.Range(0, myList.Count) 
    .Where(n => myList[n] 
     || (n-1 >= 0 && myList[n-1]) 
     || (n+1 < myList.Count && myList[n+1])) 
    .ToList(); 

foreach (var i in indexesToChange) 
{ 
    myList[i] = true; 
} 

này sẽ cập nhật danh sách cũ. Bạn có thể sao chép vào danh sách mới trong vòng lặp foreach nếu bạn không muốn thay đổi danh sách cũ.

Các vấn đề liên quan