2008-11-10 82 views
11

Tôi có Array này tôi đã viết một hàm MostFreq lấy một mảng số nguyên và trả về 2 giá trị: số thường xuyên hơn trong mảng và tần suất kiểm tra mã này i worte bạn nghĩ sao? có cách nào tốt hơn để làm điều đó không?Số thường xuyên nhất trong một mảng

static void Main() 
{ 
    int [] M={4,5,6,4,4,3,5,3}; 
    int x; 
    int f=MyMath.MostFreq(M,out x); 
    console.WriteLine("the most Frequent Item = {0} with frequency = {1}",x,f); 
} 

=====

trong Mymath lớp

public static int MostFreq(int[] _M, out int x) 
{ 
    //First I need to sort the array in ascending order 
    int Max_Freq, No_Freq, i, k; 
    Array.Sort(_M);       
    k = _M[0]; 
    Max_Freq = 0; i = 0; x = 0; 
    while (i < _M.Length) 
    { 
     //No_Freq= the frequency of the current number 
     No_Freq = 0; 
     //X here is the number which is appear in the array Frequently 
     while (k == _M[i]) 
     { 
      No_Freq++; 
      i++; 
      if (i == _M.Length) 
       break; 
     } 
     if (No_Freq > Max_Freq) 
     { 
      //so it will be printed the same 
      Max_Freq = No_Freq; 
      x = k; 
     } 
     if (i < _M.Length) k = _M[i]; 
    } 
    return (Max_Freq); 
} 
+0

Tại sao điều này được đánh giá thấp và đánh dấu xúc phạm? – FlySwat

+0

@Brandon Bạn đang sử dụng phiên bản C# nào? –

+0

Tôi vừa chỉnh sửa các thẻ để mọi người biết nên nhắm vào phiên bản nào. –

Trả lời

7

LINQ nó lên. Tôi biết điều này là trong VB nhưng bạn sẽ có thể chuyển nó sang C#:

Dim i = From Numbers In ints _ 
      Group Numbers By Numbers Into Group _ 
      Aggregate feq In Group Into Count() _ 
      Select New With {.Number = Numbers, .Count = Count} 

EDIT: Bây giờ trong C# quá:

var i = from numbers in M 
       group numbers by numbers into grouped 
       select new { Number = grouped.Key, Freq = grouped.Count()}; 
+0

Tôi thích bạn làm điều đó :) –

3

Từ một quan điểm kỹ thuật phần mềm, tôi mong chờ một chức năng gọi là MostFreq trả về phần tử có tần số cao nhất - không phải tần số chính nó. Tôi sẽ chuyển đổi của bạn ra và trả về giá trị.

5

Giả sử bạn không thể sử dụng LINQ, tôi có lẽ muốn tiếp cận các thuật toán như thế này:

  • Tạo từ điển Key/Value
  • Lặp mảng của bạn, thêm một chìa khóa từ điển cho mỗi elem độc đáo, tăng giá trị mỗi khi phần tử được lặp lại.
  • Đi bộ các phím từ điển và trả lại elem có giá trị cao nhất.

Đây không phải là giải pháp tuyệt vời nhưng đơn giản, ContainsKey là tra cứu O (1), vì vậy bạn sẽ lặp lại nhiều nhất mảng của mình hai lần.

+0

yep, thats cool Tôi sẽ thử nó thanx –

1

Bạn có thể loại bỏ sắp xếp bạn làm lúc đầu bằng cách lặp lại toàn bộ mảng một lần, giữ số lần bạn xem qua từng giá trị trong một mảng tạm thời, và sau đó lặp lại mảng tạm thời cho số cao nhất. Bạn có thể giữ cả số tần số cao nhất và mục thường xuyên nhất trong suốt.

Các loại khác nhau có hiệu quả khác nhau trên các loại dữ liệu khác nhau, tất nhiên, nhưng đây sẽ là trường hợp xấu nhất chỉ với hai lần lặp.

Edit: Xin lỗi cho lặp lại ... 'Tweren't có khi tôi bắt đầu :)

0
int count = 1; 
int currentIndex = 0; 
for (int i = 1; i < A.Length; i++) 
{ 
    if (A[i] == A[currentIndex]) 
     count++; 
    else 
     count--; 
    if (count == 0) 
    { 
     currentIndex = i; 
     count = 1; 
    } 
} 

int mostFreq = A[currentIndex]; 
+2

Ngay cả với thuật toán đơn giản, nó là một thực hành tốt để giải thích những gì nó làm và quan trọng nhất tại sao bạn làm theo cách đó. Những lợi thế, bất lợi, vv :) – ForceMagic

0
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace MostFrequentElement 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      int[] array = new int[] { 4, 1, 1, 4, 2, 3, 4, 4, 1, 2, 4, 9, 3, 1, 1, 7, 7, 7, 7, 7 }; 
      Array.Sort(array, (a, b) => a.CompareTo(b)); 
      int counter = 1; 
      int temp=0 ; 

      List<int> LOCE = new List<int>(); 
      foreach (int i in array) 
      { 
       counter = 1; 
       foreach (int j in array) 

{ 
        if (array[j] == array[i]) 
        { 
         counter++; 
        } 
        else { 
        counter=1; 
        } 
        if (counter == temp) 
        { 
         LOCE.Add(array[i]); 
        } 
        if (counter > temp) 
        { 
         LOCE.Clear(); 
         LOCE.Add(array[i]); 
         temp = counter; 

        } 
       } 

      } 
      foreach (var element in LOCE) 
      { 
       Console.Write(element + ","); 
      } 
      Console.WriteLine(); 
      Console.WriteLine("(" + temp + " times)"); 
      Console.Read(); 
     } 
    } 
} 
0

Dưới đây là một ví dụ làm thế nào bạn có thể làm điều đó mà không cần LINQ và không có từ điển và danh sách , chỉ cần hai vòng lồng nhau đơn giản:

public class MostFrequentNumber 
{ 
    public static void Main() 
    { 
     int[] numbers = Console.ReadLine().Split(' ').Select(int.Parse).ToArray(); 

     int counter = 0; 
     int longestOccurance = 0; 
     int mostFrequentNumber = 0; 

     for (int i = 0; i < numbers.Length; i++) 
     { 
      counter = 0; 

      for (int j = 0; j < numbers.Length; j++) 
      { 
       if (numbers[j] == numbers[i]) 
       { 
        counter++; 
       } 
      } 

      if (counter > longestOccurance) 
      { 
       longestOccurance = counter; 
       mostFrequentNumber = numbers[i]; 
      } 
     } 

     Console.WriteLine(mostFrequentNumber); 
     //Console.WriteLine($"occured {longestOccurance} times"); 
    } 
} 

Bạn nhận được giá trị của số xuất hiện thường xuyên nhất và (nhận xét) bạn cũng có thể nhận được số lần xuất hiện. Tôi biết tôi có một "sử dụng LINQ;", đó là chỉ để chuyển đổi chuỗi đầu vào ban đầu thành một mảng int và để dự phòng một vài dòng và một vòng lặp phân tích cú pháp. Thuật toán là tốt ngay cả khi không có nó, nếu bạn điền vào các mảng cách "dài" ...

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