北理复试上机题2010年

版权声明:作者:weizu_cool https://blog.csdn.net/qq_26460841/article/details/88391575

1、输入一串整数,输入指令。

要求:(1)输入a t,在这串整数后添加整数t。(2)输入c\m\n,用n替换m。(3)输入d t,删除t。(4)输入s,排序。

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int parseInt(string b){
	char a = b[0];//switch-case中只能接受int\char类型,故而不能直接用string,这里使用了讨巧的方法
	switch(a){
		case '0':return 0;break;
		case '1':return 1;break;
		case '2':return 2;break;
		case '3':return 3;break;
		case '4':return 4;break;
		case '5':return 5;break;
		case '6':return 6;break;
		case '7':return 7;break;
		case '8':return 8;break;
		case '9':return 9;break;
		default: return -1;
	}
}
void replaceNum(int &num, int m, int n){//n替换m
	int sum=0;                        //思路来源图1
	int bei = 1;
	while(num){
		int mo = num%10;
		if(mo==m){
			sum = n*bei+sum;
		}else{
			sum = mo*bei+sum;
		}
		num=num/10;
		bei*=10;
	}
	num = sum;
}
void addT(int &num, int t){
	num=num*10+t;
}
void optionA(int &num){
	int t;
	cin>>t;
	addT(num, t);
	cout<<"结果是:"<<num<<endl;
}
void optionC(int &num){
	//	\m\n,用n替换m
	string s;
	int index;
	cin>>s;
	for(int i=1;i<s.length();i++){
		if(s[i]=='\\'){
			index=i;
			break;
		} 
	} 
	int m = parseInt(s.substr(1,index-1));
	int n = parseInt(s.substr(index+1));
	//可以直接使用字符串,然后我们用replace函数 
	replaceNum(num, m, n);
	cout<<"结果是:"<<num<<endl;//输出结果
}
void deleteT(int &num, int t){
	int sum=0, bei=1;
	while(num){               //思路来源图2
		int mo = num%10;
		if(mo!=t){//当等于t时候什么都不做 ,也就是图2中的,遇到2 sum=sum
			sum = mo*bei+sum;	
			bei*=10;
		}
		num=num/10;
	}
	num = sum;
}
void optionD(int &num){//3.输入d t,删除t。
	int t;
	cin>>t;
	deleteT(num, t);
	cout<<"结果是:"<<num<<endl;//输出结果	
}
void assemble(vector<int>& v, int num){
	while(num){
		int mo = num%10;
		v.push_back(mo);       //思路来源,利用vector可以用sort函数
		num/=10;
	}
	sort(v.begin(),v.end());
}
void sortNum(int &num){
	vector<int> v;
	assemble(v, num);
	for(vector<int>::iterator it=v.begin();it!=v.end();it++){
		cout<<*it;
	} 
	cout<<endl;
}
int main()
{
	while(1){
		cout<<"\n输入一串整数,输入指令。要求:\n1.输入a t,在这串整数后添加整数t。\n2.输入c \\m\\n,用n替换m。\n3.输入d t,删除t。\n4.输入s,排序。\n请先输入一串整数:";
    //加入两杠\\是因为转义字符
		int num;
		cin>>num;
		char type;
		cout<<"请输入操作指令:";
		cin>>type;
		if(type=='a'){
			optionA(num);
		}else if(type=='c'){
			optionC(num);
		}else if(type=='d'){
			optionD(num);
		}else if(type=='s'){
			sortNum(num); 
		}else{
			return 0;
		}
	}
    return 0;
}

2、输入表达式,输出值。分两种情况:中缀表达式和后缀表达式。

中缀表达式求值:先将中缀表达式建立二叉树转后缀表达式,然后再求值。

尝试1:

#include <iostream>
#include <string>
#include <cmath>
#include <cstdlib>//sum1=atof(t1.c_str());
using namespace std;
 

//后缀表达式求值,这种方式的弊端很明显,只能计算单个位置的数据,不能出现多位数和小数,原因是我这里每次取数是expression[i]造成的 
double  postfix_expression(string expression){
	//56+2*3+
	double stack[20];//操作数栈
	int top = -1;//栈顶指针
	for(int i=0;i<expression.length();i++){
		if(expression[i]=='+'){
			double d = stack[top];//栈顶指针在top 
			top--;
			double c = stack[top];
			stack[top]=d+c;
			cout<<d<<"+"<<c<<"="<<stack[top]<<endl;
		}else if(expression[i]=='-'){
			double d = stack[top];
			top--;
			double c = stack[top];
			stack[top]=c-d;
			cout<<c<<"-"<<d<<"="<<stack[top]<<endl;
		}else if(expression[i]=='*'){
			double d = stack[top];
			top--;
			double c = stack[top];
			stack[top]=c*d;
			cout<<d<<"*"<<c<<"="<<stack[top]<<endl;
		}else if(expression[i]=='/'){
			double d = stack[top];
			top--;
			double c = stack[top];
			stack[top]=c/d;
			cout<<c<<"/"<<d<<"="<<stack[top]<<endl;
		}else if(expression[i]>='0' and expression[i]<='9'){
			top++;
			string s = expression.substr(i,1);
			double c = atof(s.c_str());
			stack[top]=c;
		}else{
			cout<<"输入错误!"<<endl;
			exit(0);
		}
	} 
	return stack[top--];
}
int main()
{
//	string ex;
//	cout<<"请输入后缀表达式:"; 
//	cin>>ex;
	//用例:3*(5+4)/8+4*(5+2) 
    cout<<postfix_expression("54+3*8/52+4*+")<<endl;
    return 0;
}

猜想,我们对数字的判断应该在之前就判断完毕,因为后缀表达式中,如:54+3*8/52+4*+,是比较难确定54还是5 4 当然可以用操作符的个数匹配,但是比较麻烦。这里,我们可以用中缀表达式,也就是原来输入的数据表达式,然后我们截取数据放入集合中,集合的类型是vector<string>,我们在使用后缀表达式的时候,转换数据就会比较方便。下面关键是如何处理由中缀表达式向后缀表达式转化。

参考数据结构:

需要用操作符的优先级进行栈运算。用icp(in coming priority)表示当前扫描到的运算符的优先级,用isp(in stack priority)表示该运算符进栈后的优先级。

操作符

#

(

* /

+ -

)

isp

0

1

5

3

6

icp

0

6

4

2

1

举例说明:3*(5+4)/8+4*(5+2)

中缀表达式:3*(5+4)/8+4*(5+2)  后缀表达式:354+*8/452+*+

步骤

扫描项

项类型

动作

字符栈内内容

输出

0

 

 

‘#’进栈,读取下一字符

#

 

1

3

操作数

直接输出

#

3

2

*

操作符

isp(#)<icp(*),进栈

#*

 

3

(

操作符

isp(*)<icp((),进栈

#*(

 

4

5

操作数

直接输出

#*(

5

5

+

操作符

isp(()<icp(+),进栈

#*(+

 

6

4

操作数

直接输出

 

4

7

)

操作符

isp(+)>icp()),出栈

#*(

+

 

 

 

isp(()==icp()),退栈

#*

 

8

/

操作符

isp(*)>icp(/),出栈

#

*

 

 

 

isp(#)<icp(/),出栈

#/

 

9

8

操作数

直接输出

 

8

10

+

操作符

isp(/)>icp(+),出栈

#

/

11

 

 

isp(#)<icp(+),进栈

#+

 

12

4

操作数

直接输出

 

4

13

*

操作符

isp(+)<icp(*),进栈

#+*

 

14

(

操作符

isp(*)<icp((),进栈

#+*(

 

15

5

操作数

直接输出

 

5

16

+

操作符

isp(()<icp(+),进栈

#+*(+

 

17

2

操作数

直接输出

 

2

18

)

操作符

isp(+)>icp()),出栈

#+*(

+

 

 

 

isp(()==icp()),退栈

#+*

 

19

#

操作符

isp(*)>icp(#),出栈

#+

*

 

 

 

isp(+)>icp(#),出栈

#

+

 

 

 

isp(#)==icp(#),退栈结束

#)

 

就可以得到中缀表达式,所以这里需要使用优先级比较+栈

#include <iostream>
#include <string>
#include <cmath>
#include <vector>
#include <cstdlib>//sum1=atof(t1.c_str());
using namespace std;
 
/*
操作符	#	(	* /	 + -	)
isp	   0	1	5	 3 	   6
icp	   0	6	4	 2 	   1
*/
//四则运算,栈内>入栈,而且*/一定高于+-;括号,栈内<入栈, 站内尾大,入栈头大,占两端 
// 前期思考数据封装函数,最后演化成 transform_postfix 中的中心架构 
vector<double> data_package(string expression){
	vector<double> vc;
	int index=0, count=0;//记录需要截取字符串的下标位置
	for(int i=0;i<expression.length();i++){
		//3*(5+4)/8+4*(5+2)
		if(expression[i]=='+' or expression[i]=='-' or expression[i]=='*' or expression[i]=='/' or expression[i]==')' or expression[i]=='('){
			if(count!=0){
				string s=expression.substr(index, count);//使用截取而不是直接expression[i],是因为写入字符,是字符地址后面的一大坨字符(首地址) 
				double num = atof(s.c_str());
				vc.push_back(num);
			}
			index=i+1;
			count=0;
		}
		else {
			count++;
		}
	} 
	return vc;
}
//3*(5+4)/8+4*(5+2)
//为了方便+-*/()表示为:335516   224461
int get_isp(char a){
	if(a=='+' or a=='-')
		return 3;
	else if(a=='*' or a=='/')
		return 5;
	else if(a=='(') 
		return 1;
	else if(a==')')
		return 6;
	else if(a=='#')
		return 0;
}
int get_icp(char a){
	if(a=='+' or a=='-')
		return 2;
	else if(a=='*' or a=='/')
		return 4;
	else if(a=='(') 
		return 6;
	else if(a==')')
		return 1;
	else if(a=='#')
		return 0;
}
string transform_op_stack_to_string(char a){
	//op_stack[top]
	if(a=='+')
		return "+";
	else if(a=='-')
		return "-";
	else if(a=='*')
		return "*";
	else if(a=='/')
		return "/";
}
//思路来源于上面的:data_package 
string  transform_postfix(string expression){
	//这里也要完成表达式的封装vector<string>
	vector<double> vc = data_package(expression);
	char op_stack[20];//+-*/():335516   224461
	int top = -1;
	top++;
	op_stack[top]='#';
	string str="";
	int index=0, count=0;//记录需要截取字符串的下标位置
	int i=0;
	while(top!=-1){
		if(i==expression.length()){
			expression.append("#");//因为栈可能没出完,而表达式判断已经到了末尾 
		}
		if(expression[i]=='+' or expression[i]=='-' or expression[i]=='*' or expression[i]=='/' or expression[i]==')' or expression[i]=='#' or expression[i]=='('){
			//数字在前 
			if(count!=0){
				string s=expression.substr(index, count);
				str.append(s);
				str.append(" ");  //数字,直接输出 
			}
			index=i+1;
			count=0;
			
			//符号判断在后 
			//isp icp 大,进;小,顶出;等,退 
			if(get_isp(op_stack[top])<get_icp(expression[i])){
				top++;
				op_stack[top]=expression[i]; 
			}else if(get_isp(op_stack[top])>get_icp(expression[i])){
				bool flag = true;//是否循环 
				while(flag){//使用标识,进栈或者退栈,就退出循环 
					if(get_isp(op_stack[top])>get_icp(expression[i])){
						//小 ,顶出
						str.append(transform_op_stack_to_string(op_stack[top])+" ");
						//这里之所以要把char 转为 string ,是因为使用char 数组,加入的是该地址后的所有的字符 
					//	cout<<op_stack[top]<<"顶出"<<"此时的比较元素是:"<<expression[i]<<endl;
						top--; 
					}else if(get_isp(op_stack[top])<get_icp(expression[i])){//大,进 
						top++;
						op_stack[top]=expression[i]; 
						flag = false;//不再循环 
					//	cout<<op_stack[top]<<"进栈"<<endl;
					}else if(get_isp(op_stack[top])==get_icp(expression[i])){
						flag = false;//不再循环 
					//	cout<<op_stack[top]<<"退栈"<<endl;
						top--;//等,退 
					} 
				}
			}else if(get_isp(op_stack[top])==get_icp(expression[i])){
				top--;//等,退 
			} 
		}else {
			count++;
		}
		i++;
	}
	cout<<"后缀表达式的结果:"<<str<<endl;
	return str;
}



//初始版本(已抛弃):后缀表达式求值,这种方式的弊端很明显,只能计算单个位置的数据,不能出现多位数和小数,原因是我这里每次取数是expression[i]造成的 
double  postfix_expression(string expression){
	//56+2*3+
	double stack[20];//操作数栈
	int top = -1;//栈顶指针
	cout<<"计算的过程如下:"<<endl; 
	for(int i=0;i<expression.length();i++){
		if(expression[i]=='+'){
			double d = stack[top];//栈顶指针在top 
			top--;
			double c = stack[top];
			stack[top]=d+c;
			cout<<d<<"+"<<c<<"="<<stack[top]<<endl;
		}else if(expression[i]=='-'){
			double d = stack[top];
			top--;
			double c = stack[top];
			stack[top]=c-d;
			cout<<c<<"-"<<d<<"="<<stack[top]<<endl;
		}else if(expression[i]=='*'){
			double d = stack[top];
			top--;
			double c = stack[top];
			stack[top]=c*d;
			cout<<d<<"*"<<c<<"="<<stack[top]<<endl;
		}else if(expression[i]=='/'){
			double d = stack[top];
			top--;
			double c = stack[top];
			stack[top]=c/d;
			cout<<c<<"/"<<d<<"="<<stack[top]<<endl;
		}else if(expression[i]>='0' and expression[i]<='9'){
			top++;
			string s = expression.substr(i,1);
			double c = atof(s.c_str());
			stack[top]=c;
		}else{
			cout<<"输入错误!"<<endl;
			exit(0);
		}
	} 
	return stack[top--];
}
//改进
double  postfix_expression_fix(string expression){
	//56+2*3+
	double stack[20];//操作数栈
	int top = -1;//栈顶指针
	int count=0, index=0; 
	//测试的结果:3 5 4 + * 8 / 4 5 2 + * +  用空格分割 
	for(int i=0;i<expression.length();i++){
		if(expression[i]=='+' or expression[i]=='-' or expression[i]=='*' or expression[i]=='/' or expression[i]==')' or expression[i]==' ' or expression[i]=='('){
			//数字在前 
			if(count!=0){
				string s=expression.substr(index, count);
			//	cout<<"操作数:"<<s<<endl;//测试 
				top++;
				stack[top]=atof(s.c_str()); //字符串转化为double,加入栈 
			}
			index=i+1;
			count=0;
			
			//判断符号 
			if(expression[i]=='+'){
				double d = stack[top];//栈顶指针在top 
				top--;
				double c = stack[top];
				stack[top]=d+c;
				cout<<d<<"+"<<c<<"="<<stack[top]<<endl;
			}else if(expression[i]=='-'){
				double d = stack[top];
				top--;
				double c = stack[top];
				stack[top]=c-d;
				cout<<c<<"-"<<d<<"="<<stack[top]<<endl;
			}else if(expression[i]=='*'){
				double d = stack[top];
				top--;
				double c = stack[top];
				stack[top]=c*d;
				cout<<d<<"*"<<c<<"="<<stack[top]<<endl;
			}else if(expression[i]=='/'){
				double d = stack[top];
				top--;
				double c = stack[top];
				stack[top]=c/d;
				cout<<c<<"/"<<d<<"="<<stack[top]<<endl;
			}else if(expression[i]>='0' and expression[i]<='9'){
				top++;
				string s = expression.substr(i,1);
				double c = atof(s.c_str());
				stack[top]=c;
			}
		}else{
			count++;
		} 
		
	} 
	return stack[top--];
}
 
int main()
{
	string expression;
	cout<<"请输入中缀表达式:"; 
	cin>>expression;
	//用例:3*(5+4)/8+4*(5+2) 
	string postfix = transform_postfix(expression);//后缀表达式:354+*8/452+*+ 
	double result = postfix_expression_fix(postfix);
    cout<<"表达式:"<<expression<<",计算的结果是:"<<result<<endl;
    return 0;
}

下面是使用电脑计算器计算的结果: 

作者:无涯明月

上篇:北理复试上机题2009年

猜你喜欢

转载自blog.csdn.net/qq_26460841/article/details/88391575