Proste dziedziczenie

0

Mam do zrealizowania bibliotekę klasyfikatora knn, temat teoretycznie dość prosty, jednak w wymaganiach projektu mam:

Klasyfikacja danych reprezentowanych przez wektory liczbowe oraz innych obiektów nie będących wektorami (np. łańcuchy znakowe) - proszę to zrealizować w dwóch klasach potomnych

Teraz chciałbym aby ktoś pomógł mi odnaleźć sens używania tutaj dziedziczenia. Nie widzę żadnych metod, które można by uznać za wspólne dla obu klas. Pobieranie danych liczbowych a stringów się różni, na siłę można zrobić to w klasie bazowej używając szablonów. Tak samo przechowywanie danych, dla dowolnej przestrzeni muszę użyć vectora a dla napisów wystarczyłby string. Mam wrażenie, że to jest zupełnie bez sensu.

0

Mam wrażenie, że to jest zupełnie bez sensu.
Ale masz zrobić i basta ;-)

Pobieranie danych liczbowych a stringów się różni
To akurat może być przykładem użycia metody wirtualnej...

0

Jakoś tam wcisnąłem to dziedziczenie, ale teraz mam inny problem. Program się wykłada.
knn.h

 #ifndef knn_h
#define knn_h
#include <list>
using namespace std;

class knn_classifier
{
protected:
    struct near_item
    {
        double distance;
        string label;
    };
    list<string> trSet;
    list<string> unSet;
    list<string> clSet;
    list <near_item> KNN;
    int k;
public:
    knn_classifier();
    void show()
    {
        cout<<trSet.front()<<endl;
        cout<<unSet.front()<<endl;
        //cout<<clSet.front()<<endl;
    }
    virtual ~knn_classifier();
    void push_trset(string);
    void push_unset(string);
    void get_k(int);
    void classify();
    string label(string);
    virtual double count_dist(string, string)=0;
    static bool compare(const near_item &lhs, const near_item &rhs)
    {
        return lhs.distance < rhs.distance;
    }
};

class knn_string : public knn_classifier
{
private:
    struct item
    {
        string label;
        string attributes;
    };
public:
    knn_string(){};
    item split(string);
    double count_dist(string, string);
};

class knn_vector : public knn_classifier
{
private:
    struct item
    {
        string label;
        list<double> attributes;
    };
public:
    knn_vector(){};
    item split(string);
    double count_dist(string, string);
};

#endif
void knn_classifier::classify()
{
    struct label_c
    {
        string label;
        int counter;
        label_c() {counter = 0;}
    };
    list<string> tempString;
    list<string> counting;
    string tempU;
    string tempT;
    string done;
    tempString=trSet;
    near_item NEAR;
    while(unSet.empty()!=1)
    {
        label_c *CL = new label_c[k]();
        tempU = unSet.back();
        while(tempString.empty()!=1)
        {
            tempT = tempString.back();
            tempString.pop_back();
            NEAR.distance = count_dist(tempU, tempT);
            NEAR.label = label(tempT);
            KNN.push_back(NEAR);
        }
        KNN.sort(compare);
        for(int i=0; i<k;i++)
        {
            for(int j=0;j<k;j++)
            {
                if(KNN.front().label==CL[j].label)
                    CL[j].counter++;
            }
            CL[i].label=KNN.front().label;
            CL[i].counter=1;
            KNN.pop_front();
        }
        for (unsigned int i=0;i<KNN.size();i++)
        KNN.pop_back();
        int a=0;
        int j=CL[a].counter;
        for(a=1;a<k;a++)
        {
            if(j<CL[a].counter)
                j=CL[a].counter;
        }
        done=CL[a].label;
        done.append(tempU);
        clSet.push_back(done);
        a=0;
        unSet.pop_back();
        delete [] CL;
    }
}
 
 knn_string::item knn_string::split(string to_sp)
{
    string temp;
    item b;
    unsigned int j = 0;
    if(to_sp.at(0)==';')
        b.label = "unclassified";
    for(int i=0, j=0; to_sp.at(j)!=';';i++, j++)
    {
        b.label.append(1,to_sp.at(j));
    }
    j++;
    int i=0;
    while(j<to_sp.size())
    {
        b.attributes.append(1,to_sp.at(j));
        j++;
        i++;
    }
    j=0;
    i=0;
    return b;
}

double knn_string::count_dist(string A, string B)
{
    double dist=0;
    double counter=1;
    item a;
    item b;
    a=split(A);
    b=split(B);
    for(unsigned int i=0;i<a.attributes.size();i++)
    {
        for(unsigned int k=0;k<b.attributes.size();k++)
        {
            if(a.attributes.at(i)==b.attributes.at(k))
                counter++;
        }
    }
    dist=1/counter;
    return dist;
}

no i teraz robię test:

 int main()
{
    knn_string nowy;
    nowy.push_trset("a;pierwszy");
    nowy.push_trset("b;drugi");
    nowy.push_unset(";nowy");
    nowy.classify();
    nowy.show();
    return 0;
}

debuger zatrzymuje się na nowy.classify() i oto co wyrzuca:
Program received signal SIGSEGV, Segmentation fault.
In std::string::assign(std::string const&) () ()
#2 0x0040308d in main () at D:\polibuda\semestr 2\programowanie obiektowe\KNN\klasyfikator\main.cpp:12
D:\polibuda\semestr 2\programowanie obiektowe\KNN\klasyfikator\main.cpp:12:202:beg:0x40308d
At D:\polibuda\semestr 2\programowanie obiektowe\KNN\klasyfikator\main.cpp:12
#2 0x0040308d in main () at D:\polibuda\semestr 2\programowanie obiektowe\KNN\klasyfikator\main.cpp:12
D:\polibuda\semestr 2\programowanie obiektowe\KNN\klasyfikator\main.cpp:12:202:beg:0x40308d

Ktoś coś widzi?

1 użytkowników online, w tym zalogowanych: 0, gości: 1