命題の公式の主な範式を求めます

40557 ワード

実装機能:命題式の合式を入力し、式の真値テーブルを求め、その式の主合取パターンと主析取パターンを出力します.
入力:命題式の式
出力:式の主析出パターンと主析出パターンで、出力形式は「mi∨mj;Mi∧Mj」で、極小項と∨記号の間にスペースがあり、極大項と∧記号の間にスペースがある.主解析パターンと主合成パターンの間に「;」区切る前後にそれぞれスペースがあります.永真式の主合取パターンは1,永偽式の主析取パターンは0である.
数式の記号の説明を入力します.
! いいえ、書面記号の「」に相当します.
&と、書面記号の「∧」に相当
|または、書面記号の「∨」に相当する
  • は結合語を含み、書面記号の「→」
  • に相当する.
  • 等価結合語は、書面記号の「↔ ”

  • (前かっこ
    )後括弧の主な考え方:1.接尾辞式(かっこ抜き)2に変換する.いくつの異なる要素(アルファベット)があるか数えて、列挙するときに3を使います.バイナリに変換し、各ビットでアルファベットの付与4を表す.各可能な付与値に基づいて計算結果を計算し、注意を記録する:永真式の主合取パターンは1であり、永偽式の主析取パターンは0である.
    #include 
    #include 
    #include 
    #include 
    using namespace std;
    char in[1000];
    int order[30], value[30] = {
          0 }, as[10000000] = {
          0 }, cnt1 = 0, cnt2 = 0;
    int priority(char op);
    void RPN(int n);
    int e_cnt();
    int cal(int a, int b, char c);
    int rpn_cal();
    int main()
    {
         
    	int ecnt, sum;
    	cin >> in;
    	RPN(strlen(in));//        
    	ecnt = e_cnt();//       
    	sum = pow(2, ecnt);//      
    	for (int i = 0; i < sum; i++)//  
    	{
         
    		int c = i;
    		memset(value, 0, sizeof(value));
    		for (int j = ecnt-1; j >=0; j--)
    		{
         
    			value[j] = c % 2;
    			c /= 2;
    		}
    		int res = rpn_cal();
    		if (res == 1)
    		{
         
    			as[i] = 1;
    			cnt1++;
    		}
    		else
    		{
         
    			as[i] = 0;
    			cnt2++;
    		}
    	}
    	for (int i = 0; i < sum; i++)
    	{
         
    		if (as[i] == 1 && cnt1 > 1)
    		{
         
    			cout << 'm' << i << " " << "∨" << " ";
    			cnt1--;
    		}
    		else if (as[i] == 1 && cnt1 == 1)
    		{
         
    			cout << 'm' << i << " " << ";" << " ";
    		}
    	}
    	if (cnt1 == 0)
    		cout << 0 << " " << ";" << " ";
    	for (int i = 0; i < sum; i++)
    	{
         
    		if (as[i] == 0 && cnt2 > 1)
    		{
         
    			cout << 'M' << i << " " << "∧" << " ";
    			cnt2--;
    		}
    		else if (as[i] == 0 && cnt2 == 1)
    		{
         
    			cout << 'M' << i << endl;
    		}
    	}
    	if (cnt2 == 0)
    		cout << 1 << endl;
    	return 0;
    }
    int priority(char op)//    
    {
         
    	switch (op)
    	{
         
    	case')':return 7;
    	case'!':return 6;
    	case'|':return 5;
    	case'&':return 4;
    	case'-':return 3;
    	case'+':return 2;
    	case'(':return 1;
    	case'#':return 0;
    	default:return -1;
    	}
    }
    void RPN(int n)//        
    {
         
    	int cnt = 0;
    	char post[1000] = {
          0 };
    	stack <char> op;
    	op.push('#');
    	for (int i = 0; i < n; i++)
    	{
         
    		if (priority(in[i]) == -1)
    			post[cnt++] = in[i];
    		else
    		{
         
    			if (in[i] == ')')
    			{
         
    				while (op.top() != '(')
    				{
         
    					post[cnt++] = op.top();
    					op.pop();
    				}
    				op.pop();
    			}
    			else if(in[i] == '(')
    				op.push(in[i]);
    			else
    			{
         
    				if (priority(in[i]) > priority(op.top()))
    					op.push(in[i]);
    				else if (priority(in[i]) == priority(op.top()))
    				{
         
    					post[cnt++] = op.top();
    					op.pop();
    					op.push(in[i]);
    				}
    				else
    				{
         
    					while (priority(in[i]) <= priority(op.top()))
    					{
         
    						post[cnt++] = op.top();
    						op.pop();
    					}
    					op.push(in[i]);
    				}
    			}
    		}
    	}
    	while (priority(op.top()) != 0)
    	{
         
    		post[cnt++] = op.top();
    		op.pop();
    	}
    	for (int i = 0; i < n; i++)
    	{
         
    		in[i] = post[i];
    	}
    }
    int e_cnt()//         
    {
         
    	int a[30] = {
          0 }, ecnt = 0;
    	for (int i = 0; i < strlen(in); i++)
    	{
         
    		if (priority(in[i]) == -1)
    			a[in[i] - 'a']++;
    
    	}
    	for (int i = 0; i < 30; i++)
    	{
         
    		if (a[i])
    		{
         
    			order[i] = ecnt;
    			ecnt++;
    		}
    	}
    	return ecnt;
    }
    int cal(int a, int b, char c)//       
    {
         
    	switch (c)
    	{
         
    		case'&':return a * b;
    		case'|':if(a + b) return 1; else return 0;
    		case'+':return !((a + b) & 1);
    		case'-':if (a == 1 && b == 0) return 0; else return 1;
    	}
    }
    int rpn_cal()
    {
         
    	stack <int> num;
    	for (int i = 0; i < strlen(in); i++)
    	{
         
    		if (priority(in[i]) == -1)
    		{
         
    			int n = order[in[i] - 'a'];
    			num.push(value[n]);
    		}
    		else if (in[i] == '!')
    		{
         
    			int temp = num.top();
    			temp = (temp + 1) & 1;
    			num.pop();
    			num.push(temp);
    		}
    		else
    		{
         
    			int b = num.top();
    			num.pop();
    			int a = num.top();
    			num.pop();
    			int temp = cal(a, b, in[i]);
    			num.push(temp);
    		}
    	}
    	int ans = num.top();
    	num.pop();
    	return ans;
    }