PDA

Visualizza la versione completa : [C++] Ottimizzazione del confronto tra due file


freetom
05-12-2009, 17:21
Ho due file:

fileA.txt
fileB.txt

entrambi contenenti serie numeriche intervallate dal carattere virgola.

del tipo:

1,2,3,4
10,34,56,80
9,43,65,79
ecc...

io usando la memorizzazione in buffer di memoria li vorrei confrontare (ogni riga del fileA con ogni riga del fileB) in modo da avere ad esempio:

Per due files di es. così:

fileA.txt

1,2,3,4
10,11,12,13
30,31,32,33

fileB.txt

10,2,40,51
9,13,20,21
40,42,43,44

un raffronto-report di questo tipo:

fileA.txt VS fileB.txt

riga 1,2,3,4 VS riga 10,2,40,51 -> un valore uguale (il 2)
riga 1,2,3,4 VS riga 9,13,20,21 -> nessun valore uguale
riga 1,2,3,4 VS riga 40,42,43,44 -> nessun valore uguale

riga 10,11,12,13 VS riga 10,2,40,51 -> un valore uguale (il 10)
riga 10,11,12,13 VS riga 9,13,20,21 -> un valore uguale (il 13)
riga 10,11,12,13 VS riga 40,42,43,44 -> nessun valore uguale

ecc...

Il codice finora messo insieme sarebbe questo:




for (int k=0; k<fileDim; k++) {
for (int y=0; y<fileDim2; y++) {

cout << "dimensione fileA:";
cout << fileDim;
cout << "\n";
cout << k;

cout << "dimensione fileB:";
cout << fileDim2;
cout << "\n";
cout << y;


if (buff[k] == buff2[y] && buff[k] !=',' && buff2[y] !=',' && buff[k] !='\n' && buff2[y] !='\n' ) {


cout << "\n";
cout << buff[k];
cout << "VS";
cout << buff2[y];
cout << "\n";


cout << "carattere uguale";
punti++;
cout << "\n";
cin.get();

}
else
{
cout << "\n";
cout << buff[k];
cout << "VS";
cout << buff2[y];
cout << "\n";
cout << "carattere NON uguale";
cout << "\n";
cin.get();

}
if (punti >5 || buff[k]=='\n' || buff2[k]=='n') {
righeanalisi++;
cout << "PUNTI COMPLESSIVI PER LA RIGA ";
cout << righeanalisi;
cout << " : ";
cout << punti;
cout << "\n";
cout << "azzeriamo punti in quanto si passa alla seconda riga...";
punti=0;
//cin.get();
}
cout << "PUNTI X RIGA: ";
cout << punti;
//cin.get();

}

}

cout << "FINISH!";
cin.get();



ma in questo riscontro due GROSSI PROBLEMI :madai!?:

(1) mi confronta ogni elemento di riga del primo file con il suo corrispettivo (per posizione) elemento del secondo file passando ogni volta dopo aver fatto questo confronto alla riga successiva senza passare al confronto con il secondo,terzo,quarto elemento della riga del secondo file...

in sostanza invece di avere un controllo di questo tipo:

fileA.txt
1,2,3,4

fileB.txt
3,10,11,12
7,20,31,85

1vs3 -> non uguale
1vs10 -> non uguale
1vs11 -> non uguale
1vs12 -> non uguale
2vs3 -> non uguale
2vs10 -> non uguale
2vs11 -> non uguale
2vs12 -> non uguale
3vs3 -> UGUALE
3vs10 -> non uguale
3vs11 -> non uguale
3vs12 -> non uguale
4vs3 -> non uguale
4 vs ecc...

e poi passare a confrontare sempre la prima riga del primo file conb la seconda riga del secondo file sempre alla stessa maniera...

mi fa...

1vs3 -> non uguale

e poi passa a confrontarmi il primo elemento del primo file con il primo elemento della seconda riga del secondo file quindi:

1vs7 -> non uguale

ecc...

:dhò:

Grazie infinite a chi mi dipana sta matassa logiko-programmatica... :mame:

Dimenticavo il secondo PROBLEMONE...

(2) Ogni buff[k] o buff2[y] è un singolo carattere e quindi il confronto viene eseguito correttamente solo per i numeri con una cifra... ma la maggioranza di questi ne hanno 2...
10,11,12,13 ecc... e quindi la necessità di confrontare anche questi numeri formati da due caratteri... :master:



:ciauz:

oregon
05-12-2009, 19:03
Devi ottenere tutti i valori delle due righe tramite la

strtok

e la

atoi

e poi confrontarli.

freetom
05-12-2009, 20:10
for (int i=0; i<fileDim; i++) {
cout << "carattere: ";
cout << buff[i];
cin.get();
s +=buff[i];

cout << s;
cout << "\n";

if (buff[i]==0x0A) {

n++;
}
}

//------------------

cout << "stringa: ";
cout << s;
cin.get();

//{
char str[] = s;

char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, ",");
}
//return 0;
cin.get();
//}




Nonostante :

cout << "stringa: ";
cout << s;
cin.get();

mi stampi a video correttamente la stringa creata dalla congiunzione dei diversi buff[i] trovati compreso le virgole... non riesco a "tokenizzarla" ... in quanto da questo mio codice
ottengo dalla riga:

char str[] = s;

il seguente errore:

velocita13.cpp initializer fails to determine size of `str'

Come posso rimediarvi?

grazie

:ciauz:

oregon
05-12-2009, 20:21
Originariamente inviato da freetom
char str[] = s;

il seguente errore:

velocita13.cpp initializer fails to determine size of `str'


Se i dati sono contenuti in s perche' tenti di usare (in modo sbagliato) un'altra stringa (la str)??



char *pch;
pch = strtok (s, ",");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, ",");
}

freetom
05-12-2009, 20:27
cout << "stringa: ";
cout << s;
cin.get();


char *pch;
pch = strtok (s, ","); //l'errore si riferisce a questa riga
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, ",");
}


cin.get();




errore:

velocita14.cpp cannot convert `std::string' to `char*' for argument `1' to `char* strtok(char*, const char*)'

oregon
05-12-2009, 20:52
Scusa, ma è da tanto che "scrivi codice" C/C++ ... non riesci ancora a risolvere questo tipo di problemi? Vuol dire che non stai "imparando" (come spero e credo) ma solamente "usando" il C/C++ ... e non va bene ...

s è un oggetto di classe

string

del C++, mentre la strtok accetta un puntatore a char (la stringa del C) ... e questo ti sta dicendo quel messaggio d'errore ... devi fare in modo che la strtok riceva quello che si aspetta a partire dalla classe string ...

char *ascnum = strtok((char *)s.c_str(), ",");

freetom
05-12-2009, 21:41
:)

Grazie ancora

Per quanto riguarda il mio programmare in c++ purtroppo lo faccio da poco tempo... (2 mesi al massimo ca) :mame:

:ciauz:

oregon
06-12-2009, 01:52
Originariamente inviato da freetom
(2 mesi al massimo ca)

Sì ... ma quando dici "sembra funzionare" non dimostri che hai cercato di capire anche il "perchè" sembra funzionare ...

E sembra che tu non abbia interesse a capire il "perchè" di certe soluzioni ma solo per il funzionamento finale del tuo generatore di "giocate del lotto" ...

Scusa la franchezza, ma ad ogni risposta ad ogni tua domanda mi sembra di sviluppare conto terzi un programma per il lotto ...

freetom
06-12-2009, 10:55
Per quanto riguarda il cosa sto facendo...

è un programmino per l'analisi di specifici ritardi per mio uso personale appunto per il lotto.
In sostanza vorrei analizzare tutte le possibili quartine (2.555.190) (es.1,2,3,4) confrontandole con tutte le estrazioni di una specifica ruota (che sono ca 4.000) (es.10,11,20,23,43) rilevandone per ogni quartina i ritardi x A,T e Q.

Però dopo essere rimasto positivamente impressionato dalla rapidità di immagazzinamento nella memoria con (char) sono di nuovo fermo per quanto riguarda la rapidità del calcolo allorchè con strtok o atoi separo l'insieme dei caratteri trovati servendomi del carattere separatore virgola...

In quanto è vero che a questo punto ho i numeri voluti... ma non so come gestirli se non reinserendoli in un vector o array e riperdendo così la rapidità del calcolo iniziale...




#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <new>
#include <stdio.h>
#include <string.h>

using namespace std;
int main (int argc, char *argv[]) {
string s;
vector <string> numeri;
int n=0;
//prendo dal file...
FILE *file;
char ch, *buff, FileName[256]="prova2.txt";
int indice, fileDim = 0;
if(( file = fopen( FileName, "rb")) != NULL)
{
// Si posiziona alla fine del file
fseek(file, 0, SEEK_END);
// Legge la posizione attuale
fileDim = ftell(file);
// Alloca la dimensione del buffer
buff = (char*) malloc(sizeof(char) * fileDim+1);
printf("Dimensione del file %s = %d\n", FileName, fileDim);
cin.get();
// Mi riporto all'inizio del file
fseek(file, 0, SEEK_SET);
// Copio tutto il contenuto del file nel buffer
fread(buff, fileDim, 1, file);

for (int i=0; i<fileDim; i++) {

/*
cout << "carattere: ";
cout << buff[i];
cin.get();
*/

s +=buff[i];

//cout << s;
//cout << "\n";

if (buff[i]==0x0A) {

n++;
}
}
}

//------------------

cout << "\n";
cout << "stringa: ";
cout << "\n";
cout << s;
cout << "\n";

//cin.get();



char *ascnum = strtok((char *)s.c_str(), ",");

//{
//char str[] = s;

cout << "\n\n";
cout << "quartine visualizzate: ";
cout << n;
cout << "\n\n";

cin.get();

cout << "\n cosa stampa adesso? \n";

cin.get();

cout << "caricamento array in progress...";

while (ascnum != NULL)
{

//cout << "\n";
//cout << ascnum;

cout << "\n";


// qui inserisco ogni NUMERO nel vector per poterlo gestire
// poi... ma così facendo perdo la velocità... del calcolo iniziale...
// mi piacerebbe... rimanere con i numeri distinti... in memoria
// e poterli gestire direttamente da lì...

numeri.push_back(ascnum);




//printf ("\n%s\n",pch);
ascnum = strtok (NULL, ",");
}

//return 0;
//cin.get();
//}

cout << "arriva qui????";
cin.get();

cout << "stampa qualcosa? ovvero tutti i 10 milioni di numeri memorizzati?";
cout << "\n";
cout << "misura di numeri: ";

cout << numeri.size();
//Anche questo dato non torna... invece di essere.. 2.555.190 (righe rilevate) x 5 (numeri x
// ogni riga) = 12.775990 me ne tornano solo... 7665571

cout << "\n";

cin.get();

cout << "valori: ";
//cout << numeri[3];
cout << "\n";

for (int i=0; i<numeri.size();i++) {

//cout << numeri[i];
cin.get();

}

cout << "\n\n";
cout << "Sono stati raccolti esattamente... : ";
cout << numeri.size();
cout << " numeri";

}



Grazie comunque oregon e complimenti per la tua grandissima esperienza in questo campo.

:ciauz:

freetom
06-12-2009, 11:22
praticamente

in questa riga qui:




numeri.push_back(ascnum);

ascnum = strtok (NULL, ",\n");

}



non avevo messo \n e quindi i caratteri alla fine e all'inizio della riga mi risultavano uno solo... e poi non devo calcolare 2.555.190 x 5 che fa appunto 12.775.950 bensì x 4 = 10.220.760 come appunto mi risulta regolarmente :D

Loading