Working with Batches of Data

Kategori: C++ , 11 Kasım 2019 , JanFranco


Bu yazımda verileri tutmayı göreceğiz. Bir örnek ile başlayalım, bir öğrencinin notlarını alalım ve dönem sonu notunu hesaplayalım. %40 final notu , %20 midterm notu, kalan yüzde 40 da ödevlerin ortalaması olsun:


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

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

int main()
{
    cout << "Enter your name: ";

    string name;
    cin >> name;

    cout << "Hello, " + name + "!";
    cout << endl;

    cout << "Please enter your midterm and final grades: ";
    double midterm, final;
    cin >> midterm, final;

    cout << "Please enter your homework grades: ";

    int count;
    double sum, x;

    while (cin >> x) {
        ++count;
        sum += x;
    }

    streamsize prec = cout.precision();
    cout << "Your final grade is " << setprecision(3) << 0.2 * midterm + 0.4 * final + 0.4 * sum / count
        << setprecision(prec) << endl;

    return 0;
}
Kütüphaneri açıklayarak başlayalım, önceki yazılarımda da iostream ve string kütüphanelerini kullanmıştık. Burada yeni iki kütüphane kullanacağız. Bunlar iomanip ve ios. iomanip kütüphanesini dahil etmemizin sebebi, barındırdığı setprecision fonksiyonu. Bu fonksiyon ile konsola bir değer bastırırken kaç basamağının yazılacağını ayarlayabiliriz. ios kütüphanesini de dahil etmemizin sebebi streamsize tipini kullanacak olmamız.

name adında bir string tanımladık ve kullanıcıdan isim alıp, karşılama mesajı hazırladık. Daha sonra double tipinde midterm ve final değişkenleri oluşturup, bu değerleri kullanıcıdan aldık. double tipini ilk kez görüyoruz. Rasyonel sayılar için kullanılan bir veri tipidir. Rasyonel sayılar için kullanabileceğimiz float veri tipi de mevcuttur fakat double veri tipi, float veri tipinden daha güvenlidir ve daha çok basamağı tutabilir.

Daha sonra bir while döngüsü açtık ve koşul olarak kullanıcının x değişkenine değer girmesini atadık. Kullanıcı konsola her veri girdiğinde koşul sağlanacak aynı zamanda x değişkenine de değer atanmış olacak. Kullanıcı double tipi dışında (bir karakter, string vs.) bir veri girdiği zaman koşul sağlanamayacak ve while döngüsü sona erecek. Yeni satıra geçtiğimizde veya dosyanın sonuna geldiğimizde de döngü sonlanır.

Döngünün her adımında count değişkenini bir artırıyoruz ve sum değişkenine x değerini ekliyoruz. Böylelikle sum / count işlemi ile ortalamayı bulabiliriz. Daha sonra precision() methodu ile konsolun, bir değer için kaç basamak basabileceği bilgisini, tipi streamsize olan prec değişkenine atıyoruz. Orijinal değeri saklıyoruz çünkü problemi çözdüğümüzde tekrar konsolu eski haline çevireceğiz.

Son olarak son notu konsola yazdıyoruz. Yazdırırken setprecision() fonksiyonu ile konsolun bir değer için kaç basamak yazacağını 3 olarak belirliyoruz. Notu yazdıyoruz ve aynı fonksiyonu kullanarak bu sefer argüman olarak önceden değerini atadığımız prec değişkenini kullanıyoruz. Böylelikle konsolun da ayarını eski haline çeviriyoruz. Kullanıcıdan notlarını aldık ve notlarını hesapladık. Burada ödev notlarının ortalamasını aldık. Bu sefer ödevlerin medyanını (ortanca değer) alalım. Bunu yapabilmek için kullanıcıdan aldığımız notları saklamamız gerekli. Kullanıcıdan aldığımız verileri C++ vector kütüphanesinde bulunan vector veri yapılarında saklayabiliriz:


vector<double> homework;
Bir vektör tanımlarken < > karakterleri arasında saklayacağımız değerlerin tipini belirtmemiz gerekir. Bu bilgiden de anlıyoruz ki vektör, verileri tutan bir toplayıcıdır. Artık ortalama hesabı yapmayacağımız için count ve sum değişkenlerini silebiliriz. While döngüsünü yeniden düzenleyelim:


while (cin >> x) {
    homework.push_back(x);
}
vector sınıfının push_back() methodu sayesinde vektörlere bu şekilde veri ekleyebiliriz. Ortalama değil de medyan alacağımız için vektörün boyutunun 0 olmaması gerekli. Bunun kontrolünü yapalım. size() methodu ile vektörün boyutunu alabiliriz. Bu boyut bilgisini sık kullanacağız bu nedenle bu bilgiyi bir değişkene atayalım:


typedef vector<double>::size_type vec_sz;
vec_sz size = homework.size();
typedef ifadesi ile ifadeleri başka bir isimle çağırabiliriz. Bu örnekte her vec_sz yazdığımızda aslında vector::size_type yazmış olacağız. vector sınıfının tanımladığı size_type veri tipini kullanarak bir size adında bir değişken oluşturalım ve değerini homework.size() olarak atayalım. Şimdi kontrol yapalım:


if (size == 0) {
    cout << endl << "You must enter your grades, please try again." << endl;
    return 1;
}
Medyan hesabı için vektörün sıralanmış olması gerekli. Vektörü kolayca sıralayabilmek için sort() fonksiyonunu kullanabiliriz:


sort(homework.begin(), homework.end());
sort() fonksiyonu ile vektörü sıralayabileceğimizi bilmemiz şimdilik yeterli, bu fonksiyonu daha sonraki yazılarımda detaylıca açıklayacağım. Sıralanmış vektörün ortasındaki sayıyı alalım. Bunun için size değerini ikiye bölelim. Eğer boyut çift sayı ise ortadaki sayıyı alamayız. Ortanca sayının bir fazlasını ve bir eksiğini toplayıp ikiye bölmeliyiz. Eğer boyut tek sayı ise direk ortadaki sayıyı alabiliriz:


vec_sz mid = size / 2;
double median;
median = size % 2 == 0 ? (homework[mid] + homework[mid-1]) / 2 : homework[mid];
Programımızın son halini görelim:


#include <iostream>
#include <string>
#include <iomanip>  // setprecision, how many digits our output contains
#include <ios>      // streamsize, input / output library represents sizes
#include <vector>   // vector, collections of data
#include <algorithm>    // sort, sorting vector

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

int main()
{
    cout << "Enter your name: ";

    string name;
    cin >> name;

    cout << "Hello, " + name + "!";
    cout << endl;

    cout << "Please enter your midterm and final grades: ";
    double midterm, final;
    cin >> midterm, final;

    cout << "Please enter your homework grades: ";

    double x;
    vector<double> homework;

    while (cin >> x) {
        homework.push_back(x);
    }

    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(homework.begin(), homework.end());

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

    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;
}


Sonraki Yazı: Organizing Program and Data
Yorumlar

Henüz bir yorum bulunmuyor.