求一个命题公式的主析取(合取)范式

时间:2024-03-11 16:46:22

这是大二学离散数学的时候写的, 在这里留个档吧, 算是回忆...

代码各种乱, 不改了.

 1 /* header.h
 2  *author : jackiesteed
 3  *内容: 给定一个命题公式, 可以求出该公式的主吸取范式和主合取范式, 思路也比较简单, 就是暴力写的.
 4  **/
 5 #include <string>
 6 #include <stack>
 7 #include <vector>
 8 #include<iostream>
 9 using namespace std;
10 
11 
12 
13 class formulaBase
14 {
15 private:
16     static const int MAXN = 110;
17     int numVar;//记录范式中的变量
18     bool variables[MAXN];//存储变量
19     //3个string分别存储源串,合取, 析取串
20     string sourceFormula;
21     string normalCFormula;
22     string normalDFormula;
23     string dualFormula;
24 
25     vector<char> vctofVar;
26     vector<char> vctofPoland;
27     stack<char> stk;
28     bool isVar(char ch)const;
29     void addMin(int  minterm);
30     void addMax(int maxterm);
31     bool  compute(int minterm);
32     void getInversePoland();
33     int countTerms(int n);
34     void assign(int minterm);
35     stack<bool> boolStk;
36 public:
37     formulaBase();
38     formulaBase(const formulaBase& rhs);
39     ~formulaBase();
40     void getSource();
41     string generateNormalC();
42     string generateNormalD();
43     string getDual();
44     void printSource()
45     {
46         cout<<sourceFormula<<endl;
47     }
48     void printDNormal()
49     {
50         cout<<normalDFormula<<endl;
51     }
52     void printCNormal()
53     {
54         cout<<normalCFormula<<endl;
55     }
56     void printDual()
57     {
58         cout<<dualFormula<<endl;
59     }
60     void printTruthTable();
61 //void printTruthTable();
62 
63 
64 
65 
66 
67 };

 

  1 /* main.cpp
  2  * auther: jackiesteed
  3  **
  4  **/
  5 #include <iostream>
  6 #include <fstream>
  7 #include <cstdlib>
  8 
  9 #include "header.h"
 10 
 11 
 12 formulaBase::formulaBase()
 13 {
 14     for(int i=0; i<MAXN; i++)
 15         variables[i]=false;
 16 
 17     numVar=0;
 18 }
 19 formulaBase::formulaBase(const formulaBase& rhs)
 20 {
 21     sourceFormula=rhs.sourceFormula;
 22     for(int i=0; i<100; i++)
 23         variables[i]=false;
 24     numVar=0;
 25 }
 26 formulaBase::~formulaBase()
 27 {
 28 
 29     while(!stk.empty())stk.pop();
 30     vctofVar.clear();
 31     vctofPoland.clear();
 32 }
 33 int formulaBase::countTerms(int n)
 34 {
 35     if(n==0)
 36     {
 37         cout<<"invalid input!"<<endl;
 38         exit(0);
 39     }
 40     switch(n)
 41     {
 42     case 1:
 43         return 2;
 44     case 2:
 45         return 4;
 46     default:
 47     {
 48         int tempA=2,tempB=2;
 49         int i;
 50         for(i=2; i<=n; i*=2)tempA*=tempA;
 51         i/=2;
 52         if(i==n)return tempA;
 53         i=n-i;
 54         int j;
 55         for(j=2; j<=i; j*=2)tempB*=tempB;
 56 
 57         for(j/=2; j<i; j++)tempB*=2;
 58         tempB*=tempA;
 59         return tempB;
 60     }
 61     }
 62 
 63 
 64 }
 65 bool formulaBase::isVar(char ch)const
 66 {
 67     if (ch>=\'A\'&&ch<=\'Z\')
 68         return true;
 69     return false;
 70 }
 71 void formulaBase::getSource()
 72 {
 73     cout<<"Input the source formula:"<<endl;
 74     cin>>sourceFormula;
 75     /*if(!isValid(sourceFormula))
 76     cout<<"Invalid input !"
 77     "Operate again:"<<endl;
 78     cin>>sourceFormula;*/
 79     //cout << sourceFormula << endl;
 80 
 81 }
 82 void formulaBase::getInversePoland()
 83 {
 84 
 85     wchar_t temp,temp1;
 86     int len = sourceFormula.size();
 87     for(int i=0; i < len; i++)
 88     {
 89         temp=sourceFormula[i];
 90         //putchar(temp);
 91         if(isVar(temp))
 92         {
 93             if(!variables[temp])
 94             {
 95                 numVar++;
 96                 vctofVar.push_back(temp);
 97                 variables[temp]=true;
 98             }
 99             vctofPoland.push_back(temp);
100         }
101         else
102             switch(temp)
103             {
104 //            case\'→\':
105 //            case\'↑\':
106 //            case\'↓\':
107 //            case\'⊕\':
108 //            case\'⊙\':
109 //                while(!stk.empty())
110 //                {
111 //                    if(stk.top()==temp)
112 //                    {
113 //                        vctofPoland.push_back(temp);
114 //                        stk.pop();
115 //                    }
116 //                    else break;
117 //                }
118 //                stk.push(temp);
119 //                break;
120             case \'(\':
121             case \'!\':
122                 stk.push(temp);
123                 break;
124             case \'+\':
125                 while (!stk.empty())
126                 {
127                     if(stk.top()!=\'(\')
128                     {
129                         temp1=stk.top();
130                         vctofPoland.push_back(temp1);
131                         stk.pop();
132                     }
133                     else break;
134                 }
135                 stk.push(temp);
136                 break;
137             case \'*\':
138                 while (!stk.empty())
139                 {
140                     temp1=stk.top();
141                     if(stk.top()==\'*\'||stk.top()==\'!\')
142                     {
143                         vctofPoland.push_back(temp1);
144                         stk.pop();
145                     }
146                     else
147                         break;
148                 }
149                 stk.push(temp);
150                 break;
151 
152             case \')\':
153                 while (!stk.empty())
154                 {
155                     if(stk.top()!=\'(\')
156                     {
157                         temp1=stk.top();
158                         vctofPoland.push_back(temp1);
159                         stk.pop();
160                     }
161                     else break;
162                 }
163                 if(stk.empty())exit(0);
164                 stk.pop();//pop the operator \'(\'
165 
166                 break;
167 
168             }
169     }
170     while(!stk.empty())
171     {
172         temp1=stk.top();
173         vctofPoland.push_back(temp1);
174         stk.pop();
175     }
176 }
177 void formulaBase::assign(int minterm)
178 {
179     int temp=minterm;
180 
181     for(vector<char>::const_iterator itr=vctofVar.begin(); itr!=vctofVar.end(); itr++)
182     {
183 
184         variables[(int)*itr]=bool(temp&1);
185         temp=temp>>1;
186     }
187 
188 }
189 
190 bool formulaBase::compute(int minterm)
191 {
192     assign(minterm);
193     wchar_t temp;
194     bool valueA,valueB;
195     vector<char>::const_iterator itr=vctofPoland.begin();
196     while (itr!=vctofPoland.end())
197     {
198         temp=*itr;
199         if(isVar(temp))boolStk.push(variables[temp]);
200         else
201             switch(temp)
202             {
203                 case \'+\':
204                 {
205                     if(boolStk.size()<2)exit(0);
206                     valueA=boolStk.top();
207                     boolStk.pop();
208                     valueB=boolStk.top();
209                     boolStk.pop();
210                     valueA=valueA||valueB;
211                     boolStk.push(valueA);
212                     break;
213 
214                 }
215 
216                 case \'*\':
217                 {
218                     if(boolStk.size()<2)exit(0);
219                     valueA=boolStk.top();
220                     boolStk.pop();
221                     valueB=boolStk.top();
222                     boolStk.pop();
223                     valueA=valueA&&valueB;
224                     boolStk.push(valueA);
225                     break;
226 
227                 }
228 
229                 case \'!\':
230                 {
231                     if(boolStk.empty())exit(0);
232                     valueA=!(boolStk.top());
233                     boolStk.pop();
234                     boolStk.push(valueA);
235                     break;
236 
237                 }
238 
239 //            case\'→\':
240 //            {
241 //                if(boolStk.size()<2)exit(0);
242 //                valueA=boolStk.top();
243 //                boolStk.pop();
244 //                valueB=boolStk.top();
245 //                boolStk.pop();
246 //                valueA=(!valueA)||valueB;
247 //                boolStk.push(valueA);
248 //
249 //            }
250 //            break;
251 //            case\'↑\':
252 //            {
253 //                if(boolStk.size()<2)exit(0);
254 //                valueA=boolStk.top();
255 //                boolStk.pop();
256 //                valueB=boolStk.top();
257 //                boolStk.pop();
258 //                valueA=!(valueA&&valueB);
259 //                boolStk.push(valueA);
260 //
261 //            }
262 //            break;
263 //            case\'↓\':
264 //            {
265 //                if(boolStk.size()<2)exit(0);
266 //                valueA=boolStk.top();
267 //                boolStk.pop();
268 //                valueB=boolStk.top();
269 //                boolStk.pop();
270 //                valueA=!(valueA||valueB);
271 //                boolStk.push(valueA);
272 //
273 //            }
274 //            break;
275 //            case\'⊕\':
276 //            {
277 //                if(boolStk.size()<2)exit(0);
278 //                valueA=boolStk.top();
279 //                boolStk.pop();
280 //                valueB=boolStk.top();
281 //                boolStk.pop();
282 //                valueA=(!valueA&&valueB)||(valueA&&!valueB);
283 //                boolStk.push(valueA);
284 //
285 //            }
286 //            break;
287 //            case\'⊙\':
288 //            {
289 //                if(boolStk.size()<2)exit(0);
290 //                valueA=boolStk.top();
291 //                boolStk.pop();
292 //                valueB=boolStk.top();
293 //                boolStk.pop();
294 //                valueA=(valueA&&valueB)||(!valueA&&!valueB);
295 //                boolStk.push(valueA);
296 //
297 //            }
298 //            break;
299 
300 
301 
302             }
303         itr++;
304     }
305     if(boolStk.size()!=1)
306     {
307         cout<<"Error in computing the value of minterm"<<endl;
308         exit(0);
309     }
310     valueA=boolStk.top();
311     boolStk.pop();
312     return valueA;
313 
314 
315 }
316 void formulaBase::addMin(int minterm)
317 {
318 //    int temp=minterm;
319     vector<char>::const_iterator itr=vctofVar.begin();
320     normalCFormula+=\'(\';
321     while (itr!=vctofVar.end())
322     {
323         if(!variables[(int)*itr])
324             normalCFormula+=\'!\';
325         normalCFormula+=*itr;
326         normalCFormula+=\'*\';
327         itr++;
328 
329     }
330     normalCFormula+="\b)+";
331 }
332 void formulaBase::addMax(int maxterm)
333 {
334 //    int temp=maxterm;
335     vector<char>::const_iterator itr=vctofVar.begin();
336     normalDFormula+=\'(\';
337     while (itr!=vctofVar.end())
338     {
339         if( variables[(int)*itr])
340             normalDFormula+=\'!\';
341         normalDFormula+=*itr;
342         normalDFormula+=\'+\';
343         itr++;
344 
345     }
346     normalDFormula+="\b)*";
347 }
348 
349 //获取主合取范式
350 string formulaBase::generateNormalC()
351 {
352     if(vctofPoland.size()==0)//This operation has not been done yet!
353         getInversePoland();
354 //    cout<<"Here!"<<endl;
355     int n=countTerms(numVar);
356 //    cout<<n<<"countTerms"<<endl;
357     normalCFormula=\' \';
358     for(int i=0; i<n; i++)
359     {
360         if(compute(i))addMin(i);
361 
362     }
363     normalCFormula+="\b ";
364     return normalCFormula;
365 
366 }
367 
368 //获取主析取范式
369 string formulaBase::generateNormalD()
370 {
371     if(vctofPoland.size()==0)//This operation has not been done yet!!
372         getInversePoland();
373     int n=countTerms(numVar);
374     normalDFormula=\' \';
375     for(int i=0; i<n; i++)
376     {
377         if(!compute(i))addMax(i);
378     }
379     normalDFormula+="\b ";
380     return normalDFormula;
381 
382 }
383 
384 //获取对偶范式, ans = !f, 例如 !(a+b) == !a * !b
385 string formulaBase::getDual()
386 {
387 
388     int len = sourceFormula.size();
389     char temp;
390     dualFormula="";
391     for(int i = 0; i < len; i++)
392     {
393         temp = sourceFormula[i];
394         switch(temp)
395         {
396         case \'!\':
397         {
398             i++;
399             dualFormula+=sourceFormula[i];
400             break;
401         }
402         case \'+\':
403             dualFormula+=\'*\';
404             break;
405         case \'*\':
406             dualFormula+=\'+\';
407             break;
408 
409         case\'(\':
410         case \')\':
411             dualFormula+=sourceFormula[i];
412             break;
413         default:
414             if (isVar(temp))
415             {
416                 dualFormula+=\'!\';
417                 dualFormula+=temp;
418             }
419             else
420             {
421                 cout<<"Error in generatint Dual Formula!"<<endl;
422                 exit(0);
423             }
424             break;
425         }
426     }
427     return dualFormula;
428 }
429 //void formulaBase::printTruthTable()//A const function is unable to call a nonconst function!!!
430 //{
431 //    int i=0;
432 //    int count=countTerms(numVar);
433 //    cout<<"                      TRUTH TABLE                          \n";
434 //    for(  i=0; i<=numVar; i++)cout<<"___";
435 //    cout<<endl;
436 ////for( i=0;i<numVar;i++)cout<<\'|\'<<vctofVar[i];
437 ////cout<<"|F|" <<endl;
438 //    for(  i=0; i<=numVar; i++)cout<<"___";
439 //    cout<<endl;
440 //    for(i=0; i<count; i++  )
441 //    {
442 //        int temp=i;
443 //        for(int j=0; j<numVar; j++)
444 //        {
445 //            if(bool(temp&1))cout<<"|1";
446 //            else cout<<"|0";
447 //            temp=temp>>1;
448 //        }
449 //        if(this->compute(i))cout<<"|1";
450 //        else cout<<"|0";
451 //        cout<<\'|\'<<endl;
452 //        for( int k=0; k<=numVar; k++)cout<<"___";
453 //        cout<<endl;
454 //    }
455 //
456 //}
457 
458 int main()
459 {
460 //    freopen("input.txt", "r", stdin);
461 //变量使用单个的大写字母表示...
462 
463     formulaBase fb;
464     fb.getSource();
465     cout << "主合取范式是:";
466     cout << fb.generateNormalC() << endl;
467     cout << "主吸取范式是:";
468     cout << fb.generateNormalD() << endl;
469 
470 
471 
472     return 0;
473 }