-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSetCalc.cpp
208 lines (186 loc) · 6.96 KB
/
SetCalc.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
//
// Created by tuli on 07/11/2020.
#include "SetCalc.h"
SetCalc::SetCalc()
:NAMERR2("ERROR: "), NAMERR(" does not exist"),SIZERR("ERROR: group has more than 10 elements"),INPERR("ERROR: invalid input"),CMDRR("ERROR: invalid command; type 0 for exit")
{}
int SetCalc::run() {
string temp;// return value for checking purpose
getline(cin,temp);
stringstream tip(temp);
if (tip.gcount()>1) { cerr << CMDRR << endl ; return 1;} //illegal cmd
unsigned char cmd=tip.get();
cin.clear();
if(!isdigit(cmd)){
cerr << CMDRR << endl;
return 1;
}
cmd=cmd-'0';
switch(cmd){
case(1): //add
if(setAdd()){return 1;}
return 1;
case(2):
if(setDel());
return 2;
case(3):
if (!setUnion()) { return 1;}
return 1;
case(4):
if (setIntersect()) { return 1; }
return 4;
case(5):
if(powerSet()){ return 1; }
return 5;
case(6):
if(!setPrint()){
return 1;}
return 1;
case(0):
if (SetLINKED.isEmpty()) {return 0; }
else { SetLINKED.Destroy(); return 0;}
default:
cerr << CMDRR << endl;
return 1;
}
return 1;
}
int SetCalc::setAdd() {
int elmtSIZE;
string nom;
int *elmts = new int; // temp input array
nom = parsi.parseNameX(false);
if ((nom == "0")) { cerr << INPERR << endl; return 1; } //parse name if illegal return
elmtSIZE = parsi.parseSet(elmts);
if (elmtSIZE == -1) { cerr << INPERR << endl; return 1; } //parse set if illegal return
Set *a = new Set(elmts, elmtSIZE, nom);
if ( SetLINKED.find(a->getName())) { SetLINKED.Replace(a) ;
return 0; }
SetLINKED.append(a);
return 0;
}
int const SetCalc::setPrint() {
string tst;
string nom = parsi.parseNameX(false);
if ((nom == "0")) { cerr << INPERR << endl; return 1; }
LLNode* temp = ( SetLINKED.find(nom));
if (temp) { cout<<temp->getData()->getName()<<"=";
temp->printNod();
cout<<endl;
return 0; }
else { cerr <<NAMERR2<< nom << NAMERR << endl; return 1; }
}
int SetCalc::setIntersect() {
string nom1;
string nom2;
string nomNew;
if( parsi.parse2Name(nom1, nom2) =="0" ){ cerr << INPERR << endl; return 1; }//parsing names
LLNode* bit1 = SetLINKED.find(nom1);
if(!bit1) { cerr <<NAMERR2 << nom1 << NAMERR << endl; return 1;}
LLNode* bit2 = SetLINKED.find(nom2);
if(!bit2) { cerr <<NAMERR2 << nom2 << NAMERR << endl; return 1;}//new name
nomNew = parsi.parseNameX(false);
if ((nomNew == "0")) { cerr << INPERR << endl; return 1; }
int count =0;
int * temps = new int[ max(bit1->getData()->getSize(),bit2->getData()->getSize()) ]; //max size if contained
for (int i=0; i<bit1->getData()->getSize(); i++){ //copying if elm appear in both
for (int j=0; j<bit2->getData()->getSize(); j++){
if ((bit1->getData()->get(i) == (bit2->getData()->get(j)))){
temps[count++] = (bit1->getData()->get(i));
}
}
}
Set* sect = new Set(temps, count, nomNew);
if ( SetLINKED.find ( sect->getName())) { SetLINKED.Replace(sect) ; //if set in list override
return 0; }
SetLINKED.append(sect);
return 0;
}
int SetCalc::setDel(){
string nom;
nom = parsi.parseNameX(false);
if (nom == "0") { cerr << INPERR << endl; return 1; } //searching for element in list by name
LLNode* tmp = ( SetLINKED.find(nom) ) ;
if (!tmp) { cerr << NAMERR2 <<nom<< NAMERR << endl; return 1; }
SetLINKED.del(tmp);
return 0;
}
int SetCalc::setUnion() { // this is union,
string nom1;
string nom2;
string nomNew;
if( parsi.parse2Name(nom1, nom2)=="0") { cerr << INPERR << endl; return 1; } //parsing
LLNode* bit1 = SetLINKED.find(nom1);
if(!bit1) { cerr <<NAMERR2 << nom1 << NAMERR << endl; return 1;}
LLNode* bit2 = SetLINKED.find(nom2);
if(!bit2) { cerr <<NAMERR2 << nom2 << NAMERR << endl; return 1;} //searching for sets in list
nomNew = parsi.parseNameX(false);
if ((nomNew == "0")) {cerr << INPERR << endl; return 1;}
int count = bit1->getData()->getSize()+bit2->getData()->getSize();
int * temps = new int[count]; //max size if unrelated
for ( int i=0; i<bit1->getData()->getSize(); i++ ){ //copying
*temps++ = (bit1->getData()->get(i));
}
for ( int i=0; i<bit2->getData()->getSize(); i++ ){
*temps++ = (bit2->getData()->get(i));
}
temps-=count;
Set* unii = new Set (temps, count, nomNew); //appending new set
if ( SetLINKED.find ( unii->getName()) ) { SetLINKED.Replace(unii) ;
return 0; }
SetLINKED.append(unii);
return 0;
}
int SetCalc::powerSet(){
string nom;
nom = parsi.parseNameX(false);
if((nom == "0")) { cerr << INPERR << endl; return 1; }
LLNode* tmp = SetLINKED.find(nom);
if ((!tmp) || (tmp->getData()->getSize()>10)) { cerr <<NAMERR2 << nom << NAMERR << endl; return 1;}
SetLL* powLink = new SetLL();
Set* subset = new Set(); //powerset function creates a new linked list just for the power set
Set* OGset = tmp->getData();
const int Oshel = pow(2.0,OGset->getSize());
powerSetLLHelper(OGset, subset, powLink, 0 ); //helper function calculates subsets recursivly
powLink->gotoBeginning();
Set* powArr = new Set[Oshel]; //linked list copied to a new array of known size
for (int i=0; i<Oshel; i++){
powArr[i] = *powLink->getCurr()->getData();
powLink->gotoNext();
}
powerSort(powArr,Oshel); //sorting function sorts array sorting array is easy and cheaper to sorting a linked list
cout << "P("<<OGset->getName()<<")={"; //printings set of sets
for (int i=0; i<Oshel; i++){
powArr[i].printSet();
if (i<Oshel-1) cout<<",";
}
cout<<"}"<<endl;
powLink->Destroy();
delete[] powArr; //free memory
return 0;
}
int SetCalc::powerSetLLHelper(Set *&given_set, Set *&subset, SetLL*& powLink, int index){
if (index >= given_set->getSize()) { //recursion iterates over index, if reached add to list
Set* T = new Set(*subset);
powLink->append(T); powLink->gotoPrior(); return 0;} //for every item in OG set there are two subsets in a power set
else {
powerSetLLHelper(given_set, subset, powLink,index+1); //one subset is a set with the item
subset->add(given_set->get(index));
powerSetLLHelper(given_set, subset, powLink,index+1); //and one without the item
subset->pop();
}
return 0;
}
void SetCalc::powerSort(Set *&arr, int Oshel){
int i, j;
Set key;
for (i = 1; i < Oshel; i++){ //sorting function for set, using insertion sort,
key = arr[i];
j = i - 1;
while (j >= 0 && arr[j] < key){ //set operator '<' helps us use this sorting algorithm naturally
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
}