问题标题: 酷町堂:Coding.lin 1.0

2
1
已解决
李致远
李致远
高级光能
高级光能
#include <cmath>
#include <Windows.h>
#include <bits/stdc++.h>
#include <iostream>
#include <string>
#include <windows.h>
#include <stdlib.h>
#include <fstream>
#include <sys/time.h>
#include <cstdlib>
#include <ctime>
#include <string.h>
#include <conio.h>
#include <iomanip>
#include <stdio.h>
#include <iterator>
using namespace std;
const char NUM[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.'};
const char OPERATION[] = {'+', '-', '*', '/'};
const double PI = 3.14159265358979;
const double EE = 2.71828182818281;
void cursor(bool a) {
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO CursorInfo;
	GetConsoleCursorInfo(handle, &CursorInfo);
	CursorInfo.bVisible = a;
	SetConsoleCursorInfo(handle, &CursorInfo);
}
class Fun { //处理系统数学函数的类
	public:
		Fun(string o, int t, double l = 0.0, double r = 0.0): op(o), type(t), lvalue(l), rvalue(r) {}
		static string FUN[];
		double calc();
	private:
		int type; //666 0 1 sin90 2 3! 3 3C2
		string op; //函数类型
		double lvalue; //函数左边的值
		double rvalue; //函数右边的值
		static int FunNum;
};
int Fun::FunNum = 10;
string Fun::FUN[] = {"!", "sin", "cos", "tan", "log", "ln", "C", "A", "^", "-"};
/*
函数说明:
1:log是以10为底的工程对数
2:ln 是以e为底的自然对数
3:C 计算组合数 输入规则 如计算 3取2的组合 输入表达式 3C2
4:A 计算排列数 输入规则 如计算 3取2的排列 输入表达式 3A2
5:! 计算阶乘
6:^ x的y次方 输入 x^y
*/
int factorial(int n) { //阶乘函数
	int i, s = 1;

	for(i = 1; i <= n; i++)
		s *= i;

	return s;
}
int C(int a, int b) {
	return factorial(a) / (factorial(b) * factorial(a - b));
}
int A(int a, int b) {
	return factorial(a) / factorial(b);
}
double Fun::calc() { //计算系统函数的值
	if(type == 0)
		return lvalue;
	else {
		if(op == "!")
			return factorial(lvalue);

		if(op == "sin")
			return sin(rvalue / 180 * PI);

		if(op == "cos")
			return cos(rvalue / 180 * PI);

		if(op == "tan")
			return tan(rvalue / 180 * PI);

		if(op == "log")
			return log10(rvalue);

		if(op == "ln")
			return log10(rvalue) / log10(EE);

		if(op == "C")
			return C(lvalue, rvalue);

		if(op == "A")
			return A(lvalue, rvalue);

		if(op == "^")
			return pow(lvalue, rvalue);

		if(op == "-")
			return -rvalue;
		else {
			string err = "暂时没有函数" + op;
			MessageBox(NULL, err.c_str(), "错误", MB_OK);
			return 0;
		}
	}
}
struct Unit { //双向链表保存运算单元
	Unit(int p, char o, string c, double v, int t, Unit * pr = NULL, Unit * n = NULL)
		: PRI(p), Operation(o), Code(c), value(v), Type(t), Pre(pr), Next(n) {}
	int PRI; //优先级
	char Operation; //操作符
	string Code; //原始代码
	double value; //数据
	int Type; //类型 操作符0 数据1 函数2
	Unit * Pre; //构成双向链表
	Unit * Next;
};
class Node { //表达式树状结构的节点
	public:
		Node(char o, int p, int e = 1, double v = 0, Node * ph = NULL, Node * pl = NULL, Node * pr = NULL)
			: Operation(o), PRI(p), Expression(e), value(v), Head(ph), Left(pl), Right(pr) {}
		Node * Head; //节点的根,左树枝,右树枝
		Node * Left;
		Node * Right;
		double GetValue();
		char GetOperation() const {
			return Operation;
		}
		int GetPri() const {
			return PRI;
		}
		int IsExp() const {
			return Expression;
		}
	private:
		char Operation; //操作符
		int PRI; //优先级
		int Expression; //记录该节点是否是表达式0 1
		double value; //该节点的值
};
double Node::GetValue() { //运算该节点的值
	if(IsExp()) { //该节点的值还未算出来
		double lvalue, rvalue;
		lvalue = Left->GetValue();
		rvalue = Right->GetValue();
		Expression = 0;
		char op = GetOperation();

		switch(op) {
			case '+':
				return lvalue + rvalue;

			case '-':
				return lvalue - rvalue;

			case '*':
				return lvalue * rvalue;

			case '/':
				return lvalue / rvalue;

			default:
				return 0;
		}
	} else
		return value;
}
bool Isnum(char c) {
	for(int i = 0; i < sizeof(NUM); i++) {
		if(c == NUM[i])
			return true;
	}

	return false;
}
bool Isoperation(char c) {
	for(int i = 0; i < sizeof(OPERATION); i++) {
		if(c == OPERATION[i])
			return true;
	}

	return false;
}
Unit * Analyse(string exp) { //分析表达式并生成链表
	int pri = 0; //当前优先级
	int stat = 1; //当前的读入状态 括号 0 运算符 1 其他 2
	Unit * head = NULL, * p = NULL;
	int i = 0, explen;
	explen = exp.size();

	for(i = 0; i < explen; i++) {
		char c = exp.at(i);

		if(c == '(') {
			pri += 3;
			stat = 0;
		} else if(c == ')') {
			pri -= 3;
			stat = 0;
		} else if(Isoperation(c) && stat != 1) { //操作符后的当正负号处理
			stat = 1;
			Unit * temp = p;
			int add_pri; //自身增加的优先级

			if(c == '+' || c == '-')
				add_pri = 1;
			else
				add_pri = 2;

			p->Next = new Unit(pri + add_pri, c, " ", 0, 0);
			p = p->Next;
			p->Pre = temp;
		} else { //其他的当做函数处理
			stat = 2;
			string function = "";

			while(i < explen && (c = exp.at(i), ! Isoperation(c)) && c != ')') {
				function += c;
				i++;
			}

			i--;

			if(head == NULL) {
				p = new Unit(pri, ' ', function, 0, 2);
				head = p;
			} else {
				Unit * temp = p;
				p->Next = new Unit(pri, ' ', function, 0, 2);
				p = p->Next;
				p->Pre = temp;
			}
		}
	}

	return head;
}
Unit * Calc(Unit * head) { //计算双向链表基本单元的值
	Unit * p = head;

	while(p != NULL) {
		if(p->Type != 0) { //非操作符
			string temp = p->Code;
			string op;
			double lvalue = 0, rvalue = 0;
			int l_point = 0, r_point = 0;
			int i = 0, type = 0;
			char ch;

			while(i < temp.size() && (ch = temp.at(i), Isnum(ch))) {
				if(ch == '.') {
					l_point++;
					i++;
					continue;
				}

				if(! l_point)
					lvalue *= 10;

				lvalue += (ch - '0') * pow(10, -l_point);
				i++;

				if(l_point)
					l_point++;
			}

			while(i < temp.size() && (ch = temp.at(i), ! Isnum(ch))) {
				op += ch;
				type = 1;
				i++;
			}

			while(i < temp.size() && (ch = temp.at(i), Isnum(ch))) {
				if(ch == '.') {
					r_point++;
					i++;
					continue;
				}

				if(! r_point)
					rvalue *= 10;

				rvalue += (ch - '0') * pow(10, -r_point);
				i++;

				if(r_point)
					r_point++;
			}

			Fun * f = new Fun(op, type, lvalue, rvalue);
			p->value = f->calc();
		}

		p = p->Next;
	}

	return head;
}
Node * Tree(Unit * head) { //生成表达式树
	Node * root = NULL, * proot = NULL, * pbranch = NULL;
	Unit * p = head;
	int now_pri; //当前优先级
	bool hadop = false;

	while(p != NULL) {
		if(p->Type == 0) { //如果是一个操作符
			hadop = true;

			if(root == NULL) {
				proot = new Node(p->Operation, p->PRI, 1);
				root = proot;
				pbranch = root;
				now_pri = p->PRI;
				proot->Left = new Node(' ', 0, 0, p->Pre->value);
				proot->Right = new Node(' ', 0, 0, p->Next->value);
			} else {
				if(p->PRI < now_pri) { //优先级低于当前优先级,树根方向
					proot = new Node(p->Operation, p->PRI, 1); //新的树根
					proot->Left = root; //根的变换
					proot->Left->Head = proot;
					proot->Right = new Node(' ', 0, 0, p->Next->value);
					proot->Right->Head = proot;
					root = proot;
					pbranch = proot; //右树枝的变换
//pbranch->Right=new Node(' ',0,0,p->Pre->value); //树枝右边取值
				} else if(p->PRI == now_pri) { //优先级相同,先算左边的
					Node * temp;
					temp = new Node(p->Operation, p->PRI, 1);
					temp->Left = pbranch;

					if(pbranch->Head == NULL) {
						proot = temp;
						root = proot;
						pbranch->Head = proot;
					} else {
						Node * temp0;
						temp0 = pbranch->Head;
						temp0->Right = temp;
						temp->Head = temp0;
						pbranch->Head = temp;
					}

					pbranch = temp;
					pbranch->Right = new Node(' ', 0, 0, p->Next->value);
					pbranch->Right->Head = pbranch;
				} else {
					Node * temp;
					temp = new Node(p->Operation, p->PRI, 1);
					pbranch->Right = temp;
					temp->Head = pbranch;
					pbranch = pbranch->Right;
					pbranch->Left = new Node(' ', 0, 0, p->Pre->value);
					pbranch->Left->Head = pbranch;
					pbranch->Right = new Node(' ', 0, 0, p->Next->value);
					pbranch->Right->Head = pbranch;
				}

				now_pri = p->PRI;
			}
		}

		p = p->Next;
	}

	if(! hadop)
		root = new Node(' ', 0, 0, head->value);

	return root;
}
void print(string s,int p) {
	for(int i=0; i<s.size(); i++) {
		if(s[i]=='/'&&s[i+1]=='n'&&i<s.size()-1) {
			cout<<endl;
			i++;
		} else {
			cout<<s[i];
			Sleep(p);
		}
	}
}
void ko() {
	int s=5;
	while(s--) {
		cout<<"●●●\n";
		cout<<"●    正在关机...\n";
		cout<<"●●  \n";
		Sleep(60);
		system("cls");
		cout<<"●●  \n";
		cout<<"●    正在关机...\n";
		cout<<"●●●\n";
		Sleep(60);
		system("cls");
		cout<<"●    \n";
		cout<<"●  ●正在关机...\n";
		cout<<"●●●\n";
		Sleep(60);
		system("cls");
		cout<<"    ●\n";
		cout<<"●  ●正在关机...\n";
		cout<<"●●●\n";
		system("cls");
	}
}
void k_o() {
	int s=5;
	while(s--) {
		cout<<"●●●\n";
		cout<<"●    正在重启...\n";
		cout<<"●●  \n";
		Sleep(60);
		system("cls");
		cout<<"●●  \n";
		cout<<"●    正在重启...\n";
		cout<<"●●●\n";
		Sleep(60);
		system("cls");
		cout<<"●    \n";
		cout<<"●  ●正在重启...\n";
		cout<<"●●●\n";
		Sleep(60);
		system("cls");
		cout<<"    ●\n";
		cout<<"●  ●正在重启...\n";
		cout<<"●●●\n";
		system("cls");
	}
}
string getTime() {
	time_t timep;
	time (&timep);
	char tmp[64];
	strftime(tmp, sizeof(tmp), "系统时间:%Y年%m月%d日 %H时%M分%S秒",localtime(&timep) );
	return tmp;
}
void color(int corcorcor) {
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),corcorcor);
}
int main() {
	cursor(0);

	int kep;
	int p=80;
	while(1) {
		string exp;
		color(9);
		print("Coding.lin--1.0操作系统:欢迎您!\n",p);
		color(7);
		string s= getTime();
		print(s,p);
		color(14);
		print("\n1 Coding系统操作 2 简易函数计算器 3 Code相关知识链接\n",p);
		color(7);
		cin>>kep;
		if(kep==1) {
			system("cls");
			printf("Coding.lin--1.0操作系统\n1 关机 2 重新启动 3 低性能模式(取消字符出现速度)\n",p);

			int a;
			cin>>a;
			if(a==1) {
				system("cls");
				ko();
				print("BYE!",p);
				return 0;
			} else if(a==2) {
				system("cls");
				k_o();
				Sleep(1000);
				p=80;
				print("重启成功!(低性能模式恢复默认关闭)",p);
			} else if(a==3) {
				p=0;
				print("开启成功!",p);
			} else {
				print("乱输入什么!",p);
			}
		}
		if(kep==2) {
			system("cls");
			cout << "简易函数计算器" << endl;
			cout << "函数说明: " << endl <<
			     "1: log是以10为底的工程对数" << endl <<
			     "2: ln 是以e为底的自然对数" << endl <<
			     "3: C 计算组合数 输入规则 如计算 3取2的组合 输入表达式 3C2" << endl <<
			     "4: A 计算排列数 输入规则 如计算 3取2的排列 输入表达式 3A2" << endl <<
			     "5: ! 计算阶乘" << endl <<
			     "6: ^ x的y次方 输入 x^y" << endl<<"10:退出\n";

			while(1) {
				cin>>exp;
				if(exp == "10")
					break;

				Unit * h = Analyse(exp);
				h = Calc(h);
				Node * root = Tree(h);
				cout << exp << "=" << root->GetValue() << endl;
			}
		}
		if(kep==3) {
			system("cls");
			print("1 贪心 2 模拟 3 枚举 ",p);
			int a;
			cin>>a;
			int p1=60;
			if(a==3) {
				system("cls");
				print("枚举的含义\n枚举是把所有可能的情况都列举出来,逐一验证。\n当我们要求证的问题,其所有可能的方案数在一个有限范围内时,我们就可以用枚举来解决这个问题。\n枚举是解编程题常用且有效的一种手段,但在枚举时,也要注意以下几点:\n多重循环的枚举很可能超时,应当尽可能优化、减少循环次数。\n枚举虽然直接有效,但有些题并不能使用枚举解决,或者说不能单纯用枚举来解决,需要配合其他的优化算法。",p1);
				Sleep(2000);
			}
			if(a==1) {
				system("cls");
				print("贪心算法的基本思想\n在对一个问题求解时,总是做出在当前看来是最好的选择。也就是说,把一个较复杂的问题分解成若干子问题,对于每个子问题来说, 不从整体最优上加以考虑,只做出在某种意义上的局部最优解。\n通过每次得到局部最优解答,逐步推导出问题,进而得到全局最优解。\n通俗地来讲,就是怎么做有利就怎么做。\n贪心问题的解决总是伴随着排序,我们以选择尽量优的解的原则,将事物按照最优的解在最前的顺序排好,然后依次选取最优选择,构成整体最优解。\n",p1);
				Sleep(2000);
			}
			if(a==2) {
				system("cls");
				print("模拟顾名思义,就是按照题目的要求,一步步写出代码。\n题目要求怎么做就怎么做,用代码的形式描述出来。",p1);
				Sleep(2000);
			}
			//system("cls");
		}

		system("cls");
	}


	return 0;
}

鄙人还请您留下点赞,评论,关注或修改意见,谢谢!

李致远在2020-10-08 19:14:19追加了内容

哦对了,这里谢谢一下

李致远在2020-10-08 19:15:53追加了内容

沙宸安同学,我的系统时间是参考这位同学的。。

 

 


0
已采纳
沙宸安
沙宸安
高级启示者
高级启示者
string getTime() {
    time_t timep;
    time (&timep);
    char tmp[64];
    strftime(tmp, sizeof(tmp), "系统时间:%Y年%m月%d日 %H时%M分%S秒",localtime(&timep) );
    return tmp;
}

学得好,真好

(我可没讲TA抄袭我的)

0
武建豪
武建豪
中级天翼
中级天翼

整体还是很好的,可以稍微修一修框架(就是页面可以做一个)

0
0
0
0
张恩泽
张恩泽
高级天翼
高级天翼

six six six %%%

张恩泽在2020-10-06 08:48:30追加了内容

就是你这个系统操作能不能加一个退出选项

0
刘乐宸
刘乐宸
新手天翼
新手天翼

这是一个普通的计算器而已

0
0
我要回答