因为作业代码涉及隐私,所以文章只提供解题思路和有关拓展,若实在需要源码可以私信
写在前面:
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;
}