2012-08-16 58 views
2

我正在學習C#並嘗試解決以下問題: 返回重複成員的最長子數組,例如,如果數組是{1,2,2,3,4,4,4},我應該返回{4,4,4}。我試圖做到這一點,但它返回的是第一個子數組,而不是最長的。我所瞭解的C#至今:返回重複成員C#的最長子數組

  • 循環
  • 條件語句
  • 陣列

任何想法?

編輯:到目前爲止我的代碼 編輯:是的,我知道一些關於期多維數組

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace Sequence 
{ 
class Sequence 
{ 
    static void Main(string[] args) 
    { 
     Console.Write("Enter size:"); 
     int size1 = int.Parse(Console.ReadLine()); 
     int[] array1 = new int[size1]; 
     for (int i = 0; i <= size1-1; i++) 
     { 
      Console.Write ("Ënter Number:"); 
      array1[i]=Int32.Parse(Console.ReadLine()); 
     } 
     int bestLenght = 0; 
     int bestStart = 0; 
     int lenght = 0; 
     int start=0; 
     for (int i = 0; i < size1 - 2; i++) 
     { 
      if (i == 0 && array1[i] == array1[i + 1]) 
      { 
       start = 0; 
       lenght = 2; 
       if (bestLenght < lenght) 
       { 
        bestLenght = lenght; 
        bestStart = 0; 
       } 
      } 
      else if (i != 0 && lenght != 0 && array1[i] == array1[i - 1] && array1[i + 1] ==    array1[i]) 
      { 
       lenght++; 
       if (bestLenght < lenght) 
       { 
        bestLenght = lenght; 
        bestStart = start; 
       } 
      } 
      else if (i != 0 && array1[i - 1] != array1[i] && array1[i] == array1[i + 1]) 
      { 
       start = i; 
       lenght = 2; 
       if (bestLenght < lenght) 
       { 
        bestLenght = lenght; 
        bestStart = start; 
       } 

      } 
      else 
      { 
       lenght = 0; 
      } 


     } 
     Console.WriteLine(bestLenght); 



    } 
} 

}

Cureently我想只是返回最長陣列的lenght

+8

因此,請顯示一些代碼,你到目前爲止嘗試 – sloth 2012-08-16 09:17:13

+3

親愛的答覆者,作爲一個初學者,請避免LINQ。 – 2012-08-16 09:17:35

+0

你知道多維數組嗎? – Ketchup 2012-08-16 09:18:15

回答

1

編輯:您的代碼的問題是它沒有與邊緣的情況下處理時最長的名單是最後一個子表

變化

Console.WriteLine(bestLenght); 

來讀取

if (lenght > bestLenght) { 
    bestLenght=lenght; 
    bestStart=start; 
} 
Console.WriteLine(bestLenght); 

或者

你可以用linq Agregate做這個

var x= new[] {1,2,2,3,4,4,4}; 
var y=x.Aggregate(Tuple.Create(new List<int>(),new List<int>()), 
(a,b) =>{ 
    if (a.Item2.Count()>0 && a.Item2[0] != b) { 
    if (a.Item2.Count>a.Item1.Count()) { 
     a=Tuple.Create(a.Item2,new List<int>()); 
    } 
    a.Item2.Clear(); 
    } 
    a.Item2.Add(b); 
    return a; 
},a=>(a.Item2.Count() > a.Item1.Count()) ? a.Item2 : a.Item1); 

這本質上確實是在迭代使用一個元組來存儲2列出了採集,Item1代表最長先前的序列,Item2表示當前序列。

對於每個項目,如果當前序列不是空的,並且第一個項目不同,那麼我們在一個新的子列表中,所以檢查最後一個序列的長度,如果長度超過了先前的最大值,我們會替換之前的最大值,否則只是清除列表。

的agregate檢查這兩個列表較長(好像longests子集合是最後的項目1長度檢查將不會發生的最後一部分。

該代碼可以變成一個泛型函數處理任何類型,如下所示。

IEnumerable<T> LongestSublist<T>(IEnumerable<T> source) { 
return source.Aggregate(Tuple.Create(new List<T>(),new List<T>()), 
    (a,b) =>{ 
     if (a.Item2.Count()>0 && a.Item2[0] != b) { 
     if (a.Item2.Count>a.Item1.Count()) { 
      a=Tuple.Create(a.Item2,new List<T>()); 
     } 
     a.Item2.Clear(); 
     } 
     a.Item2.Add(b); 
     return a; 
    },a=>(a.Item2.Count() > a.Item1.Count()) ? a.Item2 : a.Item1); 

甚至作爲擴展功能

public static IEnumerable<T> LongestSublist<T>(this IEnumerable<T> source) { 
return source.Aggregate(Tuple.Create(new List<T>(),new List<T>()), 
    (a,b) =>{ 
     if (a.Item2.Count()>0 && a.Item2[0] != b) { 
     if (a.Item2.Count>a.Item1.Count()) { 
      a=Tuple.Create(a.Item2,new List<T>()); 
     } 
     a.Item2.Clear(); 
     } 
     a.Item2.Add(b); 
     return a; 
    },a=>(a.Item2.Count() > a.Item1.Count()) ? a.Item2 : a.Item1); 

讓你做

var longest = new [] {1,2,2,3,4,4,4} .LongestSubList();

+0

對於一個學習者..我認爲它很複雜。 Quesionare是:) – Peru 2012-08-16 09:45:07

+2

我學會了這種方式...深刻的結局。人們應該儘快學習Linq,它可以擺脫如此多的循環和嵌套ifs! – 2012-08-16 10:01:04

+0

正確...如果您有任何有用的鏈接,請分享我。我知道有很多鏈接..bt你的建議 – Peru 2012-08-16 10:38:29

1

你基本上需要做的是檢查前一個數字是否與當前數字相同,並相應增加一個計數器。

是精確的「循環遍歷數組的值複製到一個新的數組」和它遍歷副本只有當計數器的值高於」

希望這有助於

+0

重複的號碼可能相鄰也可能不相鄰 – freebird 2012-08-16 09:26:20

+0

我們只複製第一次重複的號碼 – Peru 2012-08-16 09:27:26

0

有幾種選擇你可以這樣做:

  1. Eeasiest是

    • 查找的每一個所有出現列表中的整數
    • 挑選出現次數最多的一個。
  2. 使用Linq,像這樣的:用數字

    var list = new List<int>{1,2,2,3,4,4,4} ; 
    var result = list.GroupBy(r => r).OrderByDescending(grp => grp.Count()).First(); 
    

    一)組(你會得到人1 S IN一組,2 S IN等,...等等

    b)訂單按每個元素的數量降序訂單,所以4在我們的情況下將成爲組的第一個有3個元素(更然後任何其他)

    c)中獲取第一個元素(列表)

+0

如果'list = new List {1,2,2,1,1,3,1,1,4, 4,4}'? – 2012-08-16 09:45:28

+0

@BobVale:它按*號*分組,並且不關心列表中元素的排序*。 – Tigran 2012-08-16 09:50:15

+0

OP說* REPEATING *成員因此順序很重要,你的代碼將返回{1,1,1,1,1}而不是{4,4,4} – 2012-08-16 09:53:35

2

一個非常迭代方法中的話:

  • 環路通過您的陣列中的每個項目。
  • 如果當前項目與前一項目相同,則將currentSeriesLength增加1。
  • 如果不是,則檢查longestSeriesLength。如果它更大,則將current index存儲在longestSeriesEnd中,將current index - currentSeriesLength存儲在longestSeriesStart中。
  • currentSeriesLength保存爲longestSeriesLength
  • 設置你的currentSeriesLength回到1
  • 您最長的系列將是一個longestSeriesStartlongestSeriesEnd之間的串聯。

這將是一個很好的練習,你將它翻譯成代碼。