面向对象程序设计-10-期中综合练习

声明

题解包含以下内容:

  • (相对)高级的 C++ 模板及语法技巧
  • 仅适用于 C++20 标准的代码
  • 强烈的个人代码风格和 Modern C++ 范式追求
  • 泛滥的标准库函数

换句话说就是(相较于其他公开题解)更低的查重率和更高的使用门槛;请酌情使用。

【id:112】【20分】A. 向量1(类和对象)

题目描述

n个有序数a1,a2,…,an组成的数组称为n维向量。 为n维向量定义CVector类,包含私有数据成员:

int *data;//存储n维向量

int n; //向量维数。

方法有:

(1)无参构造函数,设置n=5,data的数据分别为0,1,2,3,4;

(2)构造函数,用虚参n1和数组a初始化n和data的数据;

(3)输出函数,按格式输出n维向量的值;

(4)析构函数。

主函数输入数据,生成CVector对象并调用输出函数测试。

输入

输入n

输入n维向量

输出

分别调用无参和带参构造函数生成2个CVector对象,输出它们的值。

样例

输入样例1输出样例1
6
10 1 2 3 4 5
0 1 2 3 4
10 1 2 3 4 5

Answer

#include <bits/stdc++.h>
using namespace std;

inline int __init_arr[5] = { 0, 1, 2, 3, 4 };

class CVector {
  static int sum;

  int* data;
  int n;

public:
  static int get_sum() { return sum; }
  static void reset_sum() { sum = 0; }

  CVector( int nn, const int* dat )
    : data { nullptr }, n { nn } {
    data = new int[n] {};
    memcpy( data, dat, n * sizeof( int ) );
  }
  CVector( const CVector& lhs )
    : CVector( lhs.n, lhs.data ) {}
  CVector( CVector&& rhs ) {
    data = rhs.data;
    rhs.data = nullptr;
    n = rhs.n;
  }
  CVector() : CVector( 5, __init_arr ) {}
  ~CVector() { delete[] data; }
  void print() const {
    if ( data == nullptr ) return;
    for ( size_t i = 0; i < static_cast<size_t>(n); ++i )
      cout << (i != 0 ? " " : "") << data[i];
    cout << endl;
  }
  void scanner( int nn ) {
    if ( n != nn ) {
      n = nn; delete[] data;
      data = new int [n] {};
    }
    for ( size_t i = 0; i < static_cast<size_t>(n); ++i )
      cin >> data[i];
    sum += accumulate( data, data + n, 0 );
  }
  float Average() const {
    return accumulate( data, data + n, 0.0f ) / n;
  }
  friend ostream& operator<<( ostream& os, const CVector& v ) {
    if ( v.data == nullptr ) return os;
    for ( size_t i = 0; i < static_cast<size_t>(v.n); ++i )
      os << (i != 0 ? " " : "") << v.data[i];
    return os;
  }
  friend CVector add( const CVector& v1, const CVector& v2 ) {
    if ( v1.n != v2.n ) return {};
    auto ret = v1;
    transform( v2.data, v2.data + v2.n, v1.data, ret.data, plus<int>() );
    return ret;
  }
};

int CVector::sum = 0;

int main()
{
  int n {}; cin >> n;
  CVector v1, v2;
  v2.scanner( n );
  cout << v1 << endl
    << v2 << endl;
}

【id:113】【20分】B. 向量2(友元及拷贝构造)

题目描述

在题目向量1的代码上添加类CVector的友元函数add,计算两个向量的和(对应分量相加)。

add定义如下:

CVector add(const CVector v1, const CVector v2) //函数头不可修改。

主函数输入数据,生成两个向量对象v1,v2,调用add(v1, v2).print()输出向量v1 + v2的计算结果。(假设print()为CVector类中的输出函数。)

可根据需要,为类CVector添加拷贝构造函数及其它成员函数。

输入

第一行,输入测试次数t

每组测试数据格式如下:

向量维数n

第一个n维向量值

第二个n维向量值

输出

对每组测试数据,输出两个n维向量与它们的和

样例

输入样例1输出样例1
2
3
1 2 3
4 5 6
5
1 2 3 4 5
-1 2 4 6 10
1 2 3
4 5 6
5 7 9
1 2 3 4 5
-1 2 4 6 10
0 4 7 10 15

Answer

#include <bits/stdc++.h>
using namespace std;

inline int __init_arr[5] = { 0, 1, 2, 3, 4 };

class CVector {
  static int sum;

  int* data;
  int n;

public:
  static int get_sum() { return sum; }
  static void reset_sum() { sum = 0; }

  CVector( int nn, const int* dat )
    : data { nullptr }, n { nn } {
    data = new int[n] {};
    memcpy( data, dat, n * sizeof( int ) );
  }
  CVector( const CVector& lhs )
    : CVector( lhs.n, lhs.data ) {}
  CVector( CVector&& rhs ) {
    data = rhs.data;
    rhs.data = nullptr;
    n = rhs.n;
  }
  CVector() : CVector( 5, __init_arr ) {}
  ~CVector() { delete[] data; }
  void print() const {
    if ( data == nullptr ) return;
    for ( size_t i = 0; i < static_cast<size_t>(n); ++i )
      cout << (i != 0 ? " " : "") << data[i];
    cout << endl;
  }
  void scanner( int nn ) {
    if ( n != nn ) {
      n = nn; delete[] data;
      data = new int [n] {};
    }
    for ( size_t i = 0; i < static_cast<size_t>(n); ++i )
      cin >> data[i];
    sum += accumulate( data, data + n, 0 );
  }
  float Average() const {
    return accumulate( data, data + n, 0.0f ) / n;
  }
  friend ostream& operator<<( ostream& os, const CVector& v ) {
    if ( v.data == nullptr ) return os;
    for ( size_t i = 0; i < static_cast<size_t>(v.n); ++i )
      os << (i != 0 ? " " : "") << v.data[i];
    return os;
  }
  friend CVector add( const CVector& v1, const CVector& v2 ) {
    if ( v1.n != v2.n ) return {};
    auto ret = v1;
    transform( v2.data, v2.data + v2.n, v1.data, ret.data, plus<int>() );
    return ret;
  }
};

int CVector::sum = 0;

int main()
{
  size_t t {}; cin >> t;
  while ( t-- ) {
    int n {}; cin >> n;
    CVector v1, v2;
    v1.scanner( n );
    v2.scanner( n );
    cout << v1 << endl
      << v2 << endl
      << add( v1, v2 ) << endl;
  }
}

【id:114】【20分】C. 向量3(静态成员)

题目描述

为向量1题目实现的CVector类添加私有静态成员sum,在初始化对象的同时,统计所有对象的n维向量和sum。

主函数生成多个对象,测试向量和。

可根据需要自行添加需要的静态成员函数,添加非静态成员函数不得分。

输入

测试次数t

每组测试数据格式如下:

输入m,表示n维向量的数目

后跟m行,每行格式:向量维数n n维向量值

输出

对每组测试数据的m个向量,输出所有向量的分量和sum

样例

输入样例1输出样例1
2
2
5 1 2 3 4 5
3 4 5 6
3
2 1 2
3 10 20 30
2 11 22
1 2 3 4 5
4 5 6
30
1 2
10 20 30
11 22
96

Answer

#include <bits/stdc++.h>
using namespace std;

inline int __init_arr[5] = { 0, 1, 2, 3, 4 };

class CVector {
  static int sum;

  int* data;
  int n;

public:
  static int get_sum() { return sum; }
  static void reset_sum() { sum = 0; }

  CVector( int nn, const int* dat )
    : data { nullptr }, n { nn } {
    data = new int[n] {};
    memcpy( data, dat, n * sizeof( int ) );
  }
  CVector( const CVector& lhs )
    : CVector( lhs.n, lhs.data ) {}
  CVector( CVector&& rhs ) {
    data = rhs.data;
    rhs.data = nullptr;
    n = rhs.n;
  }
  CVector() : CVector( 5, __init_arr ) {}
  ~CVector() { delete[] data; }
  void print() const {
    if (data == nullptr) return;
    for ( size_t i = 0; i < static_cast<size_t>(n); ++i )
      cout << (i != 0 ? " " : "") << data[i];
    cout << endl;
  }
  void scanner( int nn ) {
    if ( n != nn ) {
      n = nn; delete[] data;
      data = new int [n] {};
    }
    for ( size_t i = 0; i < static_cast<size_t>(n); ++i )
      cin >> data[i];
    sum += accumulate( data, data + n, 0 );
  }
  float Average() const {
    return accumulate( data, data + n, 0.0f ) / n;
  }
  friend ostream& operator<<( ostream& os, const CVector& v ) {
    if ( v.data == nullptr ) return os;
    for ( size_t i = 0; i < static_cast<size_t>(v.n); ++i )
      os << (i != 0 ? " " : "") << v.data[i];
    return os;
  }
  friend CVector add( const CVector& v1, const CVector& v2 ) {
    if ( v1.n != v2.n ) return {};
    auto ret = v1;
    transform( v2.data, v2.data + v2.n, v1.data, ret.data, plus<int>() );
    return ret;
  }
};

int CVector::sum = 0;

int main()
{
  size_t t {}; cin >> t;
  while ( t-- ) {
    int m {}; cin >> m;
    while ( m-- ) {
      int n {}; cin >> n;
      CVector v {};
      v.scanner( n );
      cout << v << endl;
    }
    cout << CVector::get_sum() << endl;
    CVector::reset_sum();
  }
}

【id:115】【20分】D. 向量4(类复合)

题目描述

为向量1题目中实现的CVector类增加成员函数float Average(),计算n维向量的平均值并返回。

定义CStudent类,私有数据成员为:

string name; // 姓名

CVector score; // n个成绩

(1)添加构造函数,用虚参name1、n1、数组a1初始化CStudent类对象。

(2)添加输出函数,按样例格式输出CStudent对象值。

主函数输入数据,测试CStudent对象。

输入

输入多行,每行格式为:学生姓名 科目n n个成绩

输出

对每行测试数据,生成学生对象,输出如下数据:

学生姓名 n个成绩 成绩的平均值(保留2位小数)

样例

输入样例1输出样例1
wangwu 5 90 80 70 100 90
lisi 3 100 90 100
wangwu 90 80 70 100 90 86.00
lisi 100 90 100 96.67

Answer

#include <bits/stdc++.h>
using namespace std;

inline int __init_arr[5] = { 0, 1, 2, 3, 4 };

class CVector {
  static int sum;

  int* data;
  int n;

public:
  static int get_sum() { return sum; }
  static void reset_sum() { sum = 0; }

  CVector( int nn, const int* dat )
    : data { nullptr }, n { nn } {
    data = new int[n] {};
    memcpy( data, dat, n * sizeof( int ) );
  }
  CVector( const CVector& lhs )
    : CVector( lhs.n, lhs.data ) {}
  CVector( CVector&& rhs ) {
    data = rhs.data;
    rhs.data = nullptr;
    n = rhs.n;
  }
  CVector() : CVector( 5, __init_arr ) {}
  ~CVector() { delete[] data; }
  void print() const {
    if ( data == nullptr ) return;
    for ( size_t i = 0; i < static_cast<size_t>(n); ++i )
      cout << (i != 0 ? " " : "") << data[i];
    cout << endl;
  }
  void scanner( int nn ) {
    if ( n != nn ) {
      n = nn; delete[] data;
      data = new int [n] {};
    }
    for ( size_t i = 0; i < static_cast<size_t>(n); ++i )
      cin >> data[i];
    sum += accumulate( data, data + n, 0 );
  }
  float Average() const {
    return accumulate( data, data + n, 0.0f ) / n;
  }
  friend ostream& operator<<( ostream& os, const CVector& v ) {
    if ( v.data == nullptr ) return os;
    for ( size_t i = 0; i < static_cast<size_t>(v.n); ++i )
      os << (i != 0 ? " " : "") << v.data[i];
    return os;
  }
  friend CVector add( const CVector & v1, const CVector & v2 ) {
    if ( v1.n != v2.n ) return {};
    auto ret = v1;
    transform( v2.data, v2.data + v2.n, v1.data, ret.data, plus<int>() );
    return ret;
  }
  friend istream& operator>>( istream& is, CVector& v ) {
    int nn {}; is >> nn;
    if ( v.n != nn ) {
      v.n = nn; delete[] v.data;
      v.data = new int [v.n] {};
    }
    for ( size_t i = 0; i < static_cast<size_t>(v.n); ++i )
      is >> v.data[i];
    sum += accumulate( v.data, v.data + v.n, 0 );
    return is;
  }
};

int CVector::sum = 0;

class CStudent {
  string name;
  CVector score;

public:
  CStudent( string name1, int n1, const int* a1 )
    : name { move( name ) }, score { n1, a1 } {}
  CStudent( string name1, CVector score1 )
    : name { move( name1 ) }, score { move( score1 ) } {}
  CStudent() : CStudent( {}, {} ) {}
  void print() const {
    cout << name << ' '
      << score << ' '
      << fixed << setprecision( 2 )
      << score.Average() << endl;
  }
  friend ostream& operator<<( ostream& os, const CStudent& lhs ) {
    return os << lhs.name << ' '
      << lhs.score << ' '
      << fixed << setprecision( 2 )
      << lhs.score.Average() << endl;
  }
  friend istream& operator>>( istream& is, CStudent& lhs ) {
    return is >> lhs.name >> lhs.score;
  }
};

int main()
{
  CStudent stu;
  while ( cin >> stu )
    cout << stu;
}

【id:116】【20分】E. 向量5(友元类)

题目描述

lab10-E-1

(1)在向量CVector类的代码上,定义n阶矩阵类CMatrix,包含私有数据成员data存储矩阵数据,n存储矩阵阶数。

(2)将CMatrix定义为CVector的友元类。

(3)为CMatrix添加成员函数:CVector multi(const CVector &v1),计算n阶矩阵与n维向量v1的乘积。

(4)为CMatrix添加成员函数,判定矩阵与向量v1是否可计算乘积。

(5)为CMatrix添加需要的构造函数、析构函数和其它成员函数。

主函数输入数据,测试矩阵与向量的乘积。

动态创建n阶矩阵示例代码如下:

int n;
int** data;
int i, j;
cin >> n;
// 先创建n行
data = new int* [n];
// 再创建n列
for (i = 0; i < n; i++)
{

    data[i] = new int[n];

}
// 写入矩阵
for (i = 0; i < n; i++)
{
    for (j = 0; j < n; j++)
    {
        cin >> data[i][j];
    }

}

输入

测试次数t

对每组测试数据,格式如下

第一行,矩阵阶数n

n阶矩阵

向量维数m

m维向量

输出

对每组测试数据,若矩阵与向量不能计算乘积,输出error;否则输出计算结果

样例

输入样例1输出样例1
1
3
1 0 0
0 1 0
0 0 1
3
1 2 3
1 2 3

Answer

#include <bits/stdc++.h>
using namespace std;

inline int __init_arr[5] = { 0, 1, 2, 3, 4 };

class CMatrix;

class CVector {
  static int sum;

  int* data;
  int n;

public:
  static int get_sum() { return sum; }
  static void reset_sum() { sum = 0; }

  CVector( int nn, const int* dat )
    : data { nullptr }, n { nn } {
    data = new int[n] {};
    memcpy( data, dat, n * sizeof( int ) );
  }
  CVector( const CVector& lhs )
    : CVector( lhs.n, lhs.data ) {}
  CVector( CVector&& rhs ) {
    data = rhs.data;
    rhs.data = nullptr;
    n = rhs.n;
  }
  CVector() : CVector( 5, __init_arr ) {}
  ~CVector() { delete[] data; }
  void print() const {
    if ( data == nullptr ) return;
    for ( size_t i = 0; i < static_cast<size_t>(n); ++i )
      cout << (i != 0 ? " " : "") << data[i];
    cout << endl;
  }
  void scanner( int nn ) {
    if ( n != nn ) {
      n = nn; delete[] data;
      data = new int [n] {};
    }
    for ( size_t i = 0; i < static_cast<size_t>(n); ++i )
      cin >> data[i];
    sum += accumulate( data, data + n, 0 );
  }
  float Average() const {
    return accumulate( data, data + n, 0.0f ) / n;
  }
  CVector& operator=( const CVector& lhs ) {
    if ( this != &lhs ) {
      delete[] data; n = lhs.n;
      data = new int[n] {};
      memcpy( data, lhs.data, n * sizeof( int ) );
    }
    return *this;
  }
  CVector& operator=( CVector&& lhs ) {
    if ( this != &lhs ) {
      delete[] data;
      n = lhs.n;
      data = lhs.data;
      lhs.data = nullptr;
    }
    return *this;
  }
  friend ostream& operator<<( ostream& os, const CVector& v ) {
    if ( v.data == nullptr ) return os;
    for ( size_t i = 0; i < static_cast<size_t>(v.n); ++i )
      os << (i != 0 ? " " : "") << v.data[i];
    return os;
  }
  friend CVector add( const CVector& v1, const CVector& v2 ) {
    if ( v1.n != v2.n ) return {};
    auto ret = v1;
    transform( v2.data, v2.data + v2.n, v1.data, ret.data, plus<int>() );
    return ret;
  }
  friend istream& operator>>( istream& is, CVector& v ) {
    int nn {}; is >> nn;
    if ( v.n != nn ) {
      v.n = nn; delete[] v.data;
      v.data = new int [v.n] {};
    }
    for ( size_t i = 0; i < static_cast<size_t>(v.n); ++i )
      is >> v.data[i];
    sum += accumulate( v.data, v.data + v.n, 0 );
    return is;
  }
  friend class CMatrix;
};

int CVector::sum = 0;

class CMatrix {
  CVector* data;
  int n;

public:
  CMatrix( int nn, CVector* dat )
    : data { nullptr }, n { nn } {
    data = dat;
  }
  CMatrix() : data { nullptr }, n { 0 } {}
  ~CMatrix() { delete[] data; }
  CVector multi( const CVector& v1 ) const {
    CVector ret { v1 };
    for ( size_t i = 0; i < static_cast<size_t>(n); ++i ) {
      ret.data[i] = 0;
      for ( size_t ii = 0; ii < static_cast<size_t>(data[i].n); ++ii )
        ret.data[i] += data[i].data[ii] * v1.data[ii];
    }
    return ret;
  }
  bool can_mul( const CVector& v1 ) const {
    return n == v1.n;
  }
};

int main()
{
  size_t t {}; cin >> t;
  while ( t-- ) {
    int n {}; cin >> n;

    auto vec_list = new CVector[n] {};
    for ( int i = 0; i < n; ++i ) {
      auto input = new int[n] {};
      for ( int ii = 0; ii < n; ++ii )
        cin >> input[ii];
      vec_list[i] = CVector( n, input );
      delete[] input;
    }
    CMatrix mat { n, vec_list };
    vec_list = nullptr;
    // vec_list 所有权已转移

    int m {}; cin >> m;
    auto input = new int[m] {};
    for ( int i = 0; i < m; ++i )
      cin >> input[i];
    CVector vec { m, input };
    delete[] input;

    if ( mat.can_mul( vec ) )
      cout << mat.multi( vec ) << endl;
    else cout << "error" << endl;
  }
}
向量类(综合型题目) (1)创建C# 控制台应用程序L4_2。 (2)在程序中创建一个向量类CzVector,在其中定义一个double []类型的私有字段_values,用于维护向量的各个元素值。 (3)为CzVector定义三个公有属性Length、Sum和Prod,分别用于返回向量的长度、向量所有元素的和以及向量所有元素的积。 (4)在CzVector中定义一个索引函数,用于获取或设置各个元素的值。 (5)为CzVector定义两个构造函数,一个根据指定长度对向量进行初始化(向量各元素取默认值0),另一个由指定的数组来构造向量并设置各元素的值。 (6)利用操作符重载来实现向量加法、减法和乘法。这三种运算均要求两个向量的长度相等。设向量α=(a1,a2,…an) ,β=(b1,b2,…bn),那么α+β=(a1+b1,a2+b2,….,an+bn),减法与之类似,而α*β=a1*b1+a2*b2+….+an*bn)。另外,一个向量还可以单独乘以一个系数(向量加法的重载形式),此时,λ*α=(λ*a1, λ*a2,…λ*an) 。以加法操作符重载为例,参考源代码如下: public static CzVector operator +(CzVector v1,CzVector v2) { if(v1.Length!=v2.Length) return null; CzVector result=new CzVector(v1.Length); for(int i=0;i<v1.Length;i++) result [i]=v1[i]+v2[i]; return result; } (7)类似的,利用操作符重载来判断两个向量是否相等。向量相等的条件是:两个向量的长度相等,且各个位置上的对应元素值也相等。 (8)为CzVector定义一个ConsoleOutput方法,用于在控制台一行输出向量的所有元素,其之间以空格分割。 (9)在程序主方法中随机定义几个向量对象,并测试其运算结果。参考源代码如下: static void Main() { CzVector v1=new CzVector(1,-5,9,6); CzVector v2=new CzVector(0,1,2,3); Console.Write(“v1= “); v1.ConsoleOutput(); Console.Write(“v2= “); v2.ConsoleOutput(); CzVector v3=v1+v2; Console.Write(“v1+v2= “); v3.ConsoleOutput(); CzVector v4=v1-v2; Console.Write(“v1-v2= “); v4.ConsoleOutput(); Console.Write(“3*(v1+v2)= “); (v3*3).ConsoleOutput(); Console.Write(“v1*v2= “{0}”,v1*v2); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值