2014/4月 金山WPS 实习生C++笔试题

今天无聊就写了出来,仅供参考,大题都是不一样的,准备参加笔试的同学别以为是一样的哈

发现自己手写效果真的挺差的,而且不能调试BUG真心挺多的,本来还以为我自己做的挺不错的,但是真正写出来,我去啊,发现BUG一堆堆的啊!

//金山WPS C++面试题
/*完成下列函数的功能,可以自己重新设计类,也可以改名etc
	1.可以插入学生
	2.可以删除学生
	3.可以找出成绩最高的N位学生
	struct Student{
		int id;
		string name;
		double score;
	}
	class StudentMrg{
		public:
			Student[100];
		bool InsertStudent(Student *s);//插入学生
		bool DeleterStudent(const string &name);
		student FindByName(const string *name);//
		vector<student> GetNTop(Student *s,int n);//最高分的n个
	
		StudentMrg();
		~StudentMrg();
	}
*/
/*
	我是用单链表做的,因为更容易增删
*/

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

struct student{//直接做成嵌套类,更安全,但是测试不方便,还是弄到外面吧
	string name;
	double score;
	struct student *next;//我去啊,我笔试好像写出了struct *student next了,郁闷
};

class StudentMrg{
//public://要放到前面,前置声明

private:
	student *front;//头指针
	student *rear;//尾指针,指向最后一个元素的下一个节点
	int size;//学生人数
public:
	StudentMrg();
	~StudentMrg();
	bool Insert(student *s);
	bool Delete(const string &name);
	bool FindByName(const string &name);//发现这里最好返回一个副本,//发现直接返回引用也不错
									//发现返回一个结构好郁闷的样子,因为最后那个构造怎么写?
									//结构体是可以返回,但是如果找不到的时候该返回什么?
									//返回一个bool值吧
	vector<student> GetNTop(int n)const;
	void showStudentMrg()
	{
		student *p=front;
		cout<<"size="<<size<<endl;
		while(p!=rear)//不能写成while(p),因为rear是指向最后一个的下一个,p!=null就行,
		{
			cout<<"name:"<<p->name<<"   ,score:"<<p->score<<endl;
			p=p->next;
		}
		cout<<"over"<<endl;
	};//这个是我方便测试
};
//实现
StudentMrg::StudentMrg()//建立新链表
{
	front=rear=nullptr;
	size=0;
};
StudentMrg::~StudentMrg()//要逐一节点删除
{
	student *p=front;
	while(p)//当p!=nullptr时才执行删除,这样保证了空链表不会删除失败
	{
		front=p->next;
		delete p;
		p=front;
	}
};
//插入我的思想是新建节点插入,并根据成绩高低进行排序插入,这样方便查找最高分的人
bool StudentMrg::Insert(student *s)
{
	bool flag=false;//判断是否成功插入了
	if(!front)//当是第一次插入新数据时,//即当front=nullptr时
	{
		student *newS=new student;
		front=newS;
		newS->name=s->name;
		newS->score=s->score;
		//rear=newS->next;//最好把newS->next指向尾指针
		rear=front->next;
		size++;//学生数-1;
		flag=true;
		return flag;
	}
	else//不是第一次插入时
	{
		//啊,忘记判断在头部插入的时候了啊,我去啊
		//当要在头部插入数据时
		if(s->score>=front->score)
		{
			student *insertS=new student;//因为析构函数用了delete,节点值都要new
			insertS->name=s->name;
			insertS->score=s->score;
			insertS->next=front;//使新节点成为新头部
			front=insertS;
			size++;
			flag=true;
			return flag;
		}
		//当不是头部插入时
//*******//为何新建了这两个变量,在监视里面找不到呢??
		student *find=front;//用于查找插入的位置
		student *temp=find;//用于记录find的上一个值
		/*testing 明明有,为何监视找不到????
		cout<<"front:"<<front<<endl;
		cout<<"find:"<<find<<endl;
		cout<<"temp:"<<temp<<endl;
		*/
		/*
			按分数从低到高插入
		*/
		while(find!=rear)//当find所指向的下一个指针不是尾指针时//find->next!=rear//error
		{		//应当是find不是rear是,否则的话,例如,插入70到20,100的时候
				//find指向100时,还没进来判断就结束了while
			//cout<<"find->next:"<<find->next<<endl;
			//判断要注意了,当上一个<=s->score的时候,就应该插入了
			//这里默认是在链表中间插入
			if((temp->score>s->score)&&((find->score==s->score)||(find->score<s->score)))
			{
				student *insert=new student;
				insert->name=s->name;//值复制过来
				insert->score=s->score;
				//链表插入,先断开后面的,再连接前面的
				insert->next=find;
				temp->next=insert;
				size++;
				flag=true;
				return true;
			}
			//倘若不是
			temp=find;//先保存上一个值
			find=find->next;//顺移,指向下一个
		}
		//在最后面插入时
		if(find==rear)//这时,find指向rear的前一个节点
		{
			student *endInsert=new student;
			endInsert->name=s->name ;
			endInsert->score=s->score;
			temp->next=endInsert;//改变尾指针
			rear=endInsert->next;
			size++;
			flag=true;
			return flag;
		
		}
	}
	return flag;
	//发现写在卷子上就会忽略很多细节的东西,真郁闷。

};

bool StudentMrg::Delete(const string &name)
{
	student *find=front;//用于存储找到的那个节点
	student *temp=find;//用于记录find的上一个节点
	bool flag=false;

	if(front->name==name)//如果是头指针
	{
		front=front->next;//头指针后移
		delete temp;
		size--;
		flag=true;
		return flag;
	}
	while(find!=rear)//当find->不为null时,即不==rear,即是在中间删除时
	{				//直接领find不为rear即可,这样即便删除最后一个,此时,find==rear
					//因为temp保存了上一个值,temp->next=find->next 依然会令上一个指向rear指针
		if(find->name==name)//如果找到,这里假设不存在同名
		{
			temp->next=find->next;//直接更改指针
			delete find;
			size--;
			flag=true;
			return flag;
		}
		temp=find;
		find=find->next;
	}
	//如果是rear的前一个节点,发现删除的时候,前一句可以正确地删除rear的前一个节点
	//但是Insert就不行了,因为有个if判断语句 
	/*if(find->next)
	{
	}*/
	cout<<"no such student who's name is "<<name<<endl;
	return flag;

};

bool StudentMrg::FindByName(const string &name)
{
	student *find=front;
	while(find!=rear)//
	{
		if(find->name==name)
		{
			/*
			student target;
			target.name=find->score;
			target.score=find->score;
			return target;//find;//student{nname,score,nullptr};
				//这个结构体是临时的,返回会不会出问题呢?
				*/
			cout<<"Had found!"<<"  name:"<<find->name<<"  score:"<<find->score<<endl;
			return true;
		}
		find=find->next;
	}
	cout<<"no such man,can't find!"<<endl;
	//return *rear;
	return false;

}
//说真的,感觉最后这个最容易啊

vector<student> StudentMrg::GetNTop(int n)const//GetNTop(const StudentMrg *s,int n)
{
	bool flag=false;
	if(n>size)
		cout<<"OO,no so many people!Are you king me ??"<<endl;
	else
	{
		flag=true;
		student *p=front;
    	vector<student> arr;
		//vector<student>::iterator it=arr.begin();//用迭代器,发现不太会用0.0
		while(n--)
		{
			//cout<<"in"<<endl;
			student s={p->name,p->score,nullptr};
			arr.push_back(s);
			p=p->next;//居然写出了P++,真是人才啊..
		}
		/*/test
		vector<student>::iterator it;
		for(it=arr.begin();it!=arr.end();++it)
			cout<<it->name<<"  "<<it->score<<endl;
		cout<<"OKK"<<endl;
		*/
		if(flag)
			return vector<student>(arr);
		else
			return vector<student>(0);

	}
}

/*
void output(const student *s){
	cout<<s->name<<"  "<<s->score<<endl;
};
*/

void JSstudent()//testing
{ 
	{
	StudentMrg s;
	//student *s1={"one",50,nullptr};
	//s.Insert(s1);
	student s1[5]={{"one",30,nullptr},
					{"two",10},
					{"three",70},
					{"four",65},
					{"five",100}};
	for(int i=0;i<5;i++)
	  s.Insert(&s1[i]);
	//s.showStudentMrg();//插入测试成功
	//s.Delete("five");
	//student find(s.FindByName("five5"));
	//if(find.name!="")
		//cout<<"name:"<<find.name<<"  score:"<<find.score<<endl;
	//s.showStudentMrg();
	//s.FindByName("one1");

	vector<student> ar=s.GetNTop(6);//大于5时会有BUG
	//ostream_iterator<string,char> out(cout," ");
	//for_each(ar.begin(),ar.end(),output);
	vector<student>::iterator it;
	if(ar.size()>0)//加了这个判断之后就不会有BUG了
	{
		cout<<"The top "<<ar.size()<<" is :"<<endl;
	for(it=ar.begin();it!=ar.end();++it)
		cout<<it->name<<"  "<<it->score<<endl;
	cout<<endl;
	}
	cout<<"JS over"<<endl;
	cin.get();
	
	}
}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值