课程:北京大学程序设计与算法(三) MOOC
OJ: OpenJudge
005 编程填空:学生信息处理程序
这个题对于初学来说有一点难度,需要了解相关库函数,本文会将实现代码的函数进行简单的说明。
成员变量:
name 姓名,age 年龄,id 学号,grade[4] 四年成绩,avg 平均成绩,初值为0.
private:
string name;
int age;
string id;
int grade[4];
double avg = 0;
注意avg为浮点类型
成员函数:
input():
需要对成员变量进行初始化,但是由于输入的数据为一行,且有逗号隔开,需要我们对输入数据进行处理才能对变量进行赋值。
首先,将数据读入,为了后面使用,我用string类型来存这串字符
string a;
getline(cin, a);
getline(cin, str)
是 C++ 中用来从标准输入流 cin
中读取一行字符串并存储在字符串变量 str
中,初学先记住这么用会使用我认为就可以了
这里我们介绍4个函数:stoi()、erase()、substr() 、find() 都位于头文件<<string>>里面
stoi(): stoi(字符串,起始位置,2~32进制),将n进制的字符串转化为十进制。
erase(): erase(pos,shul) 删pos位置的后shul个字符
substr(): substr(pos,shul) pos开始截取shul个字符
find(): find(“sada”,0) //没找到返回-1,找到返回所在的起始位置
那么具体该如何使用?我们以这道题为例,我们可以用substr()和find()来截取起始位置到逗号处字符然后存到变量中,然后用erase()将已截取的代码都删掉。如果碰到整型(如age)用stoi()将其转换成数字存入即可。
比如:
name = a.substr(0, a.find(','));
a.erase(0, a.find(',') + 1);
截取a中从0到逗号之间的位置,此处虽然第二个参数用find返回逗号的下标,但是其下标在哪就截取几个(比如逗号位于1处,截取1个字符,刚好符合我们需要)。再用erase删除,此处find()y用法跟刚才一样,但要+1,把逗号删去。
calculate():
这个就比较简单了,只需要用循环遍历grade数组,都加到avg上即可。
void output():
使用cout输出所需要变量即可。
完整成员函数代码如下:
public:
void input()
{
string a;
getline(cin, a);
name = a.substr(0, a.find(','));
a.erase(0, a.find(',') + 1);
age = stoi(a.substr(0, a.find(',')));
a.erase(0, a.find(',') + 1);
id= a.substr(0, a.find(','));
a.erase(0, a.find(',') + 1);
for (int i = 0; i < 3; i++)
{
grade[i]= stoi(a.substr(0, a.find(',')));
a.erase(0, a.find(',') + 1);
}
grade[3] = stoi(a);
}
void calculate()
{
for (int i = 0; i < 4; i++)
avg += grade[i];
avg /= 4;
}
void output()
{
cout << name << ',' << age << ',' << id << ',' << avg;
}
该题完成程序如下:
#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <sstream>
#include <cstdlib>
using namespace std;
class Student {
private:
string name;
int age;
string id;
int grade[4];
double avg = 0;
public:
void input()
{
string a;
getline(cin, a);
name = a.substr(0, a.find(','));
a.erase(0, a.find(',') + 1);
age = stoi(a.substr(0, a.find(',')));
a.erase(0, a.find(',') + 1);
id= a.substr(0, a.find(','));
a.erase(0, a.find(',') + 1);
for (int i = 0; i < 3; i++)
{
grade[i]= stoi(a.substr(0, a.find(',')));
a.erase(0, a.find(',') + 1);
}
grade[3] = stoi(a);
}
void calculate()
{
for (int i = 0; i < 4; i++)
avg += grade[i];
avg /= 4;
}
void output()
{
cout << name << ',' << age << ',' << id << ',' << avg;
}
};
int main() {
Student student; // 定义类的对象
student.input(); // 输入数据
student.calculate(); // 计算平均成绩
student.output(); // 输出数据
}
006 奇怪的类复制
这个题主要是了解复制构造函数调用情况
Sample a(5);
Sample b = a;
PrintAndDouble(b);
Sample c = 20;
PrintAndDouble(c);
Sample d;
d = a;
cout << d.v;
第二行 b 初始化时调用一次,PrintAndDouble中作为参数时又调用一次
c初始化正常调用构造函数,PrintAndDouble中作为参数时又调用一次
b输出前出现两次调用,c只有一次。
若是正常复制答案应为5 20 5,但此处b多了4,c多了2,可知拷贝构造函数需+2
该题完整代码如下:
#include <iostream>
using namespace std;
class Sample {
public:
int v;
Sample() {}
Sample(int i)
{
v = i;
}
Sample(const Sample& s)
{
v = s.v +2;
}
};
void PrintAndDouble(Sample o)
{
cout << o.v;
cout << endl;
}
int main()
{
Sample a(5);
Sample b = a;
PrintAndDouble(b);
Sample c = 20;
PrintAndDouble(c);
Sample d;
d = a;
cout << d.v;
return 0;
}
008:超简单的复数类
这个题考察类型转换构造函数,我们先将默认构造函数写出来,再写一个参数为字符型数组的构造函数,函数体里对成员变量进行赋值。
该题完整代码如下:
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
class Complex {
private:
double r,i;
public:
void Print() {
cout << r << "+" << i << "i" << endl;
}
//填写你的代码
Complex() {
}
Complex( const char a[10])
{
r = a[0]-'0'; i = a[2]-'0';
}
//结束
};
int main() {
Complex a;
a = "3+4i"; a.Print();
a = "5+6i"; a.Print();
return 0;
}
009:哪来的输出
这个题面有两个对象生成,第一个存了1,第二个存了2,第二个先析构,只需析构时编写输出代码即可。
完整代码如下:
#include <iostream>
using namespace std;
class A {
public:
int i;
A(int x) { i = x; }
~A()
{
cout << i << endl;
}
};
int main()
{
A a(1);
A * pa = new A(2);
delete pa;
return 0;
}