// 1. 先处理 from clause 收集表信息
// from 中的 table 有两个层级 第一级是笛卡尔积 第二级是 INNER JOIN
// e.g. (t1 inner join t2 inner join t3, t4) -> (t1, t2, t3), (t4)
-
- 当
FROM
子句中列出多个表时,如果没有指定连接条件(即没有JOIN
子句),那么这些表将会进行笛卡尔积操作。这意味着第一个表中的每一行都会与第二个表中的每一行组合,以此类推,结果是一个行数为每个表行数乘积的大表。 - 例如,如果有三个表
t1
、t2
和t3
,那么FROM t1, t2, t3
会产生t1
的行数乘以t2
的行数再乘以t3
的行数的结果集。
- 当
6-1 表彰优秀学生(多态)
#include<iostream>
#include <string>
using namespace std;
//有两门课程,对两门课程的分数求个平均,比较这个分数的排名
//对于第一个条件,记录最高分?
//添加类的静态变量,在构造函数里,对静态变量进行累加
class Student {
public:
virtual void display() = 0;
static double max;
protected:
string num;
string name;
};
double avg = 0.0;
double Student::max = 0;
class GroupA :public Student {
public:
void display() {
if (this->score >= avg) {
cout << this->num << " " << this->name << endl;
return;
}
}
GroupA(string num, string name, int s1, int s2) {
this->num = num;
this->name = name;
this->s1 = s1;
this->s2 = s2;
this->score = (double)(s1 + s2) / (2.0);
avg = max(avg, this->score);
}
private:
int s1;
int s2;
double score;
};
class GroupB :public Student {
public:
GroupB(string num, string name, int s1, int s2, char gs) {
this->num = num;
this->name = name;
this->s1 = s1;
this->s2 = s2;
this->s = gs;
this->score = (double)(s1 + s2) / (2.0);
avg = max(avg, this->score);
}
void display() {
if (this->score >= avg) {
cout << this->num << " " << this->name << endl;
return;
}
if ((this->score >= avg * 0.7) && (this->s == 'A')) {
cout << this->num << " " << this->name << endl;
return;
}
}
private:
int s1;
int s2;
char s;
double score;
};
class GroupC :public Student {
public:
GroupC(string num, string name, int s1, int s2, int s3, int s4, int s5) {
this->num = num;
this->name = name;
this->s1 = s1;
this->s2 = s2;
this->s3 = s3;
this->s4 = s4;
this->s5 = s5;
this->score = (double)(s1 + s2 + s3 + s4 + s5) / (5.0);
}
void display() {
if (this->score >= avg * 0.9) {
cout << this->num << " " << this->name << endl;
return;
}
}
private:
int s1;
int s2;
int s3;
int s4;
int s5;
double score;
};
/* 请在这里填写答案 */
int main()
{
const int Size = 50;
string num, name;
int i, ty, s1, s2, s3, s4, s5;
char gs;
Student* pS[Size];
int count = 0;
for (i = 0; i < Size; i++) {
cin >> ty;
if (ty == 0) break;
cin >> num >> name >> s1 >> s2;
switch (ty) {
case 1:pS[count++] = new GroupA(num, name, s1, s2); break;
case 2:cin >> gs; pS[count++] = new GroupB(num, name, s1, s2, gs); break;
case 3:cin >> s3 >> s4 >> s5; pS[count++] = new GroupC(num, name, s1, s2, s3, s4, s5); break;
}
}
for (i = 0; i < count; i++) {
pS[i]->display();
delete pS[i];
}
return 0;
}

#include<iostream>
#include <string>
using namespace std;
struct Node {
string name;
int start;
int end;
Node* next;
};
Node* add(Node*, Node*);
void display(Node*);
bool check(Node* head)
{
if (head == NULL || head->next == NULL) return true;
Node* p = head->next;
if (head->start > p->start) return false;
return check(p);
}
int main()
{
Node* head = NULL, * p;
int i, repeat;
cin >> repeat;
for (i = 0; i < repeat; i++) {
p = new Node;
cin >> p->name >> p->start >> p->end;
p->next = NULL;
head = add(head, p);
//cout << "此时head的name为" << head->name << endl;
}
if (!check(head)) cout << "ERROR" << endl;
display(head);
return 0;
}
//存储顺序按照开始时间递增的顺序,
Node* add(Node* head, Node* p) {
if (head == NULL) {
head = p;
return head;
}
Node* curNode = head;
while (curNode->start < p->start) {
if (curNode->next == NULL) {
break;
}
if (curNode->next->start > p->start) {
break;
}
curNode = curNode->next;
}
//cout << "此时要插入的前一个Node的start是 " << curNode->start << "插入的值是 " << p->start << endl;
p->next = curNode->next;
curNode->next = p;
return head;
}
void display(Node* head) {
if (head == NULL) {
return;
}
Node* curNode = head;
int lastT = 0;
while (curNode) {
//cout << "此时遍历了一个结点为 " << curNode->name;
Node* nxtNode = curNode->next;
if ((curNode->start < lastT)||((nxtNode != NULL)&& (curNode->end > nxtNode->start))) {
cout << "*";
}
lastT = max(curNode->end, lastT);
//cout << "它的下一个节点是" << (nxtNode == NULL ? "NULL" : nxtNode->name) << endl;
cout << curNode->name << " " << curNode->start << " " << curNode->end << endl;
curNode = nxtNode;
}
}
/* 请在这里填写答案 */

并没有考虑到新插入的结点比头节点小的情况
加入对头节点的特判后,解决

//存储顺序按照开始时间递增的顺序,
Node* add(Node* head, Node* p) {
if (head == NULL) {
head = p;
return head;
}
if(head->start>p->start){
p->next=head;
head=p;
return head;
}
Node* curNode = head;
while (curNode->start < p->start) {
if (curNode->next == NULL) {
break;
}
if (curNode->next->start > p->start) {
break;
}
curNode = curNode->next;
}
//cout << "此时要插入的前一个Node的start是 " << curNode->start << "插入的值是 " << p->start << endl;
p->next = curNode->next;
curNode->next = p;
return head;
}
void display(Node* head) {
if (head == NULL) {
return;
}
Node* curNode = head;
int lastT = 0;
while (curNode) {
//cout << "此时遍历了一个结点为 " << curNode->name;
Node* nxtNode = curNode->next;
if ((curNode->start < lastT)||((nxtNode != NULL)&& (curNode->end > nxtNode->start))) {
cout << "*";
}
lastT = max(curNode->end, lastT);
//cout << "它的下一个节点是" << (nxtNode == NULL ? "NULL" : nxtNode->name) << endl;
cout << curNode->name << " " << curNode->start << " " << curNode->end << endl;
curNode = nxtNode;
}
}
=========
6-3 学生排名表(析构函数)
很抽象的一个问题,禁止直接访问私有成员,但是又没有提供相应的函数
sort(pS,pS+count,[](Student *a, Student *b){
return a->getRank()<b->getRank();
});
// for(int i=0;i<count;i++){
// cout<<pS[i]->name<<endl;
// }
用sort的话,又没有相应的algoritthm头文件
冒泡排序
cpp
for(int i=count;i>0;i--){
for(int j=1;j<i;j++){
if(pS[j]->getRank()<pS[j-1]->getRank()){
temp=pS[j];
pS[j]=pS[j-1];
pS[j-1]=temp;
}
}
}
i相当于冒泡的顶,每次冒泡都是从最底部开始冒的,选定一个最大值之后,就让这个最大值一直往上浮
6.4


这是因为把函数参数里的*stu看成了指向student类型的指针,但实际上这个*代表的是学生数组的意思,即stu是头