#include #include #include #include #include #include #include struct Set { char el; Set* next; Set(char e, Set* n = nullptr) : el(e), next(n) { } ~Set() { delete next; } }; using namespace std; const char universum[] = "ABCDEFGHIJKMNLOPQRSTUVWXYZ"; const char filename[] = "Test_result.txt"; const int length = 26; const int durationCoeff = 1000000; int customTestAmount = 0; char stringA[length], stringB[length], stringC[length], stringD[length]; Set *vectorA = nullptr, *vectorB = nullptr, *vectorC = nullptr, *vectorD = nullptr, *vectorF = nullptr; void setupConsole() { setlocale(LC_ALL, "Russian"); SetConsoleOutputCP(1251); SetConsoleCP(1251); cout << fixed << setprecision(7); } void outputGreeting() { cout << "Программа рассчитывает значение множества F согласно следующим законам - " << endl; cout << "F = D && (A || B) && !C, что равносильно F = D*(A + B) - C." << endl; cout << "Универсум: " << universum << endl; } void input() { cout << endl; cout << "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" << endl; cout << "Введите множество A: "; cin >> stringA; cout << "Введите множество B: "; cin >> stringB; cout << "Введите множество C: "; cin >> stringC; cout << "Введите множество D: "; cin >> stringD; cout << endl; } bool isCorrectSymbol(char symbol) { return ((symbol >= universum[0] && symbol <= universum[length - 1]) || symbol == '\0') ? 1 : 0; } bool isStringCorrect(char* string) { for (int i = 0; i < length && string[i] != '\0'; i++) if (!isCorrectSymbol(string[i])) return 0; return 1; } int memberToIndex(char member) { return member - universum[0]; } char indexToMember(int number) { return number + universum[0]; } Set* vectorFromString(Set* vector, const char string[]) { Set* p = vector; for (int i = 0; string[i]; i++) { if (p) { p = vector; if (memberToIndex(vector->el) > memberToIndex(string[i])) { p = new Set(string[i], vector); vector = p; } else { while (p->next && memberToIndex(p->next->el) < memberToIndex(string[i])) p = p->next; if (p->next) p->next = new Set(string[i], p->next); else { if (memberToIndex(p->el) < memberToIndex(string[i])) p->next = new Set(string[i]); else { if (memberToIndex(p->el) != memberToIndex(string[i])) { p->next = new Set(string[i], p->next); } } } } } else { vector = new Set(string[i]); p = vector; } } return vector; } void convertSets() { vectorA = vectorFromString(vectorA, stringA); vectorB = vectorFromString(vectorB, stringB); vectorC = vectorFromString(vectorC, stringC); vectorD = vectorFromString(vectorD, stringD); } void calculateAnswer() { Set* pF = vectorF; for (Set* pA = vectorA; pA; pA = pA->next) { if (pF) { pF->next = new Set(pA->el); pF = pF->next; } else { pF = new Set(pA->el); vectorF = pF; } } pF = vectorF; for (Set* pB = vectorB; pB; pB = pB->next) { if (pF) { while (pF->next && memberToIndex(pF->next->el) < memberToIndex(pB->el)) pF = pF->next; if (!pF->next || memberToIndex(pF->next->el) != memberToIndex(pB->el)) { if (pF == vectorF) { if (memberToIndex(pB->el) <= memberToIndex(pF->el)) { pF = new Set(pB->el, vectorF); vectorF = pF; } } else { pF->next = new Set(pB->el, pF->next); pF = pF->next; } } } else { pF = new Set(pB->el); vectorF = pF; } } pF = vectorF; for (Set* pC = vectorC; pC && pF; pC = pC->next) { if (memberToIndex(pF->el) == memberToIndex(pC->el) && pF == vectorF) { vectorF = pF->next; pF = pF->next; } while (pF && pF->next && memberToIndex(pF->next->el) < memberToIndex(pC->el)) pF = pF->next; if (pF && pF->next && memberToIndex(pF->next->el) == memberToIndex(pC->el)) pF->next = pF->next->next; } pF = vectorF; Set* last = nullptr; for (Set* pD = vectorD; pD; pD = pD->next) { while (pF && memberToIndex(pF->el) < memberToIndex(pD->el)) pF = pF->next; if (pF && memberToIndex(pF->el) == memberToIndex(pD->el)) { if (last == nullptr) { last = pF; vectorF = pF; } else { last->next = pF; last = pF; } } } if(pF) last->next = nullptr; } void outputSetToConsole(Set* vector) { for (Set* p = vector; p; p = p->next) cout << p->el; } void outputSetToFile(Set* vector, ofstream& output) { for (Set* p = vector; p; p = p->next) output << p->el; } bool isSetEmpty(Set* vector) { return vector ? 0 : 1; } void outputAnswer() { cout << "Ответ: F = "; if (isSetEmpty(vectorF)) cout << "пустое множество"; else outputSetToConsole(vectorF); cout << endl; } double calulateDuration() { double firstPoint, lastPoint, duration = 0; for (int i = 0; i < durationCoeff; i++) { firstPoint = clock(); calculateAnswer(); lastPoint = clock(); duration += lastPoint - firstPoint; } return duration / durationCoeff; } void outputDuration() { cout << endl; cout << "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" << endl; cout << "Временная сложность алгоритма - O(1), постоянное время" << endl; cout << "На выполнение алгоритма уходит " << calulateDuration() << " секунд." << endl; cout << endl; } float factorial(int number) { float factorial = 1; for (int i = 1; i <= number; i++) factorial *= i; return factorial; } bool randomVector() { return rand() % 2; } void fillVectors() { Set* pA = vectorA, * pB = vectorB, * pC = vectorC, * pD = vectorD; for (int i = 0; i < length; i++) { if (randomVector()) { if (pA) { pA->next = new Set(indexToMember(i)); pA = pA->next; } else { vectorA = new Set(indexToMember(i)); pA = vectorA; } } if (randomVector()) { if (pB) { pB->next = new Set(indexToMember(i)); pB = pB->next; } else { vectorB = new Set(indexToMember(i)); pB = vectorB; } } if (randomVector()) { if (pC) { pC->next = new Set(indexToMember(i)); pC = pC->next; } else { vectorC = new Set(indexToMember(i)); pC = vectorC; } } if (randomVector()) { if (pD) { pD->next = new Set(indexToMember(i)); pD = pD->next; } else { vectorD = new Set(indexToMember(i)); pD = vectorD; } } } } void clearAnswerVector() { delete vectorA; vectorA = nullptr; delete vectorB; vectorB = nullptr; delete vectorC; vectorC = nullptr; delete vectorD; vectorD = nullptr; delete vectorF; vectorF = nullptr; } void badInputLoop() { while (cin.fail() || customTestAmount < 0) { cout << "Неправильный ввод, повторите еще раз:" << endl; cin.clear(); cin.ignore(32767, '\n'); cin >> customTestAmount; } } void testInfo() { cout << setprecision(0); cout << "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" << endl; cout << "Из 26 символов может быть составлено " << factorial(length) << " перестановок" << endl; cout << "Сколько программа должна проделать тестов со случайными комбинациями?" << endl; cin >> customTestAmount; badInputLoop(); if (customTestAmount > 0) cout << "Отчеты будут выведены в файл " << filename << endl; else cout << "Тесты не будут проделаны" << endl; } void executeTest() { ofstream output; output.open(filename); for (int i = 0; i < customTestAmount; i++) { clearAnswerVector(); fillVectors(); output << "Множество A: "; outputSetToFile(vectorA, output); output << endl; output << "Множество B: "; outputSetToFile(vectorB, output); output << endl; output << "Множество C: "; outputSetToFile(vectorC, output); output << endl; output << "Множество D: "; outputSetToFile(vectorD, output); output << endl; calculateAnswer(); output << "Ответ: F = "; outputSetToFile(vectorF, output); output << endl; output << '*' << endl; } output.close(); } int main() { setupConsole(); outputGreeting(); input(); while (!isStringCorrect(stringA) || !isStringCorrect(stringB) || !isStringCorrect(stringC) || !isStringCorrect(stringD)) { cout << "Некорректный ввод" << endl; input(); } convertSets(); calculateAnswer(); outputAnswer(); outputDuration(); testInfo(); executeTest(); }