Demo entry 6662204

sugar

   

Submitted by anonymous on Nov 25, 2017 at 11:06
Language: C++. Code size: 6.9 kB.

#include <iostream>
#include <stack>
#include <iomanip>
#include <string>
using namespace std;

string item;
bool a[100] = { 0 };
int flag = 1;

/**
*判断当前字符是否为数字
*/
bool isNumber(char s) {
	string opers = "/>*+()";
	for (int i = 0; i < opers.length(); i++) {
		if (s == opers.at(i)) {
			return false;
		}
	}
	return true;
}

/**
* 判断当前运算符与栈顶运算符的优先级大小
*/
bool isPriorityLow(char currOper, char topOper) {
	if (currOper == '*' || currOper == '+')
		if (topOper == '/')
			return true;


	if (currOper == '>')
		if (topOper == '*' || topOper == '+' || topOper == '/')
			return true;

	if (currOper == '*' || currOper == '+')
		if (topOper == '*' || topOper == '+')
			return true;

	if (currOper == '>')
		if (topOper == '>')
			return true;

	if (currOper == '/')
		if (topOper == '/')
			return true;

	return false;
}

/**
* 如果当前运算符优先级小于或等于栈顶运算符, 将栈顶运算符弹出加到后缀表达式尾,
* 并继续进行比较, 直到当前运算符优先级大于栈顶运算符优先级
*/
void loopPushOperator(string& s, char oper, stack<char>& operators) {
	if (operators.size() > 0 && isPriorityLow(oper, operators.top())) {
		s += operators.top();
		operators.pop();
		loopPushOperator(s, oper, operators);
	}
}

/**
* 判断运算符是压入运算符栈还是加到后缀表达式尾
*/
void handleOperator(string& s, char oper, stack<char>& operators) {
	switch (oper) {
	case '/':
	case '*':
	case '+':
	case '>':
		//如果运算符栈为空, 直接将当前运算符压栈 1→1┐0
		if (operators.size() <= 0) {
			operators.push(oper);
			//如果当前运算符优先级小于等于栈顶运算符优先级, 将栈顶运算符加到后缀表达式尾
		}
		else if (isPriorityLow(oper, operators.top())) {
			loopPushOperator(s, oper, operators);
			operators.push(oper);
			///如果当前运算符优先级大于栈顶运算符优先级, 将当前运算符压栈
		}
		else {
			operators.push(oper);
		}
		break;
	case '(':
		operators.push(oper);  //当前运算符为'('直接压栈
		break;
	case ')':
		//将栈中元素弹出加到后缀表达式尾,直到遇到运算符"("
		while (operators.top() != '(') {
			s += operators.top();
			operators.pop();
		}
		operators.pop();
		break;
	default:
		break;
	}
}

/**
* 中缀表达式转后缀表达式
*/
string infixToSuffix(string& s) {
	stack<char> operators;     //运算符栈
	string suffix;                        //后缀表达式

	for (int i = 0; i < s.length(); i++) {
		if (isNumber(s.at(i))) {   //如果是数字直接加到后缀表达式尾
			item += s.at(i);
			suffix += s.at(i);
		}
		else {

			handleOperator(suffix, s.at(i), operators);  //处理运算符
		}
	}


	if (suffix.length() > 0) {
		while (operators.size() > 0) {  //将运算符栈中留有的运算符全部出栈加到后缀表达式尾
			suffix += operators.top();
			operators.pop();
		}
		return suffix;
	}
	else {
		return "";
	}
}

/**
* 根据运算符,计算栈顶两个数的值,并将计算的值压栈
*/
void CalculateResult(char oper, stack<int>& tmpStack) {
	if (tmpStack.size() < 1) {
		return;
	}
	if (tmpStack.size() == 1 && oper == '/') {
		int temp = tmpStack.top();
		tmpStack.pop();
		tmpStack.push(!temp);
		return;
	}
	//栈是先进后出,所以先弹出的是第二个值
	int secondVal = tmpStack.top();
	tmpStack.pop();
	int firstVal = tmpStack.top();
	tmpStack.pop();

	int result = 0;
	switch (oper) {
	case '>':
	{
		result = (!firstVal || secondVal);
	}
	break;
	case '/':
	{
		result = !secondVal;
		tmpStack.push(firstVal);
		break;
	}

	case '*':
	{
		result = firstVal && secondVal;
	}
	break;
	case '+':
		result = firstVal || secondVal;
		break;
	default:
		break;
	}

	tmpStack.push(result);
}

/**
* 通过后缀表达式计算结果
* 将后缀表达式依次入栈, 如果为操作符, 弹出栈中两个元素计算结果再压入栈中
*/
float getResultUseSuffix(string& s) {
	if (s.length() <= 0) {
		return 0;
	}

	stack<int> tmpStack;
	for (int i = 0; i < s.length(); i++) {
		if (isNumber(s.at(i))) {
			tmpStack.push(s.at(i) - '0');
		}
		else {
			CalculateResult(s.at(i), tmpStack);
		}
	}
	return tmpStack.top();
}

//打印主合取主析取范式
void print(bool a[], int q) {
	cout << "主析取范式:";
	int i = 0;
	int sign = 0;

	for (i = 0; i < q; i++)
		if (a[i] == 1)
			if (sign == 0)
			{
				cout << "M" << i;
				sign = 1;
			}
			else
				cout << "+" << "M" << i;

	sign = 0;
	cout << endl;
	cout << "主合取范式:";
	for (int i = 0; i < q; i++)
		if (a[i] == 0)
			if (sign == 0)
			{
				cout << "m" << i;
				sign = 1;
			}
			else
				cout << "+" << "m" << i;
	cout << endl;
	cout << endl;

}
void func1() {
	cout << "请输入两个命题变元P和Q的真值:";
	int sign = 1;
	char p, q;
	cin >> p >> q;

	while (p > '1' || p < '0' || q > '1' || q < '0')
	{
		if (p == 't')
		{
			cout << endl;
			return;
		}
		cout << "输入错误,请重新输入两个命题变元P和Q的真值" << endl;
		cin >> p >> q;
	}//输入错误判断

	bool P, Q;
	P = p - '0';
	Q = q - '0';
	cout << endl;

	cout << " " << std::left << setw(10) << "真值" << setw(10) << "真值" << setw(10) << "合取" << setw(10) << "析取" << setw(10) << "蕴含" << setw(10) << "等价" << endl;
	cout << "  " << std::left << setw(10) << "P" << setw(8) << "Q" << setw(10) << "(P∧Q)" << setw(11) << "(P∨Q)" << setw(11) << "P->Q" << setw(10) << "P=Q" << endl;
	cout << "  " << std::left << setw(10) << P << setw(10) << Q << setw(10) << (P&&Q) << setw(10) << (P || Q) << setw(10) << (!P || Q) << setw(10) << (P == Q) << endl;
	cout << endl;

}
int main() {
	
	while (1) {
		cout << "选择功能:1.求两个命题变量P和Q的合取、析取、蕴涵和等价的真值." << endl;
		cout << "          2.求命题公式的真值表和主范式" << endl;
		int option;
		cin >> option;
		if (option == 1) {
			func1();
		}
		else {
			item = "";
			cout << "*****'/'代表'┐'*****" << endl;
			cout << "     '*'代表'∧'     " << endl;
			cout << "     '+'代表'∨'     " << endl;
			cout << "     '>'代表'->'     " << endl;
			cout << endl;
			cout << "请输入命题公式:";
			string infix;
			int hi = 1;
			while (cin >> infix) {
				for (int i = 0; i < infix.size(); i++)
					if (infix[i] >= 'a' && infix[i] <= 'z' || infix[i] >= 'A' && infix[i] <= 'Z' || infix[i] == '/' || infix[i] == '*' || infix[i] == '+' || infix[i] == '>' || infix[i] == '(' || infix[i] == ')')
						hi = 0;
					else
					{
						cout << "输入表达式有误,请重新输入:";
						hi = 1;
						break;
					}
				if (hi == 0)
					break;
			}
			string suffix = infixToSuffix(infix);
			bool ans[100] = { 0 };
			for (int i = 0; i < item.size(); i++)
				cout << std::left << setw(2) << item[i];
			cout << "  ";
			for (int i = 0; i < infix.size(); i++)
				cout << infix[i];
			cout << endl;

			int k = item.size()-1, q = 0;
			int count = pow(2, item.size());
			for(int j =0; j <count; j++) {

				k = item.size()-1;
				int sum = j;
				while (sum != 0)
				{
					a[k--] = sum % 2;
					sum /= 2;
				}//二进制模拟
				if (k >= 0) {
					for (int i = k; i > 0; i--)
						a[k--] = 0;
				}
				int m = 0;
				for (int i = 0; i < suffix.size(); i++)
					if (isNumber(suffix[i])) {
						suffix[i] = a[m++] + '0';
					}
				for (int i = 0; i < item.size(); i++)
					cout << a[i] << " ";
				cout << "   ";
				int result = getResultUseSuffix(suffix);

				ans[q++] = result;
				cout << result << endl;
				cout << endl;		

			}
			print(ans, q);
			
		}
	}
	return 0;
}

This snippet took 0.03 seconds to highlight.

Back to the Entry List or Home.

Delete this entry (admin only).