Tervehdys,
ongelmana on tekstitiedoston datan muokkaus. Tekstitiedosto sisältää viisi saraketta.
1 | 2 | 3 | 4 | 5 |
1 2 4 4 1
2 3 4 4 3
3 4 5 0 0
Tarkoitus olisi siirtää sarakkeiden 4 ja 5 ( arvot > 0 ) sarakkeiden 1 ja 2 yläpuolelle tai jatkoksi:
1 | 2 | 3 | 4 | 5 |
1 2 4 0 0
2 3 4 0 0
3 4 5 0 0
4 1 0 0 0
4 3 0 0 0
Toivoisin ongelmaan vastauksia, eikä suinkaan mitenkään kielisidottuna.
kun saadaan luettua luvut s1, s2, s3, s4, s5: lisää taulukkoon t1 luvut s1, s2, s3, 0, 0 lisää taulukkoon t2 luvut s4, s5, 0, 0, 0 kun taulukon t2 lopussa on 0, 0, 0, 0, 0: poista taulukon t2 viimeinen rivi tulosta taulukko t1 tulosta taulukko t2
Taulukoksi käy hyvin C++:n std::vector.
#include <iostream> #include <Windows.h> #include <vector> #include <sstream> #include <algorithm> #include <iterator> #include <fstream> #include <string> INT WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow) { std::vector<std::vector<double> > contents; { std::ifstream Tiedosto( "data.txt" ); for ( std::string line; Tiedosto; std::getline( Tiedosto, line ) ) { std::stringstream line_stream( line ); std::vector<double> row; copy( std::istream_iterator<double>( line_stream ), std::istream_iterator<double>(), back_inserter(row) ); contents.push_back( row ); } } unsigned int Koko = contents.size(); for ( unsigned int i=0; i < Koko; ++i ) { std::vector<double> row( 5, 0. ); bool add_row = false; if ( contents[i].size() >= 5 ) { for ( unsigned int j=3; j<4; ++j ) { double value = contents[i][j]; contents[i][j] = 0.; if ( value > 0 ) { add_row = true; row[j-3] = value; } } if ( add_row == true ) { contents.push_back( row ); } } } std::ofstream Uus; Uus.open("Uusi.txt"); for ( unsigned int i=0; i < contents.size(); ++i ) { copy( contents[i].begin(), contents[i].end(), std::ostream_iterator<double>( Uus, " " ) ); Uus << std::endl; } Uus.close(); MessageBox(NULL, "Valmis!", "Valmis", MB_ICONINFORMATION); ExitProcess(0); }
@Stackoverflow + pieni muokkaus.
Tässä on vielä versio, jossa on korjattu eräitä Roxin koodin puutteita: tämä on lyhyempi ja selvempi ja toimii oikein eikä ole riippuvainen Windowsista.
#include <fstream> #include <vector> #include <string> int main() { std::string a, b, c, d, e; std::vector<std::string> t1, t2; for (std::ifstream ifs("in.txt"); ifs >> a >> b >> c >> d >> e;) { t1.push_back(a + " " + b + " " + c + " 0 0\n"); if (d != "0" || e != "0") { t2.push_back(d + " " + e + " 0 0 0\n"); } } std::ofstream ofs("out.txt"); for (auto s: t1) ofs << s; for (auto s: t2) ofs << s; }
Kiitoksia vastauksista!
Päädyin tekemän koodin Pythonilla esimerkkienne mukaan. Mitenkäs muuten dataa, joka sisältää paljon numeroita kannattaa säilöä yleensäkkin? Kokeilin huvikseen .txt tiedostoa ja sain yli gigan kirjoittamiseen näköjään uppoaa aikaa kivasti. Tarkoitus olisi vielä käsitellä isoja alueita .txt tiedostosta, joten tämä ei liene järkevää. Pythonia käytän vasta ensimmäistä päivää, joten muista vaihtoehdoista ei ole kokemusta. -> data, tietokanta jne?
Ongelmia tuli vastaan myös lukujen käsittelyissä, koska for looppeja ei voinut käyttää laisinkaan pitkien numerosarjojen takia. (overflow). Onneksi asian pysty kiertää while loopeilla.
Ihastuin kyllä IPythonin (Py 2.7) Notebookkiin :)
Jos data sisältää pelkästään lukuja, binäärimuoto on selvästi käytännöllisin. Esimerkiksi jos data koostuu viidestä sarakkeesta, joissa on vain pieniä lukuja (alle 256), riittää tiedostossa yksi tavu jokaiselle luvulle. Dataa voi muuttaa binäärimuodon ja tavallisten muuttujien välillä struct-moduulin funktioilla.
Suuren datamäärän käsittelyssä on hyvä huomioida, että Python on selvästi hitaampi kuin esimerkiksi C++ tai Java ja muuttujatkin vievät siinä enemmän tilaa. Gigan kokoinen tiedosto kuulostaa jo sellaiselta, että aika monessa tilanteessa jättäisin Pythonin heti pois laskuista.
Ansy kirjoitti:
Ongelmia tuli vastaan myös lukujen käsittelyissä, koska for looppeja ei voinut käyttää laisinkaan pitkien numerosarjojen takia. (overflow). Onneksi asian pysty kiertää while loopeilla.
Olet varmaankin tulkinnut ongelman väärin; for-silmukassa ei ole mitään erityistä rajoitusta. Python 2:ssa kuitenkin range-funktio luo luvuista listan, joten sitä ei voi käyttää suurten lukualueiden kanssa, koska listasta tulee mahdottoman suuri. Sen sijaan xrange luo iteraattorin, joten sitä voi käyttää suurillakin alueilla. Python 3:ssa range toimii samoin kuin entinen xrange, joten siinä koko ongelmaa ei varmaan olisi ilmennyt.
Yleensä kannattaa käyttää uusinta versiota, jos ei ole erityistä syytä käyttää vanhaa.
Oh ok, kiitos tiedosta! Tosiaan tuli käytettyä range- / xrange-funktiota ja niihin tosiaan kosahti. Koodausmielessä Python tuntuu omasta näkövinkkelistä helpommalta ja selkeämmältä kuin C++. Javaa ei ole tullut paljon kokeiltua, joten se on seuraavana listassa, ellei Pythonilla ala toimimaan kunnolla asiat.
Tietty C++ en ole sulkenut pois mielestä, mutta osaksi rikkinäinen versio visual studiosta tuntuu vaan niin kankealta pyörittää läppärillä. Varmaan pitäisi tutustua ilmaisiin kääntäjiin.
Aihe on jo aika vanha, joten et voi enää vastata siihen.