/*
Nome: Mario
Cognome: Montanari
Classe: 3AIN
Data: 10/05/2025

1) Quick Sort tra le stringhe di una struttura Info
2) Funzione ricercaStringa
3) Funzione ricercaBinaria
*/

#include <iostream>
#include <ctime>
#include <cstdlib>

using namespace std;

typedef struct {
	int num;
	char str[9+1];
} Info;

int qstrcmp(const void * a, const void * b) {
	const Info * pa = (const Info*)a;
	const Info * pb = (const Info*)b;
	
	return strcmp(pa -> str, pb -> str);
}

int ricercaStringa(const char * str_ricerca) {
	const char * filename = "esercizio.bin";
	
	FILE * file = fopen(filename, "rb");
	
	if (file != NULL) {
		Info str;
		
		int pos = 0;
		
		while (fread(&str, sizeof(str), 1, file) == 1) {
			pos++;
			
			if (strcmp(str.str, str_ricerca) == 0) {
				return pos;
				
				break;
			}
		}
		
		fclose(file);
		
		return -1;
	} else {
		perror("Error");
		return -1;
	}
}


int ricercaBinaria(const char * bin_ricerca) {
	const char * filename = "esercizio.bin";
	
	FILE * file = fopen(filename, "rb");
	
	if (file != NULL) {
		fseek(file, 0, SEEK_END);
		long dim = ftell(file) / sizeof(Info);
		int inf = 0;
		int variabile = 0;
		long sup = dim - 1;
		
		while (inf <= sup) {
			int mid = (inf + sup) / 2;
			
			Info bin;
			
			fseek(file, mid * sizeof(Info), SEEK_SET);
			fread(&bin, sizeof(bin), 1, file);
			
			int cmp = strcmp(bin.str, bin_ricerca);
			
			if (cmp == 0) {
				return mid;
			} else if (cmp > 0) {
				sup = mid - 1;
			} else {
				inf = mid + 1;
			}
		}
		
		fclose(file);
		
		return -1;
	} else {
		perror("Error");
		return -1;
	}
}

int main(void) {
	srand(time(NULL));
	
	Info info[20];
	
	for (int i = 0; i < 20; i++) {
		for (int j = 0; j < 9; j++) {
			info[i].str[j] = rand() % 26 + 'A';
		}
		info[i].str[9] = '\0';
		info[i].num = rand() % 1000;
	}
	
	qsort(&info, 20, sizeof(*info), qstrcmp);
	
	FILE * file = fopen("esercizio.bin", "wb");
	
	if (file != NULL) {
		fwrite(&info, sizeof(Info), 20, file);
		
		fclose(file);
	} else {
		perror("Error");
		return 1;
	}
	
	cout << "== STRINGHE ORDINATE ==" << endl;
	for (int i = 0; i < 20; i++) {
		cout << i + 1 << ") " << info[i].str << ", " << info[i].num << endl;
	}
	
	char cerca[10];
	cout << endl << "Inserisci la stringa da cercare: ";
	cin >> cerca;
	
	int ricerca1 = ricercaStringa(cerca);
	if (ricerca1 != -1) {
		cout << "Stringa (ricerca lineare) trovata in posizione " << ricerca1 << endl;
	} else {
		cout << "Stringa (ricerca lineare) non trovata." << endl;
	}
	
	int ricerca2 = ricercaBinaria(cerca);
	if (ricerca2 != -1) {
		cout << "Stringa (ricerca binaria) trovata in posizione " << ricerca2 + 1 << endl;
	} else {
		cout << "Stringa (ricerca binaria) non trovata." << endl;
	}
	
	file = fopen("esercizio.bin", "rb");
	
	if (file != NULL) {
		Info temp;
		
		cout << endl << "== LETTURA DA FILE ==" << endl;
		
		int pos = 1;
		
		while (fread(&temp, sizeof(Info), 1, file)) {
			cout << pos++ << ") " << temp.str << ", " << temp.num << endl;
		}
		
		fclose(file);
	} else {
		perror("Error");
		return 1;
	}
	
	return 0;
}