2010-10-21 24 views
17

Tôi đang đọc một cuốn sách C# cho người mới bắt đầu, và trong mỗi đầu của chương, có các bài tập được trả lời dựa trên các bài học được giải quyết.Có thể diễn tả mã này trong LINQ không?

Một trong những bài tập đi theo cách này: (không phải là các chữ chính xác)

Viết một chương trình mà sẽ chấp nhận một int như độ dài mảng, và các giá trị cho mảng.
Sau đó, sẽ in:
"" nếu mảng không được sắp xếp theo chiều tăng dần.
"" nếu được sắp xếp. Và,
"" nếu được sắp xếp, nhưng có bản sao.

Ví dụ:

// Sorted 
Input: 1, 2, 3, 5 
Print: 1 

// Not sorted 
Input: 2, 1, 3, 6 
Print: 0 

// Sorted, but with duplicates 
Input: 2, 2, 3, 7 
Print: 2 

Tôi không biết nếu logic của tôi ở đây là tuyệt đối, nhưng bằng cách nào đó nó đang làm việc,
và tôi thực hiện nó theo cách của tôi sử dụng mã này:

int arrayLength = 0; 
int prev, next; 
int sortStatus = 1; 

Console.Write("Input array Length: "); 
arrayLength = Convert.ToInt32(Console.ReadLine()); 
int[] ar = new int[arrayLength]; 

for (int x = 0; x < arrayLength; x++) 
{ 
    Console.Write("Input {0} value: ", (x+1).ToString()); 
    ar[x] = Convert.ToInt32(Console.ReadLine()); 
} 

for (int x = 0; x < ar.Length-1; x++) 
{ 
    prev = (int)ar[x]; 
    next = (int)ar[x + 1]; 

    if (next < prev) 
     sortStatus = 0; 
    if (next == prev) 
     sortStatus = 2; 
} 

Console.Write(sortStatus.ToString()); 
Console.Read(); 

Có thể diễn tả điều này trong LINQ không? Làm sao?

+3

+1 cho hỏi một câu hỏi cũng có cấu trúc, cũng như muốn biết làm thế nào để cải thiện những gì bạn đã làm. – RPM1984

+0

@ RPM1984: cảm ơn sir :) – yonan2236

+0

Cho rằng mã thực tế có chứa logic 'isSorted' dài hơn 10 dòng (và thực sự nên theo phương thức riêng của nó), bạn có thực sự muốn một câu lệnh LINQ phức tạp để thay thế nó không? –

Trả lời

17
if (ar.SequenceEqual(ar.OrderBy(x => x))) 
{ 
    if (ar.Distinct().Count() == ar.Length) 
     return 1; 
    else 
     return 2; 
} 
else 
{ 
    return 0; 
} 
+0

Xin cảm ơn, tôi sẽ thử ... – yonan2236

+0

Vâng, đây là cách để đi. Công việc tốt đẹp. +1 – RPM1984

+0

nó hoạt động sir ... :) cảm ơn. – yonan2236

5

Một LINQ thay thế tinh khiết ... (đã quan tâm đến học tập duy nhất (nhưng có lẽ vẫn còn nhanh hơn so với câu trả lời chấp nhận!)

var input = new int[] { 1, 2, 3, 4, 5 }; 

var output = input.Zip(input.Skip(1), (a, b) => new {a=a, b=b}) 
       .Aggregate(1, (status, x) => status == 0 ? 0 : ((x.a > x.b ? 0 : (x.a == x.b ? 2 : status)))); 
+0

Hmm .. 'đầu vào' ở đây là gì? Có phải mảng của tôi không? – yonan2236

+0

Có, đầu vào sẽ là mảng của bạn. –

+0

cảm ơn ông vì phiên bản trả lời của bạn :) – yonan2236

3

Là một lưu ý, bày tỏ không LINQ logic của bạn có một lỗ hổng .

if (next < prev) 
    sortStatus = 0; 
if (next == prev) 
    sortStatus = 2; 

quy tắc của bạn nói rằng mảng phải được sắp xếp tăng dần nhưng có bản sao để có được một sản lượng 2. Tuy nhiên, logic của bạn sẽ trở lại 2 cho { 1, 9, 7, 7 }.

Một cách khác để viết mã của bạn có thể như sau. (Điều này không sử dụng LINQ, nhưng điều này là quá lâu để gửi như một bình luận cho câu hỏi của bạn.)

static int EvaluateArray(int[] array) 
{ 
    int? lastItem = null; 
    bool match = false; 
    foreach (int item in array) 
    { 
     if (item < lastItem) 
      return 0; 
     else if (item == lastItem) 
      match = true; 

     lastItem = item; 
    } 

    if (match) 
     return 2; 

    return 1; 
} 

Trong phương pháp này, chúng tôi sẽ sớm quay trở lại ngay khi chúng tôi có một mục dưới mục trước . Nếu không, chúng tôi sẽ thiết lập một boolean nếu chúng ta đi qua một giá trị phù hợp. Vào cuối vòng lặp, chúng ta biết mảng được sắp xếp tăng dần. Điều duy nhất còn lại là kiểm tra nếu có một trận đấu.

+0

Cảm ơn bạn đã đưa ra lỗi lầm của tôi. Tôi sẽ học hỏi từ nó. – yonan2236

+0

Chỉ là một câu hỏi, trong mã của bạn ở trên, đoạn mã này có nghĩa là gì? 'int? lastItem = null; '. Điều '"? "' Có ... – yonan2236

+2

@yonan: Đó là viết tắt của 'Nullable '. C# 2 giới thiệu khái niệm về các kiểu giá trị rỗng. Các kiểu giá trị bình thường như 'int' không thể được đặt thành null, dẫn đến các nhà phát triển sử dụng các giá trị" huyền diệu "thường có nghĩa là" không có giá trị ". (Xem xét 'string.IndexOf (chuỗi con)' trả về -1 nếu chuỗi con không tìm thấy trong chuỗi.) Với 'Nullable ', bây giờ chúng ta có một cách để chỉ ra một cái gì đó không có giá trị. Trong C#, chúng ta có thể diễn tả bằng cách viết tắt. 'int?' là viết tắt của 'Nullable ' giống như 'int' thực sự là viết tắt của C# cho' Int32'. –

0

Chưa được kiểm tra.

IEnumerable<int> signs = 
    from i in Enumerable.Range(0, ar.Length).Skip(1) 
    select ar[i-1].CompareTo(ar[i]); 

int result = 
    signs.Any(sign => sign < 0) ? 0 : 
    signs.All(sign => 0 < sign) ? 1 : 
    2; 

Cũng chưa được kiểm tra:

int minSign = !ar.Skip(1).Any() ? 1 : 
(
    from i in Enumerable.Range(0, ar.Length).Skip(1) 
    select ar[i-1].CompareTo(ar[i]) 
).TakeWhile(x => 0 <= x).Min(); 

int result = 
    minSign < 0 ? 0 : 
    0 < minSign ? 1 : 
    2; 
+0

Hãy tha thứ cho nghệ thuật ascii của tôi ... thực sự, hãy cho tôi biết nếu bit đó là khó hiểu - (x => 0 <= x) –

+0

cảm ơn câu trả lời :) – yonan2236

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