编程作业(4)

因为作业代码涉及隐私,所以文章只提供解题思路和有关拓展,若实在需要源码可以私信

写在前面:

 1,数组的下标和对应的值 --- 是天然的一种数对;
 2,

作业清单:

 作业一: 实现语法树
  
 作业二:计算一个极大数的幂(考虑溢出)
 计算:当A = 2^256 -1,3^N3 < A  5^N5 < A  7^N7 < A 时,N3,N5,N7的最大值
 
 作业三:一道ACM竞赛题的动态规划算法,以前的作业提到过不赘述

作业一:

#include <ctime> 
#include <iostream>

using namespace std;


string str = "(a+b+b)*a";
//string S="(a+b)+b*a";

int L = str.size();
bool Make(string SF) {
	if (SF.size() > L)return false;
	for (int i = 0; i < SF.size() - 1; i++) {
		string LLL = SF.substr(0, 1);
		string RRR = SF.substr(i + 1);
		if (SF[i] == 'E') {
			if (Make(LLL + "T" + RRR))return true;
			if (Make(LLL + "T+E" + RRR))return true;
			continue;
		}
		if (SF[i] == 'T') {
			if (Make(LLL + "F" + RRR))return true;
			if (Make(LLL + "F*T" + RRR))return true;
			continue;
		}
		if (SF[i] == 'F') {
			if (Make(LLL + "a" + RRR))return true;
			if (Make(LLL + "b" + RRR))return true;
			if (Make(LLL + "(E)" + RRR))return true;
			continue;
		}
	}
	return str == SF;
}
bool ThisT(string S);
bool ThisF(string S);

bool ThisE(string S) {
	if (ThisT(S)) return true;
	int L = S.size();
	for (int i = 1; i < L - 1; i++) {
		if (S[i] != '+') continue;
		if (!ThisT(S.substr(0, i))) continue;
		if (ThisE(S.substr(i + 1))) return true;
	}
	return false;
}

bool ThisT(string S) {
	if (ThisF(S)) return true;
	int L = S.size();
	for (int i = 1; i < L - 1; i++) {
		if (S[i] != '*') continue;
		if (!ThisF(S.substr(0, i))) continue;
		if (ThisT(S.substr(i + 1))) return true;
	}
	return false;
}

bool ThisF(string S) {
	if (S == "a") return true;
	if (S == "b") return true;
	int L = S.size();
	if (S[0] != '(') return false;
	if (S[L - 1] != ')') return false;
	return ThisE(S.substr(1, L - 2));

}



//

bool DasT(int Beg, int End);
bool DasF(int Beg, int End);


bool DasE(int Beg, int End) {
	if (DasT(Beg, End)) return true;
	for (int i = Beg + 1; i <= End - 1; i++) {
		if (str[i] != '+') continue;
		if (!DasT(Beg, i - 1)) continue;
		if (DasE(i + 1, End)) return true;
	}
	return false;
}

bool DasT(int Beg, int End) {
	if (DasF(Beg, End)) return true;
	for (int i = Beg + 1; i <= End - 1; i++) {
		if (str[i] != '*') continue;
		if (!DasF(Beg, i - 1)) continue;
		if (DasT(i + 1, End)) return true;
	}

	return false;

}

bool DasF(int Beg, int End) {
	if (Beg == End) return (str[Beg] == 'a') || (str[Beg] == 'b');
	if (str[Beg] != '(') return false;
	if (str[End] != ')') return false;
	return DasE(Beg + 1, End - 1);

}



//

bool EtoT(int Beg, int End);

bool EtoF(int Beg, int End);



bool EtoE(int Beg, int End) {
	if (EtoT(Beg, End)) return true;
	int NB = 0;
	for (int i = Beg; i <= End - 1; i++) {
		char C = str[i];
		if (C == '(') NB++; else if (C == ')' && --NB < 0) return false;
		if (i == Beg || NB > 0 || C != '+') continue;
		if (EtoT(Beg, i - 1) && EtoE(i + 1, End)) return true;
	}
	return false;
}



bool EtoT(int Beg, int End) {
	if (EtoF(Beg, End)) return true;
	int NB = 0;
	for (int i = Beg; i <= End - 1; i++) {
		char C = str[i];
		if (C == '(') NB++; else if (C == ')' && --NB < 0) return false;
		if (i == Beg || NB > 0 || C != '*') continue;
		if (EtoF(Beg, i - 1) && EtoT(i + 1, End)) return true;
	}
	return false;
}



bool EtoF(int Beg, int End) {
	if (Beg == End) return (str[Beg] == 'a') || (str[Beg] == 'b');
	if (str[Beg] != '(') return false;
	if (str[End] != ')') return false;
	return EtoE(Beg + 1, End - 1);
}

/

class Production {
public:
	char left;
	string right;
	void Init(char L, string R) {
		left = L; right = R;
	}
};



class Grammer {
public:
	Production PPP[7];
	bool Run(string Input);
	bool Run(string Input, string Wish);
};

bool Grammer::Run(string Input) {
	string W(1, PPP[0].left);
	return Run(Input, W);
}
bool Grammer::Run(string Input, string Wish) {
	int IS = Input.size();
	int WS = Wish.size();
	if (IS == 0 || WS == 0)return IS == 0 && WS == 0;
	char CFirst = Wish[0];
	if (CFirst != 'E' && CFirst != 'T' && CFirst != 'F') {
		if (Input[0] != CFirst)return false;
		return Run(Input.substr(1, IS - 1), Wish.substr(1, WS - 1));
	}
	for (int i = 0; i < 7; i++) {
		if (PPP[i].left != CFirst)continue;
		if (Run(Input, PPP[i].right + Wish.substr(1, WS - 1)))return true;
	}
	return false;
}


int main(int argc, char** argv) {
	cout << str << endl;
	double start = clock();
	cout << (clock() - start) / CLOCKS_PER_SEC << endl;
	start = clock();

	if (ThisE(str))
		cout << "yes" << endl;
	else cout << "no" << endl;
	cout << (clock() - start) / CLOCKS_PER_SEC << endl;

	if (DasE(0, L - 1))
		cout << "yes" << endl;
	else cout << "no" << endl;
	cout << (clock() - start) / CLOCKS_PER_SEC << endl;

	if (EtoE(0, L - 1))
		cout << "yes" << endl;
	else cout << "no" << endl;
	cout << (clock() - start) / CLOCKS_PER_SEC << endl;

	Grammer GGG;
	GGG.PPP[0].Init('E', "T");
	GGG.PPP[1].Init('E', "T+E");
	GGG.PPP[2].Init('T', "F");
	GGG.PPP[3].Init('T', "F*T");
	GGG.PPP[4].Init('F', "a");
	GGG.PPP[5].Init('F', "b");
	GGG.PPP[6].Init('F', "(E)");
	start = clock();
	if (GGG.Run(str))
		cout << "yes" << endl;
	else cout << "no" << endl;
	cout << (clock() - start) / CLOCKS_PER_SEC << endl;

	return 0;
}

作业二:这里直接使用了暴力写法,用字符串表示极大数,并实现了字符串数字的加减乘除方法

#include <iostream>
#include <string>
using namespace std;
inline int compare(string str1, string str2) {//相等返回0,大于返回1,小于返回-1
	if (str1.size() > str2.size()) return 1; //长度长的整数大于长度小的整数
	else if (str1.size() < str2.size()) return -1;
	else                              return str1.compare(str2); //若长度相等,则头到尾按位比较
}
string SUB_INT(string str1, string str2);
string ADD_INT(string str1, string str2) {//高精度加法
	int sign = 1; //sign 为符号位
	string str;
	if (str1[0] == '-') {
		if (str2[0] == '-') {
			sign = -1;
			str = ADD_INT(str1.erase(0, 1), str2.erase(0, 1));
		}
		else {
			str = SUB_INT(str2, str1.erase(0, 1));
		}
	}
	else {
		if (str2[0] == '-') {
			str = SUB_INT(str1, str2.erase(0, 1));
		}
		else { //把两个整数对齐,短整数前面加0补齐
			string::size_type L1, L2;
			int i;
			L1 = str1.size();
			L2 = str2.size();
			if (L1 < L2) {
				for (i = 1; i <= L2 - L1; i++) str1 = "0" + str1;
			}
			else {
				for (i = 1; i <= L1 - L2; i++) str2 = "0" + str2;
			}
			int int1 = 0, int2 = 0; //int2 记录进位
			for (i = str1.size() - 1; i >= 0; i--) {
				int1 = (int(str1[i]) - '0' + int(str2[i]) - '0' + int2) % 10;
				int2 = (int(str1[i]) - '0' + int(str2[i]) - '0' + int2) / 10;
				str = char(int1 + '0') + str;
			}
			if (int2 != 0) str = char(int2 + '0') + str;
		}
	}
	//运算后处理符号位
	if ((sign == -1) && (str[0] != '0')) str = "-" + str;
	return str;
}
string SUB_INT(string str1, string str2) {//高精度减法
	int sign = 1; //sign 为符号位
	string str;
	int i, j;
	if (str2[0] == '-') {
		str = ADD_INT(str1, str2.erase(0, 1));
	}
	else {
		int res = compare(str1, str2);
		if (res == 0) return "0";
		if (res < 0) {
			sign = -1;
			string temp = str1;
			str1 = str2;
			str2 = temp;
		}
		string::size_type tempint;
		tempint = str1.size() - str2.size();
		for (i = str2.size() - 1; i >= 0; i--) {
			if (str1[i + tempint] < str2[i]) {
				j = 1;
				while (1) {//zhao4zhong1添加
					if (str1[i + tempint - j] == '0') {
						str1[i + tempint - j] = '9';
						j++;
					}
					else {
						str1[i + tempint - j] = char(int(str1[i + tempint - j]) - 1);
						break;
					}
				}
				str = char(str1[i + tempint] - str2[i] + ':') + str;
			}
			else {
				str = char(str1[i + tempint] - str2[i] + '0') + str;
			}
		}
		for (i = tempint - 1; i >= 0; i--) str = str1[i] + str;
	}
	//去除结果中多余的前导0
	str.erase(0, str.find_first_not_of('0'));
	if (str.empty()) str = "0";
	if ((sign == -1) && (str[0] != '0')) str = "-" + str;
	return str;
}
string MUL_INT(string str1, string str2) {//高精度乘法
	int sign = 1; //sign 为符号位
	string str;
	if (str1[0] == '-') {
		sign *= -1;
		str1 = str1.erase(0, 1);
	}
	if (str2[0] == '-') {
		sign *= -1;
		str2 = str2.erase(0, 1);
	}
	int i, j;
	string::size_type L1, L2;
	L1 = str1.size();
	L2 = str2.size();
	for (i = L2 - 1; i >= 0; i--) { //模拟手工乘法竖式
		string tempstr;
		int int1 = 0, int2 = 0, int3 = int(str2[i]) - '0';
		if (int3 != 0) {
			for (j = 1; j <= (int)(L2 - 1 - i); j++) tempstr = "0" + tempstr;
			for (j = L1 - 1; j >= 0; j--) {
				int1 = (int3 * (int(str1[j]) - '0') + int2) % 10;
				int2 = (int3 * (int(str1[j]) - '0') + int2) / 10;
				tempstr = char(int1 + '0') + tempstr;
			}
			if (int2 != 0) tempstr = char(int2 + '0') + tempstr;
		}
		str = ADD_INT(str, tempstr);
	}
	//去除结果中的前导0
	str.erase(0, str.find_first_not_of('0'));
	if (str.empty()) str = "0";
	if ((sign == -1) && (str[0] != '0')) str = "-" + str;
	return str;
}

string DIVIDE_INT(string str1, string str2, int flag) {//高精度除法。flag==1时,返回商; flag==0时,返回余数
	string quotient, residue; //定义商和余数
	int sign1 = 1, sign2 = 1;
	if (str2 == "0") {  //判断除数是否为0
		quotient = "ERROR!";
		residue = "ERROR!";
		if (flag == 1) return quotient;
		else         return residue;
	}
	if (str1 == "0") { //判断被除数是否为0
		quotient = "0";
		residue = "0";
	}
	if (str1[0] == '-') {
		str1 = str1.erase(0, 1);
		sign1 *= -1;
		sign2 = -1;
	}
	if (str2[0] == '-') {
		str2 = str2.erase(0, 1);
		sign1 *= -1;
	}
	int res = compare(str1, str2);
	if (res < 0) {
		quotient = "0";
		residue = str1;
	}
	else if (res == 0) {
		quotient = "1";
		residue = "0";
	}
	else {
		string::size_type L1, L2;
		L1 = str1.size();
		L2 = str2.size();
		string tempstr;
		tempstr.append(str1, 0, L2 - 1);
		for (int i = L2 - 1; i < L1; i++) { //模拟手工除法竖式
			tempstr = tempstr + str1[i];
			tempstr.erase(0, tempstr.find_first_not_of('0'));//zhao4zhong1添加
			if (tempstr.empty()) tempstr = "0";//zhao4zhong1添加
			for (char ch = '9'; ch >= '0'; ch--) { //试商
				string str;
				str = str + ch;
				if (compare(MUL_INT(str2, str), tempstr) <= 0) {
					quotient = quotient + ch;
					tempstr = SUB_INT(tempstr, MUL_INT(str2, str));
					break;
				}
			}
		}
		residue = tempstr;
	}
	//去除结果中的前导0
	quotient.erase(0, quotient.find_first_not_of('0'));
	if (quotient.empty()) quotient = "0";
	if ((sign1 == -1) && (quotient[0] != '0')) quotient = "-" + quotient;
	if ((sign2 == -1) && (residue[0] != '0')) residue = "-" + residue;
	if (flag == 1) return quotient;
	else         return residue;
}


string powerSimple(string number, int b) {
	

	string res = "1";
	for (int i = b; i > 0; i--) {
		res = MUL_INT(res, number);
	}

	return res;

}

string downPowerSimple(string number, string down) {

	string res = "0";
	
	while (number != "1") {
		number = DIVIDE_INT(number, down, 1);
		res = ADD_INT(res, "1");
	}


	return res;

}


int main() {
	char ch;
	string s1, res, N3, N5, N7;
	int s2;
	/* 供调用
	while (cin >> s1 >> ch >> s2) {
		switch (ch) {
		case '^':res = powerSimple(s1, s2); break;
		case '^^':res2 = downPowerSimple(s1, s2); break;
		default:                   break;
		}
		cout << res << endl;
		
	}*/

	// 计算作业的值
	res = powerSimple("2", 256);
	res = SUB_INT(res, "1");
	N3 = downPowerSimple(res, "3");
	N5 = downPowerSimple(res, "5");
	N7 = downPowerSimple(res, "7");

	cout << res << endl;
	cout << "N3:\t" << N3 << endl << "N5:\t"<< N5 << endl << "N7:\t" << N7 << endl;
	
	return(0);
}

作业三:二维DP

using namespace std;
#include<stdio.h>
#include<iostream>


class Bilety {
private:
	int Max;
	int Arr[100];
public:
	Bilety() { Max = 0; Arr[0] = 1;}
	Bilety(const Bilety& B) { init(B); }
	void init(const Bilety& B);
	void init6();
	void init10();
	void print();
	void Mult(const Bilety& B1, const Bilety& B2);
	void Mult(const Bilety& B);
	
};


void Bilety::init(const Bilety& B){
	Max = B.Max;    // 构造函数中涉及自己本身的属性可以不添加this->
	for (int i = 0; i <= Max; i++) Arr[i] = B.Arr[i];
}

void Bilety::print(){
	for (int i = 0; i <= Max; i++) cout << i << ":" << Arr[i] << " ";
}

void Bilety::init6() {
	Max = 6;
	Arr[0] = 0;
	for (int i = 1; i <= Max; i++) Arr[i] = 1;
}

void Bilety::init10() {
	Max = 9;
	for (int i = 0; i <= Max; i++) Arr[i] = 1;
}

void Bilety::Mult(const Bilety& B1, const Bilety& B2) {
	Max = B1.Max + B2.Max;
	for (int i = 0; i <= Max; i++) Arr[i] = 0;
	
	for (int i1 = 0; i1 <= B1.Max; i1++)
		for (int i2 = 0; i2 <= B2.Max; i2++)
			Arr[i1 + i2] += B1.Arr[i1] * B2.Arr[i2];
}

void Bilety::Mult(const Bilety& B) {
	int MaxT = Max + B.Max;
	int ArrT[100];
	for (int i = 0; i <= MaxT; i++) ArrT[i] = 0;

	for (int i1 = 0; i1 <= Max; i1++)
		for (int i2 = 0; i2 <= B.Max; i2++)
			ArrT[i1+i2] += Arr[i1] * B.Arr[i2];

	Max = MaxT;
	for (int i = 0; i <= MaxT; i++)
		Arr[i] = ArrT[i];



}


Bilety PowerSimple(Bilety& A, int b) {
	int Degree2[5] = { 1,2,4,8,16};
	Bilety DegreeA[5];
	DegreeA[0] = A;
	for (int i = 1; i < 5; i++) { DegreeA[i].Mult(DegreeA[i - 1],DegreeA[i - 1]);}

	Bilety res;
	for (int i = 4; i >= 0; i--) {
		if (Degree2[i] > b) continue;
		b -= Degree2[i];
		res.Mult(DegreeA[i]);
	}

	return res;

}

Bilety Power(Bilety& B, int b) {
	Bilety res;
	Bilety m(B);
	for (;;) {
		if (b == 0) return res;
		if (b % 2) res.Mult(m);
		m.Mult(m);
		b /= 2;
	}




}


int main() {
	Bilety B; B.print(); cout << endl;
	Bilety B1(B); B1.init6(); B1.print(); cout << endl;
	Bilety B2; B2.init10(); B2.print(); cout << endl;  cout << endl;

	//B1.Mult(B2); B1.print(); cout << endl;

	Bilety B4 = PowerSimple(B1,2); B4.print(); cout << endl;
	Bilety B5 = Power(B1, 11); B5.print(); cout << endl;


	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值