Accelerated C++ kitabından not hesabı

Başlatan 0u2h4n, 13 Ağustos 2012 - 19:52:17

« önceki - sonraki »

0 Üyeler ve 4 Ziyaretçi konuyu incelemekte.

0u2h4n


#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::setprecision;
using std::string;
using std::streamsize;
using std::sort;
using std::vector;

int main()
{
// ask for and read the student's name
cout << "Please enter your first name: ";
string name;
cin >> name;
cout << "Hello, " << name << "!" << endl;

// ask for and read the midterm and final grades
cout << "Please enter your midterm and final exam grades: ";
double midterm, final;
cin >> midterm >> final;

// ask for and read the homework grades
cout << "Enter all your homework grades, followed by end-of-file: ";

vector<double> homework;
double x;
// invariant: homework contains all the homework grades read so far
while (cin >> x)
homework.push_back(x);

// check that the student entered some homework grades
typedef vector<double>::size_type vec_sz;
vec_sz size = homework.size();

if (size == 0)
{
cout << endl << "You must enter your grades.Please try again." << endl;
return 1;
}

// sort the grades
sort(homework.begin(), homework.end());

// compute the median homework grade
vec_sz mid = size/2;
double median;
median = size % 2 == 0 ? (homework[mid] + homework[mid-1]) / 2 : homework[mid];

// compute and write the final grade
streamsize prec = cout.precision();
cout << "Your final grade is " << setprecision(3) <<
0.2 * midterm + 0.4 * final + 0.4 * median << setprecision(prec) << endl;

return 0;
}


Yukarıdaki kod başlıktan da anlaşılacağı üzere Accelerated C++ kitabından alıntı.

typedef vector<double>::size_type vec_sz;
vec_sz size = homework.size();

vec_sz mid = size/2;

Bu kodun içindeki typedef vector<double>::size_type vec_sz kullanımının mantığını anlayamadım. Bunun yerine "int" tipinde size ve mid tanımlamakta aynı işi görüyor.

Erdem

Burada sanırım şunu vurgulamak istemişler. Eleman sayısı her zaman >= 0'dır. Ayrıca vector<tur>::size_type bir unsigned int  dir. Yani işaretsiz tamsayıdır.
Eğer Arch Linux tabanlı bir dağıtıma geçmek isterseniz Arcolinux D sürümünü buradan indirebilirsiniz.

Elektronik

sem

Kodları inceleme fırsayım olmadı ama sadece bu vurgu içinse bir unsigned anahtarı daha okunabilir yapabilirmiş kodu.
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

Erdem

Bu arada nasıl Accelerated C++ ile gelen alıştırmaları da yapıyormusun. Daha en başından C++'nin Standart Şablon Kütüphanesi ile gelen olanakları kullanıyor değil mi  :D

Örneğin 3. bölümdeki 3. alıştırmada girişten gelen her farklı kelimenin kaç kere girildiğini sayan bir program yazmamızı istiyor.

Her ne kadar daha okunaklı bir çözüm yazılabilse de C++'nin karmaşıklığını gösteren şöyle bir çözüm de düşünülebilir   ;)


#include <iostream>
#include <map>
#include <string>
#include <iterator>

using namespace std;

typedef map <string, unsigned int> Kelimeler;
typedef pair <string, unsigned int> Sayac;

class KelimeArttirici : public iterator <output_iterator_tag,
                                         void, void, void, void>
{
public:

    explicit KelimeArttirici (Kelimeler & kelimeler)
        : kelimeler_ (kelimeler)
    {}

    KelimeArttirici & operator= (const string & kelime)
    {
        ++kelimeler_ [kelime];
        return *this;
    }

    KelimeArttirici & operator* ()     { return *this; }
    KelimeArttirici & operator++ ()    { return *this; }
    KelimeArttirici & operator++ (int) { return *this; }

private:
    Kelimeler & kelimeler_;
};

namespace std
{
    ostream & operator<< (ostream & cikis, const Sayac & sayac)
    {
        return cikis << sayac.first << '\t' << sayac.second;
    }
}

int main ()
{
    Kelimeler kelimeler;
    copy (istream_iterator<string> (cin),
          istream_iterator<string> (),
          KelimeArttirici (kelimeler));

    copy (kelimeler.begin (), kelimeler.end (),
          ostream_iterator<Sayac> (cout, "\n"));
    return 0;
}


Bu arada eğer sorularına daha değişik, bazen de karmaşık!  :D yanıtlar almak istiyorsan ceviz c++ forumlarında sormanı tavsiye ederim. 

Ben de o forumdaki arkadaşlara göre daha başlangıç seviyesinde C++ biliyorum diyebilirim  :)
Eğer Arch Linux tabanlı bir dağıtıma geçmek isterseniz Arcolinux D sürümünü buradan indirebilirsiniz.

Elektronik

0u2h4n

#4
Alıntı yapılan: Erdem - 14 Ağustos 2012 - 00:24:56
Burada sanırım şunu vurgulamak istemişler. Eleman sayısı her zaman >= 0'dır. Ayrıca vector<tur>::size_type bir unsigned int  dir. Yani işaretsiz tamsayıdır.

sem0900'ın dediği gibi vector<tur>::size_type kullanımı gereksiz değil mi? unsigned int kulllansak olmaz mıydı?


Alıntı yapılan: Erdem - 14 Ağustos 2012 - 01:10:04
Bu arada nasıl Accelerated C++ ile gelen alıştırmaları da yapıyormusun. Daha en başından C++'nin Standart Şablon Kütüphanesi ile gelen olanakları kullanıyor değil mi  :D

Yapıyorum, gayet güzel uygulamalar var :D.


Alıntı yapılan: Erdem - 14 Ağustos 2012 - 01:10:04
Örneğin 3. bölümdeki 3. alıştırmada girişten gelen her farklı kelimenin kaç kere girildiğini sayan bir program yazmamızı istiyor.

3.3'ü yapmadım henüz. 3.2'de şöyle bi kod yazdım ama Segmentation fault (core dumped) hatası veriyor.

Soru:Write a program to compute and print the quartiles (that is, the quarter of the numbers with the largest values, the next highest quarter, and so on) of a set of integers.

Yazdığım kod:
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
cout << "Please enter values:" << endl;

vector<double> values;
double x;

while (cin >> x)
values.push_back(x);

sort(values.end(), values.begin());

for (unsigned int i = 0; i < values.size(); ++i)
cout << values[i]/4;
}



Alıntı yapılan: Erdem - 14 Ağustos 2012 - 01:10:04

Bu arada eğer sorularına daha değişik, bazen de karmaşık!  :D yanıtlar almak istiyorsan ceviz c++ forumlarında sormanı tavsiye ederim. 

Foruma üye oldum ama henüz konu açamıyorum :D


Mesaj tekrarı yüzünden mesajınız birleştirildi. Bu mesajın gönderim tarihi : 14 Ağustos 2012 - 16:56:08

"sort" fonksiyonunun kullanımını öğrendikten sonra sorunu aşağıdaki gibi düzelttim.
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
cout << "Please enter values:" << endl;

vector<double> values;
double x;

while (cin >> x)
values.push_back(x);

sort(values.begin(), values.end());

for (int i = values.size(); i > 0; --i)
cout << values[i-1]/4 << endl;
}



Mesaj tekrarı yüzünden mesajınız birleştirildi. Bu mesajın gönderim tarihi : 14 Ağustos 2012 - 17:31:49

Sırasıyla 3.3 ve 3.4 çözümlerim:


3.3:Write a program to count how many times each distinct word appears in its input.


#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
cout << "Please enter words: " << endl;

vector<string> words;
string x;

while (cin >> x)
words.push_back(x);

for (unsigned int i=0; i < words.size(); ++i)
{
int n=1;

for (unsigned int j=i+1; j < words.size(); ++j)
{
if (words[i]==words[j])
{
words.erase(words.begin()+j);
--j;
cout << words.size();
++n;
}
}

cout << words[i] << "\t" << n << endl;
}
}



3.4:Write a program to report the length of the longest and shortest string in its
input.

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
cout << "Please enter words: " << endl;

vector<string> words;
vector<int> lengths;
string x;

while (cin >> x)
{
words.push_back(x);
lengths.push_back(x.length());
}

int a;
string b;
for (int i=0; i < words.size(); ++i)
{
for (int j=i+1; j < words.size(); ++j)
{
if (lengths[j]>lengths[i])
{
a = lengths[i];
lengths[i] = lengths[j];
lengths[j] = a;

b = words[i];
words[i] = words[j];
words[j] = b;
}

}
}

cout << words[0] << '\t' << lengths[0] << endl;
cout << words[words.size()-1] << '\t' << lengths[words.size()-1] << endl;

}

Erdem

Alıntı yapılan: 0u2h4n - 14 Ağustos 2012 - 14:52:17
sem0900'ın dediği gibi vector<tur>::size_type kullanımı gereksiz değil mi? unsigned int kulllansak olmaz mıydı?

Olurdu ama özellikle her vektörün vector<tur>::size_type isimli işaretsiz bir tamsayı üyeye sahip olduğunu göstermek istemişler.

Alıntı Yap3.3'ü yapmadım henüz. 3.2'de şöyle bi kod yazdım ama Segmentation fault (core dumped) hatası veriyor.

Soru:Write a program to compute and print the quartiles (that is, the quarter of the numbers with the largest values, the next highest quarter, and so on) of a set of integers.

Bu çeyreklikleri hesaplayan programı ben şöyle yazmışım:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using std::cin;
using std::cout;        using std::string;
using std::endl;
using std::vector;      using std::sort;


int main ()
{

    cout << "Çeyrekliği hesaplanacak sayıları giriniz. Girişi\n"
        "sonlandırmak için Linux'ta CTRL-D tuşuna basınız: ";


    double girilen;

    vector<double> sayilar;

    while (cin >> girilen)
    {
        sayilar.push_back (girilen);
    }

    typedef vector<double>::size_type vector_buyukluk;

    vector_buyukluk elemansayisi = sayilar.size ();   

    if (elemansayisi == 0)
    {
        cout << endl << "Notlarınızı girmelisiniz. "
            "Lütfen tekrar deneyin" << endl;
        return 1;
    }

   
    // elemanları sıraya sok
    sort (sayilar.begin (), sayilar.end ());
   
    vector_buyukluk ortadaki = elemansayisi / 2;

    double medyan, altceyreklik, ustceyreklik = 0.00;
   

    medyan = elemansayisi % 2 == 0 ?
        (sayilar[ortadaki] + sayilar [ortadaki - 1]) / 2
        : sayilar [ortadaki];
   
    vector_buyukluk ortadaki2 = (ortadaki + 1) / 2;

    altceyreklik = (ortadaki + 1) % 2 == 0 ?
        (sayilar[ortadaki2] + sayilar [ortadaki2 - 1]) / 2
        : sayilar [ortadaki2];

   
    ustceyreklik = (ortadaki + 1) % 2 == 0 ?
        (sayilar[ortadaki + ortadaki2] +
         sayilar [ortadaki + ortadaki2 - 1]) / 2 :
        sayilar [ortadaki + ortadaki2];
    cout << "Q1 = " << medyan << " Q2 = " << altceyreklik
         << " Q3 = " << ustceyreklik << '\n';
   
    return 0;
   
}


Alıntı YapSırasıyla 3.3 ve 3.4 çözümlerim:
3.3:Write a program to count how many times each distinct word appears in its input.

Bu olmuş. Türkçesini yazarsak girişten gelen her farklı kelimenin kaç kere girildiğini sayan bir program yazmamızı istiyor.

Benim yazdığım daha okunabilir çözüm şu şekildeydi:

#include <iostream>
#include <map>
#include <string>

using std::cin;         using std::cout;
using std::map;         using std::string;

int main ()
{
    string kelime;
    typedef map <string, unsigned int> Kelimeler;
    Kelimeler::const_iterator konum;
    Kelimeler kelimeler;

    while (cin >> kelime)
    {
        ++kelimeler[kelime];
    }

    for (konum = kelimeler.begin (); konum != kelimeler.end ();
         ++konum)
    {
        cout << konum->first << '\t'
             << konum->second << '\n';
    }
    return 0;

}

   
3.4:Write a program to report the length of the longest and shortest string in its
input.


Bunun da Türkçesi girişten gelen en uzun ve en kısa kelimeyi yazan programı bizden yazmamızı istiyor. Benim çözümüm de şu şekildeydi:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using std::endl;    using std::vector;
using std::string;  using std::cin;
using std::cout;

bool uzunlugagore (const string & birinci, const string & ikinci)
{
    return birinci.size () < ikinci.size ();
}

int main ()
{
    string kelime;

    vector<string> kelimeler;

    while (cin >> kelime)
    {
        kelimeler.push_back (kelime);
    }

    cout << "En uzun kelime: " << *max_element(kelimeler.begin (),
                                               kelimeler.end (),
                                               uzunlugagore) << '\n';
    cout << "En kısa kelime: " << *min_element(kelimeler.begin (),
                                               kelimeler.end (),
                                               uzunlugagore) << '\n';
   
}


Tabi ben bu örnekleri çözerken başka kaynaklardan da faydalandığım için henüz kitapta anlatılmayan bazı olanakları kullandığımın farkındayım  ;)
Eğer Arch Linux tabanlı bir dağıtıma geçmek isterseniz Arcolinux D sürümünü buradan indirebilirsiniz.

Elektronik

0u2h4n

Benim bu 3.kısımda takıldığım bir yer var. Ödev notlarını girerken normalde hepsini toplayıp ödev sayısına bölerek ortalamayı hesaplayabiliyoruz. Fakat sonradan medyan ile hesaplamış. Bunlar aynı şeyler değil ki, not ortalaması dediğimiz ilk yöntemle hesaplanmalı bence.

Mesela ödev notlarını şöyle olsun : 40 - 80 - 45

1.yöntem ile : (40+45+80) / 3 = 55

2. yöntem ile : 40 - 45(medyan) - 80 = 45

Bana 2.yöntem saçma geldi :D

Erdem

Orada yazarların amacı daha sonra  topluluklarda sıralama, eleman çıkarma gibi konular sık sık karşımıza çıkacağı için bu hesabın nasıl yapıldığını anlatmış olabilirler.

Medyan ya da Türkçesiyle ortanca değer derken bir nevi istatistiksel ortalama alıyor sanırım.

Örneğin 1, 5, 2, 8, 7 sayılarımız olsun. Bunları sıraladığımız zaman 1, 2, 5, 7, 8 elde ediyoruz. Bunların ortanca değeri sayı adedi tek olduğu için 5 oluyor.

Çift sayılara örnek olarak da 1, 6, 2, 8, 7, 2 olsun. Bunları sıralarsak 1, 2, 2, 6, 7, 8 elde ediyoruz. Bu durumda da ortada bulunan iki değerin yani 2 ve 6 sayılarının ortalaması 4 ortanca değer olmuş oluyor.

Kitaptaki uygulama da aynen bunu mu hesaplıyor deneyebilirsin. Şimdi kitap uzakta olduğu için elim ermedi  8)
Eğer Arch Linux tabanlı bir dağıtıma geçmek isterseniz Arcolinux D sürümünü buradan indirebilirsiniz.

Elektronik

0u2h4n

Alıntı yapılan: Erdem - 15 Ağustos 2012 - 04:02:37
Kitaptaki uygulama da aynen bunu mu hesaplıyor deneyebilirsin. Şimdi kitap uzakta olduğu için elim ermedi  8)

Kitap dediğin gibi hesaplıyor da bana saçma geldi sadece biz notlarımızı öyle hesaplamazdık :D