Excel'deki kombinasyonların sayısını sayma


0

Aşağıdaki makro ile çalıştım, daha önce yayınlandım, ancak başka bir sütun ekleyemiyorum? Dört veri sütunum var ve veri kümesi içindeki herhangi bir sırada üç sayının kaç kez göründüğünü bilmek istiyorum. Hala öğreniyorum, bu yüzden herhangi bir yardımın takdir edilmesi gerekiyor.

Örneğin:

  1  16  13  43
  1  19  45  58
  1  69  58   3
 13  16  63   1
  6  34  33  59
  6  45  19  58
  6  43  48  50

Cevaplar

 13, 16,  1 = 2
 45, 58, 19 = 2

vb...

Option Explicit

Sub GetCombinations()
    Dim sheet1, sheet2 As Worksheet
    Set sheet1 = Worksheets(1)
    Set sheet2 = Worksheets(2)

    Dim sStartColumn As String
    Dim iTopRow As Long
    Dim sEndColumn As String
    Dim iBottomRow As Long

    sStartColumn = "A"
    iTopRow = 1
    sEndColumn = "E"
    iBottomRow = sheet1.UsedRange.Rows.Count

    Dim Rng As Range
    Dim sRange1 As String
    sRange1 = sStartColumn & CStr(iTopRow) & ":" & sEndColumn & CStr(iBottomRow)

    Set Rng = sheet1.Range(sRange1)
    Rng.Sort Key1:=Range("A2"), Order1:=xlAscending, _
         Key2:=Range("B2"), Order2:=xlAscending, _
         Orientation:=xlSortColumns, Header:=xlYes

    Dim i, j As Integer
    j = 2
    For i = 2 To iBottomRow
        If sheet1.Cells(i, 4) Then
            sheet2.Cells(j, 1) = sheet1.Cells(i, 1)
            sheet2.Cells(j, 2) = sheet1.Cells(i, 2)
            sheet2.Cells(j, 3) = sheet1.Cells(i, 5)
            j = j + 1
        End If
    Next i
End Sub

Yanıtlar:


0

Burada iki varsayımda bulunuyorum:

  1. Her sayı satır benzersizdir (yani aynı satırdaki bir sayıyı çoğaltmazsınız)
  2. Sayılar tanımlanmış bir aralık dahilinde (örneğin 1 ila MaxNum) ve bu MaxNum'un makul bir boyutta (ör. <96)

Her satır için sayıları bir bit dizesinde doğruluk değerleri olarak saklayabilirsiniz (örneğin, ilk satırınız için (1,16,13,43), 1, 16, 13 ve 43 bitleri "1" olarak ayarlanmış ve kalanlar bit dizisindeki öğeler "0" olarak ayarlanacaktır. Her satır için bit dizesi tam olarak aynı uzunluktadır (bu nedenle bilinen bir MaxNum varsayımı). Varsayım (1) yanlışlanırsa, burada tarif ettiğim çözüm olmaz iş (en azından bazı büyük değişiklikler olmadan).

Daha sonra bir karşılaştırma yapmak için her dizgiyi yineleyebilir ve bu karşılaştırmayı bir şekilde saklayabilirsiniz.

For I = 1 to numString - 1
  for J = I+1 to numString
    ' Do something
  Next J
Next I

'do somethingBölüm bitsel operatörleri kullanıyor (basitçe andve sayısını saymak istediğiniz trueEğer üç veya daha fazla olsun olmadığını görmek için sonuçları). Sayılarınız küçükse (yani <32) yerleşik işlevler kullanabilirsiniz, ancak örneklerinizdeki sayılar çok daha büyüktür. Bu, iki seçenek açar - genel bit dizesini birkaç küçük (örneğin 32 bit) değere bölün ve bunlar üzerinde yineleyin veya bir andsonuç için kendi basit işlevinizi oluşturun (bu, gereksinim duyduğunuz tek Boolean işlevidir.

Aklımda, sonuç almanın en basit yolu, geçerli bit dizeleri koleksiyonu oluşturmaktır (yani her satır için, üç true/'1'bit içeren bir dizi dizi (*) veya bunların tümünü içeren tek bir dize alırsınız '0'), bunları sipariş edin dizge benzeri dizeleri gruplayabilir ve ardından her dizideki üç sayı için kodu çözülmüş bir başlık ile birlikte her gruptaki dizelerin sayısını sayabilirsiniz.

(*) (ör.) Bir satırda eşleşen 4 sayı varsa, bu dört sayıdan üç sayı elde etmenin birden fazla yolu vardır. Bu, bazı satırlar için birden fazla sonuç elde edeceğiniz anlamına gelir.

Yukarıda tarif ettiğim yöntemin avantajı, şimdi ölçeklenebilir olmasıdır. Üç sütununuz, dört sütununuz, beş sütununuz vb. Olabilir. Ayrıca, üç eşleşme numarası, dört eşleme numarası vb. Almak için geçerlilik kuralını kolayca değiştirebilirsiniz.

Burada hiçbir gerçek kodlama örneği sunmadım. İçinde bir dizi ilginç kavram olsa da ('bit'leri saklamak için gerçekten bir dize kullanıyorsanız dizgi manipülasyonu, Boolean işlemleri, sıralama ve gruplama), bunlardan her biri web'deki uygun öğreticilerle temsil edilir. Ek olarak, bu kavramların ayrı ayrı Stack Exchange içerisinde ele alındığından eminim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.