Problema con ofstream in programma per anagrammi

di il
9 risposte

Problema con ofstream in programma per anagrammi

Buonasera, questo è il primo messaggio che scrivo su questo forum . Sono uno studente 5 liceo scientifico e avrei una domanda su un programma presente nelle esercitazioni delle Olimpiadi di Informatica. Questo programma prende da un file di input due parole o insiemi di lettere (ad esempio ABBA e ABAA) e deve dire se queste due parole sono un anagramma. Il codice che ho provato a fare è il seguente:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <fstream>
using namespace std;

int N;
char Parola[100];
char parola[100];
int lung;

int main()
{
ifstream in("input.txt");
ofstream out("output.txt");
in >> Parola;
in >> parola;
out<< parola<<" "<<Parola;

for(int i=0; i<100; i++)
{
	for(int j=0; j<101; j++)
	{
		if(Parola[i]==parola[j])
		{parola[j]='1';
		Parola[i]='1';
		continue;}
		else if(Parola[i]=='1')
		continue;
		else if(parola[j]=='\0')
		{out <<"NO";
		return 1;}
		
		
		
	}
	out<<endl<<endl;
}
out << "SI";
return 2;
}


Il programma in teoria funziona, facendo return 1 quando le parole non sono anagrammi e return 2 quando lo sono. Il problema è che, per qualche motivo, nel file di output non appare scritto nulla. Qualcuno saprebbe spiegarmi perchè? (Inserendo un out all'inizio, dove, per esempio, viene scritto ciao, funziona, ma il SI o il NO comunque non si attivano)
P.S.
So che molte librerie non servono, ma non ricordando i nomi della maggior parte di esse, faccio sempre copia incolla da un altro programma, aggiungendo altre librerie se necessario.
Grazie mille e buona serata a tutti

9 Risposte

  • Re: Problema con ofstream in programma per anagrammi

    Prova a fare il close dello stream prima di uscire con il return.
    Oppure aggiungi endl dopo il "SI" e il "NO" (se non mi ricordo male, il fine linea triggera il flush)
  • Re: Problema con ofstream in programma per anagrammi

    Diversi ORRORI concettuali.

    Innanzi tutto: un anagramma e' una parola/frase che usa ESATTEMENTE le stesse lettere NELLO STESSO NUMERO della parola/frase di partenza.

    Un esempio banale e'
  • Re: Problema con ofstream in programma per anagrammi

    Non so se in C/C++ complica la vita.
    Ho le due stringhe st1 e st2
    controllo se hanno la stessa lunghezza (se diversa no anagramma)
    uso i caratteri di st1, uno ad uno, per rimuoverli se uguali da st2
    se st2 resta vuota, è un anagramma.

    in C# sarebbe:
                string st1 = null;
                string st2 = null;
    riinput:
                st1 = Console.ReadLine();
                st2 = Console.ReadLine();
                if (st1.Length != st2.Length)
                {
                    Console.WriteLine("No");
                    goto riinput;
                }
                for (var i1 = 0; i1 < st1.Length; i1++)
                {
                    char car1 = st1[i1];
                    int i2 = 0;
                    do
                    {
                        char car2 = st2[i2];
                        if (car1 == car2)
                        {
                            st2 = st2.Remove(i2, 1);
                        }
                        i2++;
                    } while (i2 < st2.Length );
                }
                if (st2.Length > 0)
                {
                    Console.WriteLine("No");
                }
                else
                {
                    Console.WriteLine("Si");
                }
                goto riinput;
  • Re: Problema con ofstream in programma per anagrammi

    Comunque per quanto riguarda il problema segnalato dall'OP, il SI e NO non li leggeva semplicemente perché ha messo una tonnellata di endl nel ciclo, quindi se apre il file sono nascosti in fondo...
  • Re: Problema con ofstream in programma per anagrammi

    Di C ne so proprio poco, quanto posto di seguito funziona, ma non ho idea se si può chiamare buona programmazione.
    La logica è quella che avevo esposto di eliminare i caratteri uguali, ma non avendo .Remove la rimozione la simulo inserendo un '!' poi conto i caratteri uguali.
    Codice in C, testato con CODE::BLOCK e VisualStudio.
    
    #define _CRT_SECURE_NO_WARNINGS // per VS, se in VS si usa scanf_s si può eliminare la riga
    #include <iostream> // per VS
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    int main()
    {
    	int i, lenSt1, lenSt2, ind, quanti = 0;
    	char buffer[100];
    	char *St1 = NULL;
    	char *St2 = NULL;
    
    	printf("Controllo se due parole sono anagrammi, * per uscire\n");
    
    riinput:
    	// ************** INPUT e VALIDAZIONE **************
    	printf("---------------------\n");
    	printf("prima parola: ");
    	//scanf_s("%s", &buffer, 100); // Microsoft C compiler, previene overflow con la dichiarazione del buffer
    	scanf("%s", &buffer); // Standard C
    	if (buffer[0] == '*') { goto uscita; }
    	lenSt1 = strlen(buffer);
    	// allocazione adeguata alla stringa immessa
    	St1 = (char*)calloc(lenSt1 + 2, sizeof(char));
    
    	for (i = 0; i < lenSt1; i++)
    	{
    		St1[i] = toupper(buffer[i]); // in matrice di caratteri maiuscoli
    	}
    
    	printf("seconda parola: ");
    	//scanf_s("%s", &buffer, 100); // Microsoft C compiler, previene overflow con la dichiarazione del buffer
    	scanf("%s", &buffer); // Standard C
    	if (buffer[0] == '*') { goto uscita; }
    	lenSt2 = strlen(buffer);
    	// allocazione adeguata alla stringa immessa
    	St2 = (char*)calloc(lenSt2 + 2, sizeof(char));
    
    	for (i = 0; i < lenSt2; i++)
    	{
    		St2[i] = toupper(buffer[i]); // in matrice di caratteri maiuscoli
    	}
    
    	// ************** CONTROLLO SE ANGRAMMA **************
    	if (lenSt1 != lenSt2) // lunghezza diversa no anagramma
    	{
    		printf("%s e %s, No anagrammi\n", St1, St2);
    		goto riinput;
    	}
    	// Conto i caratteri uguali
    	ind = 0;
    	quanti = 0;
    	for (i = 0; i < lenSt1; i++)
    	{
    		ind = 0;
    		do {
    			if (St1[i] == St2[ind])
    			{
    				St2[ind] = '!'; // "rimuovo" il carattere sostituendolo con il !
    				quanti++;
    				break; // esco per evitare doppio conteggio
    			}
    			ind++;
    		} while (lenSt2 > ind);
    	}
    
    	// ************** RISULTATO **************
    	if (quanti == lenSt2) // se tutte le lettere sono presenti
    	{
    		printf("%s tutti rimossi, Si anagramma\n", St1);
    	}
    	else
    	{
    		printf("%s rimossi %d [%s], No anagramma\n", St1, quanti, St2);
    	}
    	goto riinput;
    	// ***************************************
    uscita:
    	if (St1 != NULL) { free(St1); }
    	if (St2 != NULL) { free(St2); }
    
    	return(0);
    }
  • Re: Problema con ofstream in programma per anagrammi

    Questo è un esercizio che è stato dato varie volte e ci sono un'infinità di soluzioni
    in particolare usare due stringhe e "cancellare" mano a mano i caratteri della prima che ci sono nella seconda e viceversa implica "alterare" le due stringhe in ingresso, che potrebbe nno essere consentito, o semplicemente potrebbero essere const

    nel tempo qualcuno ha consigliato anche eseguire un "sort" (funzione di libreria standard in C) delle due stringhe e poi di confrontare risultati
    mi sembra inutilmente dispendioso e comunque altera i dai in input, non sempre è possibile farlo

    anche creare due array di "lettere" e contarne le ripetizioni nella due stringhe e poi confrontarli, per vedere se ci sono differenze nelle ripetizioni delle lettere si può velocizzare e ridurre di occupazione di memoria
    venendo da arduino per me la memoria è sempre critica
    in passato avevo fatto una cosa simile a questo:
    
    #include <stdio.h>
    //#include <string.h>
    #include <stdlib.h>
    
    char input[] = "ciao, ";
    char * output;
    
    int anagramma(char * s1, char * s2)
    {
       if(s1 && s2)
       {
          // tutti e due i puntatori sono validi
          int ana[256] = {0};
    
          while(*s1)
          {
             ana[*s1]++;
             s1++;
          }
    
          while(*s2)
          {
             ana[*s2]--;
             s2++;
          }
    
          for(int i = 0; i < 256; i++)
          {
             if(ana[i])
             {
                return 0;
             }
          }
    
          return 1;
       }
    
       else
       {
          // almeno uno dei due puntatori è invalido
          return 0;
       }
    }
    int main()
    {
       
       output=input;
       
       printf("%s\n",input);
       printf("%s\n",output);
       
       if(anagramma(input, output))
       {
          printf("Le stringhe sono anagrammi\n");
       }
    
       else
       {
          printf("Le stringhe non sono anagrammi\n");
       }
    }
    
    è C, non C++
    ma quello che conta è la funzione che accetta due stringhe, non le cambia, e restituisce 1 se sono anagrammi, 0 se non lo sono

    funziona con array di caratteri, puntatori a caratteri, array di caratteri inizializzati con "stringhe letterali", che stando al K&R non sono modificabili, puntatori a caratteri che puntano ad array di caratteri,
    e ogni possibile combinazione
  • Re: Problema con ofstream in programma per anagrammi

    FireWolf20 ha postato la domanda ma poi non sembra interessato...
    @ StandardOil, ribadisco la mia ignoranza in C, il tuo codice mi ha insegnato una cosa in più sul while e come agire direttamente in ram, grazie.
    Ti faccio alcune domande, solo per capire di più:
    1) il vettore da 257 elementi non è uno spreco di memoria?
    2) il ciclo con 256 if non è uno spreco di risorse?

    Il tuo codice è case sensitive.

    Per il fatto che le stringhe di origine è meglio non modificarle, sono d'accordo ho aggiunto s3:
    
    #define _CRT_SECURE_NO_WARNINGS // per VS
    #include <iostream>
    #include <string.h>
    
    using namespace std;
    
    	char St1[] = "anno";
    	char St2[] = "Nano";
    
    int anagramma(char * s1, char * s2)
    {
    	int i, lenSt1, lenSt2, ind, quanti = 0;
    	char *s3 = NULL;
    
    	lenSt1 = strlen(s1);
    	lenSt2 = strlen(s2);
    	if (lenSt1 != lenSt2){return 0;}
    
        	s3 = (char*)calloc(lenSt2 + 1, sizeof(char));
    	strncpy(s3, s2, lenSt2 + 1); // così non modifico s2
    
    	for (i = 0; i < lenSt1; i++)
    	{
    		ind = 0;
    		while (lenSt2>ind)
            {
    		if (s1[i] == s3[ind])
    		{
    			s3[ind] = '!'; // "rimuovo" il carattere sostituendolo con il !
    			quanti++;
    			break; // esco per evitare doppio conteggio
    		}
    		ind++;
    		}
    	}
    	if (quanti == lenSt1){return(1);} else{return(0);}
    }
    int main()
    {
        	// tutto maiuscolo
       	for(char *c=St1; *c=toupper(*c); ++c);
       	for(char *c=St2; *c=toupper(*c); ++c);
        	printf("%s\n",St1);
       	printf("%s\n",St2);
    
     	if(anagramma(St1, St2))
        	{
          		printf("Le stringhe sono anagrammi\n");
        	}
        	else
        	{
          		printf("Le stringhe non sono anagrammi\n");
        	}
    }
    
    
    Prima o poi ci capirò qualcosa...
  • Re: Problema con ofstream in programma per anagrammi

    Volutamente case sensitive

    Accetta qualsiasi carattere ASCII

    Se si deve limitare si può pretrattare la stringa prima, oppure farne una versione apposta

    Ecco la ragione di 256 elementi
    Vuoi solo le maiuscole? In uno dei miei primi post la trovi
    Invece la si erano lamentati che mancavano le minuscole....

    Non è mai facile accontentare tutti

    256 if?
    Eh... se devi controlla l'intero alfabeto ASCII i test li devi fare


    Ma tanto al primo che fallisce se ne esce anticipatamente
  • Re: Problema con ofstream in programma per anagrammi

    StandardOil ha scritto:


    Volutamente case sensitive

    Vuoi solo le maiuscole? In uno dei miei primi post la trovi
    Invece la si erano lamentati che mancavano le minuscole....

    Non è mai facile accontentare tutti
    Giusto, chi chiama la funzione decide...
    Come ho fatto io invece il chiamante non ha possibilità di scelta, lo correggo perché è sbagliato concettualmente!
Devi accedere o registrarti per scrivere nel forum
9 risposte