|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
[vari] Contest 6 - Parsing
Per riempire il buco lasciato da Gugo nella numerazione dei contest, propongo il seguente:
Problema 1: Sia dato, in input, un array di stringhe; ogni stringa rappresenta un'espressione aritmetica. Gli operatori validi sono: - (unario e binario), + (unario e binario), *, /, ^. Quest'ultimo rappresenta l'operatore di elevamento a potenza: 2^3 si legge 2 elevato a 3. Si produca, in output, un file di testo in cui ogni riga contiene l'espressione seguita dal segno di uguale seguito dal risultato. Per esempio, se in input abbiamo la seguente espressione: 3 * (2.5 + 5) in output avremo: 3 * (2.5 + 5) = 22.5 In caso di errori, dopo il segno di uguale, va riportata la descrizione dell'errore. Per esempio: 3 * (2.5 + 5 = Errore: parentesi non bilanciate. I file possono essere scaricati da QUI. La prima riga del file contiene il numero di espressioni da valutare; le righe restanti contengono le espressioni(una per ogni riga). Problema 2: Sia dato, in input, un array di stringhe contenenti espressioni in formato RPN. Fornire, in output, un file di testo che contenga le espressioni equivalenti(seguite dal segno di uguale e dal risultato) in notazione infissa. Per esempio: input: 3 5 * 4 + output : 3 * 5 + 4 = 19 I file per il secondo problema possono essere scaricati da QUI il file espressioni3.txt è quello piccolo; espressioni4.txt è quello grosso. ATTENZIONE: nella notazione RPN, per distinguere il meno unario da quello binario, è necessario utilizzare due diversi simboli. Nei file suindicati, il simbolo ~ rappresenta il meno unario. Il meno binario è rappresentato dal simbolo usuale: - ![]() Ultima modifica di Vincenzo1968 : 27-10-2008 alle 18:29. |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
|
Bello, proviamo a lavorarci un po'.
__________________
C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai! |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
|
Il formato è libero? Numeri e simboli possono essere separati da un qualsiasi numero di spazi?
__________________
C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai! |
![]() |
![]() |
![]() |
#5 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Grazie
![]() Questi sono i miei tempi: sul file piccolo: ![]() sul file grosso: ![]() La mia macchina: Codice:
AMD Athlon(tm) 64 X2 Dual Core Processor 4800+ 2.50 GHz 896 MB di RAM Microsoft Windows XP Professional (32 bit) Service Pack 3 file piccolo: ![]() file grosso: ![]() Il sorgente in C può essere scaricato da qui Ne riporto solo una parte: Codice:
void Calcola(Array *pArray, char *szFileName) { double dblResult; char szResult[1024] = ""; char szError[256] = ""; int k; FILE *fp; fp = fopen(szFileName, "w+"); for (k = 0; k < pArray->size; k++) { nNextPos = 0; PreviousTokenType = EOL; sp_op = 0; sp_val = 0; dblResult = EvalInfix(pArray->m[k], szError); if ( szError[0] != '\0' ) sprintf(szResult, "%s = %s\n", pArray->m[k], szError); else sprintf(szResult, "%s = %lf\n", pArray->m[k], dblResult); fwrite(szResult, strlen(szResult), 1, fp); } fclose(fp); } int main() { Stati stato; Array myArray; char *szFileName = "espressioni1.txt"; char *szFileNameOutput = "output1.txt"; int k; clock_t c_start, c_end; c_start = clock(); myArray.m = NULL; stato = DFA(szFileName, &myArray); c_end = clock(); printf("\nTempo impiegato per il caricamento dei dati -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC); c_start = clock(); if ( stato != S_ERROR ) Calcola(&myArray, szFileNameOutput); if ( myArray.m != NULL ) { for(k = 0; k < myArray.size; k++) { if ( myArray.m[k] != NULL ) free(myArray.m[k]); } free(myArray.m); } c_end = clock(); printf("\nTempo impiegato per il calcolo delle espressioni -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC); return 0; } P.S. Dimenticavo: se volete, potete utilizzare tools come Yacc/Bison o ANTLR. Sono a disposizione per la spiegazione dell'algoritmo che ho utilizzato ![]() Ultima modifica di Vincenzo1968 : 26-10-2008 alle 20:40. |
![]() |
![]() |
![]() |
#6 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
|
![]() |
![]() |
![]() |
#7 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
|
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Apr 2006
Messaggi: 22462
|
un dettaglio ma se seguo quello che mi hanno insegnato a scuola metà delle espressioni sono sbagliate: mi spiego
-8.5 + 49.96/(3 + -77.83/2) è errata perchè ci sono due segni ( ... + -77.83....) in successione; a me a scuola quando scrivo una cosa del genere la prof fa un segno rosso e mette il cacolo sbagliato; quando usi quella notazione dte intendi dire questo? ( ... + (-77.83)....)
__________________
amd a64x2 4400+ sk939;asus a8n-sli; 2x1gb ddr400; x850 crossfire; 2 x western digital abys 320gb|| asus g1
Se striscia fulmina, se svolazza l'ammazza |
![]() |
![]() |
![]() |
#9 | |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
Codice:
double dbl = -8.5 + 49.96/(3 + -77.83/2); printf("valore -> %lf\n", dbl); ![]() |
|
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Apr 2006
Messaggi: 22462
|
nemmeno il jdk di lamenta; era solo un dettaglio che mi sembrava giusto chiarire
__________________
amd a64x2 4400+ sk939;asus a8n-sli; 2x1gb ddr400; x850 crossfire; 2 x western digital abys 320gb|| asus g1
Se striscia fulmina, se svolazza l'ammazza |
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Oct 2001
Messaggi: 11471
|
Questi sono i tempi per il primo file, togliendo i vari output.
Codice:
Macintosh:Desktop mirco$ time ruby contest6.rb real 0m3.078s user 0m2.993s sys 0m0.048s ![]() |
![]() |
![]() |
![]() |
#12 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
|
![]() |
![]() |
![]() |
#13 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
|
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Oct 2001
Messaggi: 11471
|
|
![]() |
![]() |
![]() |
#15 | |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
![]() Questo è il codice che ho usato per creare i due file: Codice:
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> #define BUFFER_SIZE 4096 char *expr[] = { "n + (n - n)/n^(1/2)", "n / n^0.5", "(n - n) + (n * 2)/(n - n)", "(n + n/(n+n)) - n * n/2", "n + (n^4^0.5 - n)", "(n * n/(1 + n) - 5) / (-4.3 + n^(1/2))", "-8.5 + n/(3 + n/2)", "-5.21 * n*(-8 + n*(n/(2+n^0.5)))", "((n * n/(1 + n) - 8.3) / (-4.3 + n^(1/2)))/(-21.8 * n*(-5 + n*(n/(2+n^0.5))))", "((n + n/(n+n)) - n * n/2)*(n / n^0.5)", "(n + (n^4^0.5 - n)) - ((n * n/(1 + n) - 5) / (-4.3 + n^(1/2))))" }; int RangedRand(int range_min, int range_max) { // Generate random numbers in the half-closed interval // [range_min, range_max). In other words: // range_min <= random number < range_max return ((double)rand() / (RAND_MAX + 1) * (range_max - range_min) + range_min); //printf( " %6d\n", u); } void CreaFile() { FILE *fp; int i, j, k, x; int n; char szNum[256]; int p1, p2; float f; int len1, len2; char szExpr[256]; int numlines = 200000; fp = fopen("espressioni2.txt", "w+"); sprintf(szExpr, "%d\n", numlines); fwrite(szExpr, strlen(szExpr), 1, fp); for ( i = 0; i < numlines; i++ ) { j = RangedRand(0, 11); len1 = strlen(expr[j]); k = 0; for(n = 0; n < len1; n++) { if ( expr[j][n] != 'n' ) { szExpr[k++] = expr[j][n]; } else { p1 = RangedRand(-100, 100); p2 = RangedRand(0, 100); if ( p2 < 10 ) f = p1 + (float)p2/10; else f = p1 + (float)p2/100; sprintf(szNum, "%3.2f", f); len2 = strlen(szNum); if ( szNum[len2 - 1] == '0' ) szNum[len2 - 1] = '1'; for(x = 0; x < len2; x++) szExpr[k++] = szNum[x]; } szExpr[k] = '\0'; } fwrite(szExpr, strlen(szExpr), 1, fp); fwrite("\n", 1, 1, fp); //printf("record n. %d\n", i); } fclose(fp); } int main() { srand((unsigned)time(NULL)); CreaFile(); return 0; } |
|
![]() |
![]() |
![]() |
#16 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Ho aperto il file con Notepad++ e mi dice che il file è in formato Windows/Ansi:
![]() ![]() |
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: Oct 2001
Messaggi: 11471
|
La riga che dava fastidio era la 6. Più precisamente quello strano carattere a doppia S che ruby sembrava non capire essere utf8.
Codice:
(-49.63 + (39.21^4^0.5 § 87.29)) - ((-93.21 * 84.57/(1 + -85.75) - 5) / (-4.3 + -64.86^(1/2)))) I tempi per il secondo file sono: Codice:
Macintosh:Desktop mirco$ time ruby contest6.rb real 0m6.174s user 0m6.008s sys 0m0.102s Codice:
File.open('prova.txt', 'r') do |file| file.gets # ignora la prima riga while expression = file.gets begin result = eval(expression.chop!.gsub('^', '**')) puts "#{expression} = #{result}" rescue ZeroDivisionError puts "#{expression} : Divisione per zero" rescue SyntaxError puts "#{expression} : Errore di sintassi nella espressione" end end end |
![]() |
![]() |
![]() |
#18 | |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
in questi casi il risultato dell'espressione dev'essere: Errore: operatore non riconosciuto(l'ho inserito a mano dopo aver creato il codice con il sorgente che ho postato sopra ![]() Posta i dati relativi alla tua macchina ![]() |
|
![]() |
![]() |
![]() |
#19 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Vicius scusa,
ma l'output viene scritto su file o a video? (sai che non me ne intendo di ruby ![]() Per il calcolo dei tempi devono essere esclusi i tempi di caricamento dell'array di stringhe dal file, ma debbono essere inclusi i tempi di scrittura sul file di output. |
![]() |
![]() |
![]() |
#20 |
Senior Member
Iscritto dal: Oct 2001
Messaggi: 11471
|
Sto su un core2 2.4ghz, 2gb di ram.
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 19:42.