OOP习题(13)

一、函数题
1、vector

本题要求实现一个Vector类模板,能实现数据的存储和访问。通过[]运算符访问时只能访问已经存在的元素,而通过add()方法访问时可以自动扩展内部存储空间。

注意,这个Vector的行为和std::vector是不同的

函数接口定义:

template <class T>
class Vector {
...

裁判测试程序样例:

#include <iostream>
using namespace std;

/* 请在这里填写答案 */

int main()
{
    Vector<int> vint;
    int n,m;
    cin >> n >> m;
    for ( int i=0; i<n; i++ ) {
        //    add() can inflate the vector automatically
        vint.add(i);    
    }
    //    get_size() returns the number of elements stored in the vector
    cout << vint.get_size() << endl;
    cout << vint[m] << endl;
    //    remove() removes the element at the index which begins from zero
    vint.remove(m);
    cout << vint.add(-1) << endl;
    cout << vint[m] << endl;
    Vector<int> vv = vint;
    cout << vv[vv.get_size()-1] << endl;
    vv.add(m);
    cout << vint.get_size() << endl;
}

输入样例:

100 50

输出样例:

100
50
99
51
-1
100

代码解答: 

template <class T>
class Vector
{
private:
    int pos;
    int size = 100;
    T* data;
public:
    Vector() {
        pos = 0;
        data = new T[size];
    }
    int add(T m) {
        data[pos]=m;
        pos++;
        return pos-1;
    }
    int get_size() { return pos; }
    void remove(int m) {
        for (int i = m; i < pos-1; i++) {
            data[i] = data[i + 1];
        }
        pos--;
    }
    const T& operator[](int index)const
    {
        return data[index];
    }
};

2、二维向量相加(C++ 运算符重载)

裁判测试程序样例中展示的是一段二维向量类TDVector的定义以及二维向量求和的代码,其中缺失了部分代码,请补充完整,以保证测试程序正常运行。

函数接口定义:

提示:需要补充的函数有:
1. 带参构造函数
2. getX
3. getY
4. setX
5. setY
6. 运算符重载函数

裁判测试程序样例:

#include <iostream>
#include <iomanip>
using namespace std;
class TDVector{
private:
    double x;
    double y;
public:
    TDVector(){
        x = y = 0;
    }
/**    你提交的代码将被嵌在这里(替换本行内容)  **/
};
int main(){
    TDVector a;
    double x, y;
    cin >> x >> y;
    TDVector b(x, y);
    cin >> x >> y;
    TDVector c;
    c.setX(x);
    c.setY(y);
    TDVector d;
    d = a + b + c;
    cout << fixed << setprecision(2) << d.getX() << ' ' << d.getY();
    return 0;
}

输入样例:

1.1 2.2
3.3 4.4

输出样例:

4.40 6.60

代码解答: 

TDVector(double a,double b)   {
    x=a,y=b;
}
void setX(double a){
    x=a;
}
void setY(double b){
    y=b;
}
double getX(){
    return x;
}
double getY(){
    return y;
}
TDVector operator+(TDVector &a){
    TDVector c;    
    c.x = this->x + a.x;    
    c.y = this->y + a.y;    
    return c;
}

3、实现数组类(C++ 拷贝构造函数、拷贝函数)

裁判测试程序样例中展示的是一段实现“数组类”的代码,其中缺失了部分代码,请补充完整,以保证测试程序正常运行。

函数接口定义:

提示:要想程序正确运行,至少需要补充以下函数(可能还需要补充其他函数):
1. 带参构造函数
2. 拷贝构造函数
3. 拷贝函数(赋值运算符重载)

裁判测试程序样例:

#include <iostream>
using namespace std;
class ArrayIndexOutOfBoundsException{  // 异常类
public:
    int index;
    ArrayIndexOutOfBoundsException(int k){
        index = k;
    }
};
class Array{
private:
    int *data;
    int size;
    static const int dSize = 10;   // 数组默认大小
public:
    Array( ){  // 无参构造
        size = dSize;
        data = new int[size]( );
    }
        
/** 你提交的代码将被嵌在这里(替换本行内容) **/        
        
    int& operator [] (int k){     // 运算符 [ ] 重载,以方便数组的使用
        if(k<0 || k>=size) throw ArrayIndexOutOfBoundsException(k);
        return data[k];
    }
    friend ostream& operator << (ostream& o, const Array& a);   // 运算符 << 重载,以方便输出
};
ostream& operator << (ostream& o, const Array& a){
    o << '[' ;
    for(int i=0; i<a.size-1; i++)
        o << a.data[i] << ',' ;
    o << a.data[a.size-1] << ']';
    return o;
}
// 注意:实际测试程序中,在此处之前的代码与样例中相同
// 注意:实际测试程序中,在此处之后的代码(即main函数)可能与样例中不同
int main(){
    int n, k;
    cin >> n >> k;
    Array a(n);  // 构造数组,大小为 n
    for(int i=0; i<n; i++) a[i] = i;
    Array b = a;  // 拷贝构造数组
    b[n/2] = k;
    cout << a << endl;
    cout << b << endl;
    Array c;  // 构造数组,默认大小
    c = a; // 拷贝数组
    c[n/2] = k;
    cout << a << endl;
    cout << c << endl;
    a = a;
    a[n/2] = 2223;
    cout << a << endl;
    return 0;
}

输入样例:

15 666

输出样例:

[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
[0,1,2,3,4,5,6,666,8,9,10,11,12,13,14]
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
[0,1,2,3,4,5,6,666,8,9,10,11,12,13,14]
[0,1,2,3,4,5,6,2223,8,9,10,11,12,13,14]

代码解答: 

Array(int n){
    size = n;
    data = new int[size]();
}
Array(const Array& a){
    size = a.size;
    data = new int[size]();
    for (int i = 0; i < size; i++){
        data[i] = a.data[i];
    }
}
Array& operator=(const Array& a){//重载“=”,便于类对象的data数组赋值
    if (a.size != size){
        delete[]data;
        size = a.size;
        data = new int[size];
    }
    for (int i = 0; i < size; i++){
        data[i] = a.data[i];
    }
    return *this; //this指针返回本函数本身的Array
}
~Array(){
    delete[]data;//写析构函数是个好习惯,节约内存
}

4、写出派生类构造方法(C++)

裁判测试程序样例中展示的是一段定义基类People、派生类Student以及测试两个类的相关C++代码,其中缺失了部分代码,请补充完整,以保证测试程序正常运行。

函数接口定义:

提示:
观察类的定义和main方法中的测试代码,补全缺失的代码。

裁判测试程序样例:

注意:真正的测试程序中使用的数据可能与样例测试程序中不同,但仅按照样例中的格式调用相关函数。

#include <iostream>
using namespace std;
class People{
private:
    string id;
    string name;
public:
    People(string id, string name){
        this->id = id;
        this->name = name;
    }
    string getId(){
        return this->id;
    }
    string getName(){
        return name;
    }
};
class Student : public People{
private:
    string sid;
    int score;
public:
    Student(string id, string name, string sid, int score)
        
        /** 你提交的代码将被嵌在这里(替换此行) **/
        
    }
    friend ostream& operator <<(ostream &o, Student &s);
};
ostream& operator <<(ostream &o, Student &s){
    o << "(Name:" << s.getName() << "; id:"
      << s.getId() << "; sid:" << s.sid
      << "; score:" << s.score << ")";
    return o;
}
int main(){
    Student zs("370202X", "Zhang San", "1052102", 96);
    cout << zs  << endl;
    return 0;
}

输入样例:

(无)

输出样例:

(Name:Zhang San; id:370202X; sid:1052102; score:96)

代码解答: 

: People(id,name){
        this->sid = sid;
        this->score = score;
}
    string getsid() {
        return this->sid;
 }
    int getscore() {
        return this->score;
 

二、编程题

1、部分排序

对于一组数据,我们可以只对原先处在中间位置的那些元素进行排序。

输入格式:

在一行内输入n r a1 a2 ... an

其中,不大于200的正整数n表示该组数据的个数;不大于200的非负整数r表示该组数据两端各自留有r个数不参与排序,若r+r>=n,则该组数据无需排序。

整数a1 a2 ... an是该组的n个数据,且都在8位以内。

输出格式:

排序之后的序列,元素之间用一个空格间隔,最后一个元素之后不加空格。

输入样例:

5 1 6 5 4 3 2

输出样例:

6 3 4 5 2

代码解答: 

#include <iostream>
#include<vector>
using namespace std;
int main(){
    int i,j,n,r,c;
    cin >> n;
    vector<int> a;
    cin >> r;
    for(i=0; i<n; i++){
        int a0;
        cin >> a0;
        a.push_back(a0);
    }
    if(2*r<n){
        for(i=r,c=0; i<n-r-1; i++,c++){
            for(j=r; j<n-1-i; j++){
                if (a[j]>a[j+1]){
                    c=a[j];
                    a[j]=a[j+1];
                    a[j+1]=c;
                }
            }
        }
        for(i=0; i<n; i++){
            cout << a[i];
            if(i<n-1)
                cout << " ";
        }
    }
    else{
        for(i=0; i<n; i++){
            cout << a[i];
            if(i<n-1)
                cout << " ";
        }
    }
    return 0;
}

2、宿舍谁最高?

学校选拔篮球队员,每间宿舍最多有 4 个人。现给出宿舍列表,请找出每个宿舍最高的同学。定义一个学生类 Student,有身高 height,体重 weight 等。

输入格式:

首先输入一个整型数 n (1≤n≤106),表示有 n 位同学。

紧跟着 n 行输入,每一行格式为:宿舍号 name height weight
宿舍号的区间为 [0, 999999], name 由字母组成,长度小于 16,heightweight 为正整数。

输出格式:

按宿舍号从小到大排序,输出每间宿舍身高最高的同学信息。题目保证每间宿舍只有一位身高最高的同学。

注意宿舍号不足 6 位的,要按 6 位补齐前导 0。

输入样例:

7
000000 Tom 175 120
000001 Jack 180 130
000001 Hale 160 140
000000 Marry 160 120
000000 Jerry 165 110
000003 ETAF 183 145
000001 Mickey 170 115

输出样例:

000000 Tom 175 120
000001 Jack 180 130
000003 ETAF 183 145

代码解答: 

#include <iostream>
#include<iomanip>
using namespace std;
 
class student
{
public:
    int id;
    string name;
    int height;
    int weight;
    student(){id = -1;name = " "; height = 0; weight = 0;}
};
 
int main()
{
    int n, maxroom = 0;
    cin >> n;
    student *pstu = new student[n];
 
    for(int i = 0; i < n; i++)
    {
        cin >> pstu[i].id >> pstu[i].name >> pstu[i].height >> pstu[i].weight;
        if(maxroom <= pstu[i].id + 1)
        {
            maxroom = pstu[i].id + 1;
        }
    }
 
    int *p = new int [maxroom]; 
 
    for(int i = 0; i < maxroom; i++)
    {
        p[i] = -1;
    }
 
    for(int i = 0; i < n; i++)
    {
        if(pstu[i].height >= pstu[p[pstu[i].id]].height)
        {
            p[pstu[i].id] = i;
        }
    }
 
    for(int i = 0; i < maxroom; i++)
    {
        if(p[i] != -1)
        {
            cout << setfill('0') << setw(6) << i << " " << pstu[p[i]].name << " " << pstu[p[i]].height << " " << pstu[p[i]].weight << endl;
        }
    }
    delete[] p;
    delete[] pstu;
}

3、 队列操作

请实现一个MyQueue类,实现出队,入队,求队列长度.

实现入队函数 void push(int x);
实现出队函数 int pop();
实现求队列长度函数 int size();

输入格式:

每个输入包含1个测试用例。每个测试用例第一行给出一个正整数 n (n <= 10^6) ,接下去n行每行一个数字,表示一种操作:
1 x : 表示从队尾插入x,0<=x<=2^31-1。
2 : 表示队首元素出队。
3 : 表示求队列长度。

输出格式:

对于操作2,若队列为空,则输出 “Invalid”,否则请输出队首元素。 对于操作3,请输出队列长度。
每个输出项最后换行。

输入样例:

5
3
2
1 100
3
2

输出样例:

0
Invalid
1
100

代码解答: 

#include<iostream>
using namespace std;
#define MAXQSIZE 100
typedef struct
{
	int *base;
	int front;
	int rear;
}SqQueue;//定义队列元素

int InitQueue(SqQueue& q)
{
	q.base = new int[MAXQSIZE];
	if (!q.base){
        return 0;
    }
	q.front = 0;
	q.rear = 0;
	return 1;
}

int push(SqQueue& q, int x)
{
	if ((q.rear + 1) % MAXQSIZE == q.front)
		return 0;
	q.base[q.rear] = x;
	q.rear=q.rear + 1;
	return 1;
}

int pop(SqQueue& q)
{
	int e=0;
	if (q.rear == q.front)
		e=-1;
	else
	{
		e = q.base[q.front];
		q.front = q.front + 1;
	}
	return e;
}

int size(SqQueue& q)
{
	return q.rear-q.front;
}

int main()
{
	SqQueue q;
	InitQueue(q);
	int i, n, a, x,e;
	cin >> n;
	for (i = 0; i < n; i++)
	{
		cin >> a;
		switch (a)
		{
		case 1:
		{
			cin >> x;
			push(q, x);
			break;
		}
		case 2:
		{
			e=pop(q);
			if (e == -1)
			{
				cout << "Invalid" << endl;
				break;
			}
			cout <<e<< endl;
			break;
		}
		case 3:
		{
			cout << size(q) << endl;
			break;
		}
		}

	}
	return 0;
}

4、字符串排序--string类的使用

先输入你要输入的字符串的个数。然后换行输入该组字符串。每个字符串以回车结束,每个字符串不多于一百个字符。
如果在输入过程中输入的一个字符串为“stop”,也结束输入。
然后将这输入的该组字符串按每个字符串的长度,由小到大排序,按排序结果输出字符串。如果存在多个字符串长度相同,则按照原始输入顺序输出。

输入格式:

字符串的个数,以及该组字符串。每个字符串以‘\n’结束。如果输入字符串为“stop”,也结束输入.

输出格式:

可能有多组测试数据,对于每组数据,
将输入的所有字符串按长度由小到大排序输出(如果有“stop”,不输出“stop”)。

输入样例:

4
faeruhyytrjh tjytj
hsrthts   hjnshtgfhs
stop
3
htrskbns
bsartanjsf tyjndyt
nsr jj jtey

输出样例:

faeruhyytrjh tjytj
hsrthts   hjnshtgfhs
htrskbns
nsr jj jtey
bsartanjsf tyjndyt

提示:
根据输入的字符串个数来动态分配存储空间(采用new()函数)。每个字符串会少于100个字符。
测试数据有多组,注意使用while()循环输入。

代码解答:

#include<iostream>
#include<vector>
#include<string>
using namespace std;
typedef long long ll;
int main(){
    int n;
    string s;
    vector<string> v;
    while(cin>>n&&n){
        cin.get();
        while((n--) && getline(cin,s) && s!="stop"){
             v.push_back(s);
        }
        for(int i=0;i<v.size()-1;i++){
            for(int j=0;j<v.size()-i-1;j++){
                if(v[j].length()>v[j+1].length()){
                    string s=v[j];
                    v[j]=v[j+1];
                    v[j+1]=s;
                }
            }
        }
        for(int i=0,n=v.size();i<n;++i)
            cout<<v[i]<<endl;
        v.clear();
    }
    return 0;
}

5、友元函数的练习

定义Boat与Car两个类,两者都有私有的整型weight属性,定义两者的一个友元函数getTotalWeight(),计算二者的重量和。

参考主函数:

int main()
{
int n,m;
cin>>n>>m;
Boat boat(n);
Car car(m);
cout<<"船和汽车共重"<<getTotalWeight(boat,car)<<"吨"<<endl;
}

输入格式:

请在这里写输入格式。例如:输入在一行中给出2个整数m和n。

输出格式:

请在这里描述输出格式。例如:对每一组输入,在一行中输出:船和汽车共重M+n吨值。

输入样例:

在这里给出一组输入。例如:

40 30

输出样例:

在这里给出相应的输出。例如:

船和汽车共重70吨

代码解答: 

#include<iostream>
using namespace std;
class Car;
class Boat{
    private:
        int weight;
    public:
        Boat(int n){
            weight = n;
        }
    friend int getTotalWeight(Boat &b,Car &c);
};
class Car{
    private:
        int weight;
    public:
        Car(int n){
            weight = n;
        }
    friend int getTotalWeight(Boat &b,Car &c);
};
int getTotalWeight(Boat &b,Car &c){
	return b.weight+c.weight;
}
int main(){
    int n,m;
    cin >> n >> m;
    Boat boat(n);
    Car car(m);
    cout<<"船和汽车共重"<<getTotalWeight(boat,car)<<"吨"<<endl;
}

6、Disk Scheduling

Everyone knows that the files are stored in the magnetic disk. It reads the information according to the horizontal movement of the magnetic head on the track and the rotation of the magnetic disk. In order to reduce the file access time, many excellent disk scheduling algorithms have appeared.

In this problem, Shortest Seek Time First Algorithm (SSTF), which requires that the track to be accessed next is closest to the track where the current magnetic head is located. For example, given that the current magnetic head is on a track of 100, the number of tracks which need to be accessed is (55, 58, 39, 18, 90, 160, 150, 38, 184). Because 90 is the closest track to 100, the head moves to track 90 with a distance of 10 (∣100−90∣), and then finds the closest track to 90 is 58 and the distance is 32 (∣90−58∣), followed by 55 ... Finally, the resulting access sequence is (90, 58, 55, 39, 38, 18, 150, 160, 184), and the sum of the travel distances is ∣100−90∣ + ∣90−58∣ + ∣58−55∣ + ∣55−39∣ + ∣39−38∣ + ∣38−18∣ + ∣18−150∣ + ∣150−160∣ + ∣160−184∣ = 10 + 32 + 3 + 16 + 1 + 20 + 132 + 10 + 24 = 248.

Note that if there are multiple tracks with the smallest distance from the current track, the track with the smallest number will be taken as the next track.

Now given the number of the current magnetic head and the track sequence which you need to access, Little Gyro wants to calculate the sum of the magnetic head's moving distance.

Input Specification:

Each input file only contains one test case.

The first line contains two integer n, m (1 ≤ n ≤ 106, 1 ≤ m ≤ 109), indicating the length of the track sequence and the number of the current magnetic head.

The second line contains n integers a1​,a2​,...,an​ (1 ≤ ai​ ≤ 109), indicating the track sequence.

Output Specification:

For each test case output an integer indicating the sum of the magnetic head's moving distance.

Sample Input:

9 100
55 58 39 18 90 160 150 38 184

Sample Output:

248

Code Solution: 

#include <iostream>
#include <cstdio>
#include <cstring>
#include<algorithm>
#include<cmath>
using namespace std;
long long int a[1000005];
int main()
{
    long long int n, m, left, right, s = 0;
    scanf("%lld %lld", &n,&m);
    for (int i = 0; i < n; i++)
        scanf("%lld", &a[i]);
    sort(a, a + n);				//对n个数据进行排序
    for (int i = 1; i < n; i++)  		//将m值插入进去后,获取m左边的值left与右边的值right
    {
        if (m <= a[0])			//特判m是否比第一个值还小
        {
            left = -1;
            s = s + a[0] - m;
            m = a[0];
            right = 1;
            break;
        }
        if (m > a[n - 1])		//特判m是否比最后一个值还大
        {
            right = n;
            s = s + m - a[n - 1];
            m = a[n - 1];
            left = n - 2;
            break;
        }
        if (m >= a[i - 1] && m <= a[i])		//遍历搜索m在n个数据中,排到哪个位置
        {
            long long int sl,sr;
            sl = m - a[i-1];
            sr = a[i] - m;
            if (sl <= sr)
            {
                s = s + sl;
                m = a[i - 1];
                left = i - 2;
                right = i;
                break;
            }
            else
            {
                s = s + sr;
                m = a[i];
                left = i - 1;
                right = i+1;
                break;
            }
        }
    }
    while (left != -1 && right!=n)	//开始左右比较,并且累加s,替换m值
    {
        long long int sl, sr;
        sl =m-a[left];
        sr = a[right]-m;
        if (sl <= sr)
        {
            s = s + sl;
            m = a[left];
            left--;
        }
        else
        {
            s = s + sr;
            m = a[right];
            right++;
        }
    }
    if (left == -1)		//若m到达最左边后,只需不断计算右边没计算的值
    {
        while (right != n)
        {
            long long int sr;
            sr = a[right]-m;
            s = s + sr;
            m = a[right];
            right++;
        }
    }
    if (right == n)		//若m到达最右边后,只需不断计算左边没计算的值
    {
        while (left != -1)
        {
            long long int sl;
            sl = m - a[left];
            s = s + sl;
            m = a[left];
            left--;
        }
    }
    printf("%lld\n", s);
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
实验一: Java编程基础 (1) 配置环境变量,熟悉编程环境。 (2) 建立一个Java的Application程序,编译、运行以下例题: public class ex01 { public static void main( String arg[ ]) { System.out.println(“hello!”); } } 实验二:流程控制 (1) 编程输出100以内的奇数。 (2) 编程输出乘法表。 (3) 编写程序,定义一个一维数组并赋有初值,同时找出一维数组的最大值和最小值并输出。 实验三:和对象 (1) 设计一个User,其包括用户名、口令等属性以及构造方法(至少重载2个)、获取和设置口令的方法、显示和修改用户名的方法等。编写应用程序测试User。 (2) 定义一个Student,其包括学号、姓名、性别、出生年月等属性以及init( )——初始化各属性、display( )——显示各属性、modify( )¬——修改姓名等方法。实现并测试这个。 (3) 从上题的Student派生出Graduate(研究生),添加属性:专业subject、导师adviser。重载相应的成员方法。并测试这个。 实验四:的继承 (1) 定义一个Animal,其包括昵称、性别、体重属性,构造函数初始化各属性,显示各属性的成员函数、修改属性的成员函数。实现并测试这个。 (2) 从上题的派生出Dog,添加年龄属性。重载相应的成员方法,并添加新的方法bark(),输出“wangwangwang”。并测试这个。 实验五:接口 (1) 定义一个接口Inf,含有常量π和一个实现计算功能的方法calculate( ),再分别定义一个面积area和一个周长circumference,各自按计算圆面积和圆周长具体实现接口的方法,并以半径为5来测试两个。 (2) 定义一个接口run(),汽车和卡车分别实现这个,汽车实现这个接口输出的是“汽车在跑”,卡车输出的是“卡车在跑”,丰富这两个,在主程序测试。 实验六:异常处理 (1) 定义一个,在main方法的try块产生并抛出一个异常,在catch块捕获异常,并输出相应信息,同时加入finally子句,输出信息,证明它的无条件执行。 (2) *定义一个Caculate实现10以内的整数加减法的计算。自定义一个异常NumberRangeException,当试图进行超范围运算时,产生相应的信息。编写应用程序进行测试。 实验七:图形界面编程 (1) 在窗体上产生一个单文本框和两个命令按纽:“显示”和“清除”。当用户单击“显示”按纽时,在文本框显示“Java 程序”字样;单击“清除”按纽时清空文本框。 (2)设计如下界面: 当用户输入了两个操作数并点击运算种按纽后,在运算结果对应的文本框显示运算结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

博学者普克尔特

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值