NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Problém při využití list.sort()

V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Oldřich Beneš:13.12.2016 20:57

Zdravím, vyskytl se mi problém, mám napsaný kód, který se mi zdál funkční, ale dnes při kontrole mi bylo řečeno, že nefunguje správně, nevrací stejný počet jmen a mám prý někde problém se sortem... Čučím na to už 5 hodin a na nic jsem nepřišel. Nekoukl by mi na to někdo prosím ?

#include "stdafx.h"
#include <iostream>
#include <thread>
#include <ios>
#include <string.h>
#include <string>
#include <list>
#include <windows.h>




using namespace std;

//převzato z http://www.cplusplus.com/forum/beginner/12089/
bool compareNoCase(string first, string second)
{
        unsigned int i = 0;
        while ((i < first.length()) && (i < second.length()))
        {
                //v if a else if pouze porovnává jednotlivé znaky slov, když je jedno z nich menší/větší vrátí true/false, ukončí cyklus....
                //když jsou písmena rovna, zvýším si index pro pohyb v "poli" a pokračuju dál v cyklu
                if (tolower(first[i]) < tolower(second[i])) return true;
                else if (tolower(first[i]) > tolower(second[i])) return false;
                i++;
        }
        //v případě, že budou stejná písmena vrátí kratší slovo, v případě že je první kratší/true
        if (first.length() < second.length()) return true;
        else return false;
}




//metoda pro samotné třídění, jako parametr bere znak, jak třídit a samotný list
void sort(const char sign, list<string> &lst) {
        //ověření, zda je znak v nebo s, provedu sort
        if (sign == 'v' || sign == 's') {
                lst.sort(compareNoCase);
                //když chceme třídit sestupně převrátím předchozí sort
                if (sign == 's') lst.reverse();
        }

}


//metoda pro slívání dvou listů(2první arg), následně znak třídění, cestu k výstupnímu souboru
void sliti(list<string> &l1, list<string> &l2, const char sign, const char * path) {
        FILE * output;
        output = fopen(path,"w+");

        //porovnávám, jak mám třídit, když vzestupně nastavím sort na false... viz další kroky
        bool sort = false;
        if (sign == 'v') {
                //vzestupně
                sort = true;
        }

        int pokus = 0;


        size_t ctemp;
        while (true) {
                //ověřuji zda není jeden z listů prázdný
                if (l1.size() == 0 && l2.size() == 0) break;
                if (l1.size() > 0 && l2.size() > 0) {
                        if (sort) {
                                //porovnávání prvních slov z listů
                                if (compareNoCase(l1.front(), l2.front())) {
                                        ctemp = l1.front().length(); //zjistím délku slova
                                        fprintf(output, "%x%s", ctemp,l1.front().c_str()); //tisk délky slova a samotného slova
                                        l1.pop_front(); // ostranění prvku z listu
                                        pokus++;
                                }
                                else {
                                        ctemp = l2.front().length();
                                        fprintf(output, "%x%s", ctemp, l2.front().c_str());
                                        l2.pop_front();
                                        pokus++;
                                }
                        }

                        else {
                                if (!compareNoCase(l1.front(), l2.front())) {
                                        ctemp = l1.front().length();
                                        fprintf(output, "%x%s", ctemp, l1.front().c_str());
                                        l1.pop_front();
                                        pokus++;
                                }
                                else {
                                        ctemp = l2.front().length();
                                        fprintf(output, "%x%s", ctemp, l2.front().c_str());

                                        l2.pop_front();
                                        pokus++;
                                }
                        }
                }

                //tady nastal případ že jeden z listů je prázný => vypíšu zbytek druhého listu do výstupu...

                //l1 je prázný => vypíšu l2
                else if (l1.size() == 0 && l2.size()>0) {
                        for (unsigned int i = l2.size(); i > 0; i--) {
                                ctemp = l2.front().length();
                                fprintf(output, "%x%s", ctemp, l2.front().c_str());
                                l2.pop_front();
                                pokus++;
                        }

                }

                //l2 je prázdný vypíšu zbytek l1
                else if (l2.size() == 0 && l1.size() > 0) {
                        for (unsigned int i = l1.size(); i > 0; i--) {
                                ctemp = l1.front().length();
                                fprintf(output, "%x%s", ctemp, l1.front().c_str());
                                l1.pop_front();
                                pokus++;
                        }

                }
        }
        int b = pokus;
        fclose(output);
}

//cesta k souboru, list 1, list 2
void nactiJmena(string path, list<string> &l1, list<string> &l2) {
        char temp[45];  //buffer pro načítání jmen ze souboru
        FILE * file;
        file = fopen(path.c_str(), "r");
        //list do kterého se načtou všechna jména
        list<string> templist;

        while (!feof(file)) {
                //zjistím si délku slova
                char word_length = getc(file);

                //vyzkouším načíst daný počet znaků ( jméno )
                if (fgets(temp, word_length + 1, file)) {
                        string s(temp);
                        templist.push_front(s);
                }
        }
        fclose(file);

        //rozdělení do dvou listů

        int index = 0;
        while (templist.size() > 0) {
                if (index % 2 == 0) {
                        l1.push_front(templist.front());
                        templist.pop_front();
                }
                else {
                        l2.push_front(templist.front());
                        templist.pop_front();
                }

                index++;
        }

}

int main(int argc, char* argv[])
{

        //načtení parametrů z konzole
        string pathin = argv[1];
        string pathout = argv[2];
        char * sortsign = argv[3];

        //listy sloužící pro ukládání načtených jmen
        list<string> mylist1;
        list<string> mylist2;

        nactiJmena(pathin, std::ref(mylist1), std::ref(mylist2));

        thread first(sort, sortsign[0], std::ref(mylist1));
        thread second(sort, sortsign[0], std::ref(mylist2));

        //počkání na ukončení práce vláken
        first.join();
        second.join();

        //provedení slití
        sliti(mylist1, mylist2, sortsign[0], pathout.c_str());

        cout << "Aplikace ukončila práci, zadejte libovolný znak a stiskněte enter" << endl;


        getchar();
        return 0;
}
 
Odpovědět
13.12.2016 20:57
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 1 zpráv z 1.