2011-03-25 41 views
7

C++ temellerini öğrenmek için temel bir program yapmaya çalışıyorum, 0'dan 100'e 100 rastgele sayı üretiyorum ve bunları bir vektörde saklıyorum, sonra görüntülüyorum Vektörün toplamı, ortalaması, medyanı, modu, yüksek ve düşük. Takılı kaldığım mod haricinde her şeyim var. Şimdiye kadar sahip olduğum kod.C++ IN Ints Vektörünün Mod Bulma

int modeFunction() 
    { 
     numMode = 0; 
     count = 0; 
     for (int n = 0; n < 100; n++) 
     { 
      for (int y = 0; y < 100; y++) 
      { 
       if (numVector.at(y) == numVector.at(n)) 
       { 
        numMode = numVector.at(y); 
        count++; 
       } 
      } 

     } 
     return numMode; 
    } 

Bundan sonra takılıyorum çünkü aklımda çalışması gerekiyor ama değil. Bu sadece son sayıyı, genellikle 100 koyar. Herhangi bir yardım çok takdir edilecektir.

+1

gibi bir şey 'myVector' bir' std ise :: vector '(bunun en az gibi görünüyor), bir dizi gibi indeks o yapabilirsiniz:' myVector [y] 've' myVector [n] 'irade "myVector.at" sürümü ile aynı verim, ancak daha güzel imho görünüyor. :) – Xeo

+2

@Xeo: "at" dizininin menzil dışı olduğu zaman davranışını tanımladığı fark. Muhtemelen operatör [] 'bir mikro-optimizasyonudur, ama aynı zamanda bir stil farkı da vardır. –

+0

@Steve: Ah, bu bahşiş için teşekkürler.:) Henüz 'at 'ile rahatsız etmedi, ama normal bir dizi de aralık dışı erişim için tanımlanmamış bir davranışı vardır, ancak ihtiyaç duyduğunuzda kesinlikle tanımlanmış olması kesinlikle güzel. :) – Xeo

cevap

7

, bir histogram ile verimli modu bulabilirsiniz: öğelerin sayısı kadar küçük olursa

std::vector<int> histogram(101,0); 
for(int i=0; i<100; ++i) 
    ++histogram[ numVector[i] ]; 
return std::max_element(histogram.begin(), histogram.end()) - histogram.begin(); 
5

Mod, en sık gerçekleşen sayı olduğundan, numMode numarasını değiştirmemelisiniz; aksi takdirde, yeni numara sayısı, numMode'un sayımından büyük değilse.

DÜZENLEME: Netleştirmek için, geçerli öğe ve mod olduğunu düşündüğünüz geçerli sayı için ayrı bir sayı tutmanız gerekir. İdeal olarak, ilk öğeye newMode ayarı iyi bir yaklaşımdır. Ek olarak, mod gerekli değildir (yani "1 1 2 2"). Bunu önemsersen, bunu akılda tutmak isteyebilirsin.

newMode = element[0] 
modeCount = # of occurrence of newMode 

for (i-th element from [1 to end]) { 
    tmpCount = # of occurrence of element[i] 
    if tmpCount > modeCount { 
    newMode = element[i] 
    modeCount = tmpCount 
    } 
} 
0

Algoritmanız yanlış - dizideki son sayı çıktısı çünkü yapabildiği tek şey bu. y dizinindeki sayı her defasında n dizinindeki sayıyla eşleştiğinde, önceki n için sonuçların üzerine yazabilirsiniz. Aynı döngü koşulları kullandığınızdan, y ve n olası her n değeri için iç içe döngü içinde en az bir noktada hep aynıdır - ve her zaman numModenumVector.at(99) olmak bitireceğiz.

(veya n endeksi count büyük ile sona erdi hangi azından) Eğer n döngünün sonunda bilmek, böylece hangi giriş yol boyunca her n endeksi için sayımı kaydetmek için algoritma değiştirmek gerekir en çok meydana geldi.

1

Alternatif çözümler. Not: denenmemiş.

int mode1(const std::vector<int>& values) 
{ 
    int old_mode = 0; 
    int old_count = 0; 
    for(size_t n=0; n < values.size(); ++n) 
    { 
     int mode = values[n]; 
     int count = std::count(values.begin()+n+1, values.end(), mode); 

     if(count > old_count) 
     { 
      old_mode = mode; 
      old_count = count; 
     } 
    } 
    return old_mode; 
} 

int mode2(const std::vector<int>& values) 
{ 
    return std::max_element(values.begin(), values.end(), [](int value) 
    { 
     return std::count(values.begin(), values.end(), value); 
    }); 
} 
0

Mod, en yüksek sıklığa sahip bir sayıdır. mantık olmalıdır - tüm değerler 0 ile 100 arasında olduğundan

//Start of function 

int mode = 0, globalCount = 0 ; 
// Start of outer for loop 
for i = 0 to length - 1  
    int localCount = 0 

    // Start of inner for loop 
    for j = 0 to length - 1  
    if vec[i] == vec[j]  
    ++localCount  
// End of Inner for loop 

if (localCount > globalCount) 
    globalCount = localCount 
    mode = vec[i] 
// End of outer for loop 

if globalCount > 1 // This should be checked whether vec has repetitions at all 
    return mode 
else 
    return 0 

// End of function 
+0

@Cistoran'a geçerek sınır kontrolünü istiyorum. Mantık, verimliliği daha iyi artırabilir ama bu ne algoritma düşünce sürecinize göre olmalıdır. – Mahesh

0

bmcnett yaklaşımı inşaat büyük . Çok sayıda öğeye sahipseniz ancak tüm öğe değeri küçük bir aralıkta ise harita/hashmap iyi çalışır.

typedef std::pair<int, int> mode_pair; 

struct mode_predicate 
{ 
    bool operator()(mode_pair const& lhs, mode_pair const& rhs) 
    { 
    return lhs.second < rhs.second; 
    } 
}; 

int modeFunction() 
{ 
    std::map<int, int> mode_map; 
    for (int n = 0; n < 100; n++) 
    mode_map[numVector[n]]++; 
    mode_predicate mp; 
    return std::max_element(mode_map.begin(), mode_map.end(), mp)->first; 
}