如需交流,请添加QQ好友 2636105163.
或可另外提供给你详细的出错样例信息。( 系统的测试样例不只是贴出来的一个测试样例。)
不过代码都是AC版本。需要声明的是,代码并非官方版本,而是自己当年写的,可能会存在不规范、效率不高、排版难看等问题。

Donghua University Online Judge 1.0
总共48道题目。基本是C++基础知识。不过正所谓是:前人栽树,后人乘凉,自己希望能给有缘人一些启发和帮助吧。
OJ题库文章目录:
目录
1: 控制公司
作者: xxx时间限制: 1S章节: OO:库
问题描述 :
有些公司是其他公司的部分拥有者,因为他们获得了其他公司发行的股票的一部分。例如,福特公司拥有马自达公司12%的股票。据说,如果至少满足了以下条件之一,公司A就可以控制公司B了: 公司A = 公司B。 公司A拥有大于50%的公司B的股票。 公司A控制K(K>= 1)个公司,记为C1, ..., CK,每个公司Ci拥有xi%的公司B的股票,并且x1+ .... + xK > 50%。 你将被给予一系列的三对数(i,j,p),表明公司i享有公司j的p%的股票。计算所有的数对(h,s),表明公司h控制公司s。至多有100个公司。 写一个程序读入三对数(i,j,p),i,j和p是都在范围(1..100)的正整数,并且找出所有的数对(h,s),使得公司h控制公司s。
输入说明 :
第一行: N,表明接下来三对数的数量。 第二行到第N+1行: 每行三个整数作为一个三对数(i,j,p),如上文所述。
输出说明 :
输出零个或更多个的控制其他公司的公司。每行包括两个整数表明序号为第一个整数的公司控制了序号为第二个整数的公司。将输出的每行以第一个数字升序排列(并且第二个数字也升序排列来避免并列)。请不要输出控制自己的公司。
输入范例 :
3
1 2 80
2 3 80
3 1 20
输出范例 :
1 2
1 3
2 3
代码:
#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#define N 101
using namespace std;
class companyHolding {
private:
short n;
short data[N][N];
bool isHeld[N][N];
public:
void initial();
void readCase();
void computing();
void outResult();
};
int main(){
companyHolding cH;
cH.initial();
cH.readCase();
cH.computing();
cH.outResult();
//cout << "Hello World!\n";
}
void companyHolding ::initial() {
memset(data, 0, sizeof(data));
memset(isHeld, false, sizeof(isHeld));
}
void companyHolding::readCase(){
cin >> n;
short i; short j; short p;
while (n--) {
cin >> i >> j >> p;
if (i < 1 || j < 1 || p < 1 || p>100 || j>100 || i>100) {
cout << "Input Error!" << endl;
}
else{
if (i == j) { continue; }
isHeld[i][j] = true;
data[i][j] = p;//股份关联
}
}
}
void companyHolding::computing() {
for (int i = 1; i < N; i++) {
for (int j = 1; j < N; j++) {
if ( isHeld[i][j] ) {//之前理解出错导致WA:并非要>50控制了才能传递,只要有股份就能传递
for ( int k = 1; k < N; k++) {
if(isHeld[k][i] && data[k][i]>50 ) {
data[k][j] += data[i][j];//间接控制
}
}
}
}
}
}
void companyHolding::outResult() {
for (int i = 1; i < N; i++) {
for (int j = 1; j < N; j++) {
if (data[i][j] > 50 && i!=j) {
cout << i << " " << j << endl;
}
}
}
}
2 日期结构体操作
作者: Turbo时间限制: 1S章节: OO:其它
问题描述 :
实验目的:巩固结构体类型知识,为学习类的声明打基础。
实验内容:声明一个结构体类型Date,包括年月日,即一个日期类型的结构体。
设计一个程序,完成以下对日期的操作,包括以下函数:
Date AddDay(Date d, int days):对日期增加days天数,然后返回得到的日期
Date AddMonth(Date d, int months):对日期增加months月数,然后返回得到的日期
Date AddYear(Date d, int years):对日期增加years年数,然后返回得到的日期
int Subtract(Date d1, Date d2):用d1-d2,计算它们相距的天数,作为函数值返回
GetWeekDay:输入参数为Date类型,返回该日期是星期几。星期几最好用枚举表示,也就是返回一个枚举类型的值。本函数可选做,测试数据不包含本函数。
程序输出相应计算结果。
请使用以下main函数:
int main()
{
char WeekDayNames[][15]={"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday","Friday", "Saturday"};
int op;
while(cin>>op)
{
Date d1, d2;
int n;
DayName w;
switch(op)
{
case 1: //add days
cin>>d1.year>>d1.month>>d1.day>>n;
d2=AddDay(d1, n);
cout<<d2.year<<" "<<d2.month <<" " <<d2.day<<endl;
break;
case 2:
cin>>d1.year>>d1.month>>d1.day>>n;
d2=AddMonth(d1, n);
cout<<d2.year<<" "<<d2.month <<" " <<d2.day<<endl;
break;
case 3:
cin>>d1.year>>d1.month>>d1.day>>n;
d2=AddYear(d1, n);
cout<<d2.year<<" "<<d2.month <<" " <<d2.day<<endl;
break;
case 4:
cin>>d1.year>>d1.month>>d1.day>>d2.year>>d2.month>>d2.day;
n=Subtract(d1, d2);
cout<<n<<endl;
break;
case 5:
cin>>d1.year>>d1.month>>d1.day;
w=GetWeekDay(d1);
cout<<WeekDayNames[w]<<endl;
break;
}
}
}
输入说明 :
程序包含多组输入,每组测试数据包含两行,第一行用一个整数(1到5)指定需要完成的操作,含义如下:
1:AddDay
2:AddMonth
3:AddYear
4:Subtract
5:GetWeekDay(测试数据中不包含本输入)
第二行为该操作需要的数据。
比如输入:
1
2016 1 1 31
表示将进行AddDay操作,输入日期为2016年1月1日,加31天。
程序输出结果日期,按年月日格式输出,中间以一个空格分隔。
输出说明 :
程序输出相应计算结果。
对于AddDay、AddMonth、AddYear三种操作,输出结果日期,按年月日格式输出,中间以一个空格分隔。
对于Subtract,结果仅输出一个整数,表示相距的天数。
每组输出占一行,行首与行尾无多余空格,所有地方无多余空行。
输入范例 :
1
2000 2 28 20
2
2000 1 31 3
3
2000 1 31 1
4
2016 3 8 2016 2 8
4
2016 1 8 2016 2 8
输出范例 :
2000 3 19
2000 4 30
2001 1 31
29
-31
#include <iostream>
#include <string>
using namespace std;
struct Date {
int day;
int month;
int year;
};
class DateOperation {
private:
int daysOfMonth[12] = {31,28,31,30,31,30,31,31,30,31,30,31 };//Set Days Of February To 28,And Then Check It For Legality Before Using.
const string weekdayNames[7] = { "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday" };
int op;//from 1 to 5
Date date;
int days, months, years;
public:
bool isLeapYear(int year) { return (!(year % 400)) || (!(year % 4) && (year % 100)); }
void setDaysOfFebruary(int year);
void checkLegality(Date& );
Date AddDay(Date& , int& );
Date AddMonth(Date& , int& );
Date AddYear(Date& , int& );
//unsigned long long GetDaysOfDate(Date& );
int Subtract(Date& , Date& );//date1 - date2
int GetWeekday(Date& );
void initial();
void computing();
friend istream& operator>>(istream&in, Date& date);
friend ostream& operator<<(ostream&out, const Date& date);
};
void DateOperation::setDaysOfFebruary(int year) {
if (isLeapYear(year)) {
daysOfMonth[1] = 29;
}else{
daysOfMonth[1] = 28;
}
}
void DateOperation :: checkLegality(Date& date) {
setDaysOfFebruary(date.year);
if (date.day > daysOfMonth[date.month - 1]) {
date.day = daysOfMonth[date.month - 1];
}
}
Date DateOperation::AddDay(Date& date, int& days) {
date.day += days;
setDaysOfFebruary(date.year);
while (date.day > daysOfMonth[date.month - 1]) {
date.day -= daysOfMonth[date.month - 1];
date.month ++;
if (date.month > 12) {
date.month -= 12;
date.year++;
setDaysOfFebruary(date.year);
}
}
checkLegality(date);
return date;
}
Date DateOperation::AddMonth(Date& date, int& months) {
date.month += months;
while (date.month > 12) {
date.month -= 12;
date.year++;
}
checkLegality(date);
return date;
}
Date DateOperation::AddYear(Date& date, int& years) {
date.year += years;
checkLegality(date);
return date;
}
/* //搞不明白哪里出错,该方法测试样例 4 2015 3 8 2016 3 8 会错误的输出 -367 而非 -366,但是其他跨闰年的又对……
//难道是数值过大导致溢出(int范围?
后经过重复测试可以确认,是溢出导致数值运算错误(比如 测试 4 15 3 8 16 3 8 也是-367,但4 5 3 8 6 3 8则正确输出 -365)
解决办法:通过 变加边减 使得数值不能溢出。
当然也可以考虑借助中间变量,long long类型的中间变量。。。后者当然是不行的了,经测试内存爆了。
unsigned long long DateOperation::GetDaysOfDate(Date& date) {
unsigned long long temp = 0;
temp += (date.year - 1) * 365 + date.year / 4 - date.year / 100 + date.year / 400;
setDaysOfFebruary(date);
for (int i = 0; i < date.month - 1; i++) {
temp += daysOfMonth[i];
}
temp += date.day;
return temp;
}
*/
int DateOperation::Subtract(Date& date1, Date& date2) {
//return int(GetDaysOfDate(date1) - GetDaysOfDate(date2));
int temp = 0;
int i = 1;
for ( ; i < date1.year; i++) {
if( i< date2.year){
}
else {
if ( isLeapYear(i) ) {
temp += 366;
}
else {
temp += 365;
}
}
}
for ( ; i < date2.year; i++) {
if (isLeapYear(i)) {
temp -= 366;
}
else {
temp -= 365;
}
}
for (i=0; i < date1.month-1; i++) {
setDaysOfFebruary(date1.year);
temp += daysOfMonth[i];
}
for (i = 0; i < date2.month-1; i++) {
setDaysOfFebruary(date2.year);
temp -= daysOfMonth[i];
}
temp += date1.day;
temp -= date2.day;
return temp;
}
int DateOperation::GetWeekday(Date& date) {
if (date.day == 1 || 2 == date.day) {
date.month += 12;
date.year--;
}
return (date.day + 2 * date.month + 3 * (date.month + 1) / 5 + date.year + date.year / 4 - date.year / 100 + date.year / 400 + 1 ) % 7;
}
istream& operator>>(istream&in, Date& date) {
return in >> date.year >> date.month >> date.day;
}
ostream& operator<<(ostream&out, const Date& date) {
return out << date.year << " " << date.month << " " << date.day;
}
void DateOperation::initial() {
days = months = years = 0;
}
void DateOperation::computing() {
while (cin >> op) {
initial();
switch(op) {
case 1://add days
cin >> date >> days;
cout << AddDay(date, days) << endl;
break;
case 2://add months
cin >> date >> months;
cout << AddMonth(date, months) << endl;
break;
case 3://add years
cin >> date >> years;
cout << AddYear(date, years) << endl;
break;
case 4://Subtracting date - date_Temp
Date date_Temp;
cin >> date >> date_Temp;
cout << Subtract(date, date_Temp) << endl;
break;
case 5://Get Weekday Of Date
cin >> date;
cout << weekdayNames[GetWeekday(date)] << endl;
break;
}
}
}
int main()
{
//cout << "Hello world!" << endl;
DateOperation dateOp;
dateOp.computing();
return 0;
}
3 函数的重载、默认形参练习
作者: Turbo时间限制: 1S章节: OO:其它
问题描述 :
内容:对于字符串,实现以下函数,并编写main函数测试这些函数:
-
padLeft函数:
功能:将一字符串左填充(在左边填充指定字符)至n个字符的长度,可指定填充字符,比如填充“*”,如果不指定填充字符,则填充空格。
提示:为实现以上功能,函数原型可为:
void padLeft(char string1[], char string2[], int n, char padding=' ')
或:
string padLeft(string string1, int n, char padding=' ')
这里使用了默认形参。
string1是原字符串,string2是填充之后的结果。
以下函数都不规定函数原型,请自行设计。
-
padRight函数:
功能:将一字符串右填充至n个字符的长度,可指定填充字符,比如填充“*”,如果不指定填充字符,则填充空格。
-
cpy函数:
功能:从第一个字符串复制字符到第二个字符串。可指定复制的起始位置和结束位置,即从startIndex到endIndex之间的所有字符都复制到第二个字符串中。startIndex默认为0, endIndex默认为到字符串尾部。
比如,
cpy(src, dest): 将src的所有字符都复制到dest
cpy(src, dest, 3):将src从下标为3的位置直到结尾的所有字符都复制到dest
cpy(src, dest, 3, 5):将src的第3、4、5个字符复制到dest中
-
remove函数:
从形参传入一个字符,将该字符从字符串中删除。
-
remove函数:
从形参传入一个下标index,将index处的字符从字符串中删除。
-
remove函数:
从形参传入两个下标startIndex和endIndex,将从startIndex到endIndex范围内的字符从字符串中删除。
main函数可参考以下代码编写:
int main()
{
int num, length, index, startIndex, endIndex;
char padding, delChar;
string src, dest;
while(cin >> num)
{
switch(num)
{
case 11:
cin >> src >> length;
cout << padLeft(src, length) << endl;
break;
case 12:
cin >> src >> length >> padding;
cout << padLeft(src, length, padding) << endl;
break;
case 21:
cin >> src >> length;
cout << padRight(src, length) << endl;
break;
case 22:
cin >> src >> length >> padding;
cout << padRight(src, length, padding) << endl;
break;
case 31:
cin >> src;
cout << cpy(src) << endl;
break;
case 32:
cin >> src >> startIndex;
cout << cpy(src, startIndex) << endl;
break;
case 33:
cin >> src >> startIndex >> endIndex;
cout << cpy(src, startIndex, endIndex) << endl;
break;
case 41:
cin >> src >> delChar;
cout << remove(src, delChar) << endl;
break;
case 42:
cin >> src >> index;
cout << remove(src, index) << endl;
break;
case 43:
cin >> src >> startIndex >> endIndex;
cout << remove(src, startIndex, endIndex) << endl;
break;
}
}
return 0;
}
输入说明 :
输入时,每组测试数据包含两行,第一行输入一个整数,指定需要完成的操作,第二行为该操作需要的数据。
对于每个整数对应的操作及其相应数据的输入方式如下(输入的字符串中不包含空格):
11:对应padLeft,第二行输入字符串string1、整数n,其间以空格分隔(由于没指定填充字符,所以填充空格)
异常处理:如果string1的长度大于等于n,则不填充任何字符。
12:对应padLeft,第二行输入字符串string1、整数n、一个填充字符,其间以空格分隔(填充字符不为空格)
异常处理:如果string1的长度大于等于n,则不填充任何字符。
21:对应padRight,第二行输入字符串string1、整数n,其间以空格分隔(由于没指定填充字符,所以填充空格)
异常处理:如果string1的长度大于等于n,则不填充任何字符。
22:对应padRight,第二行输入字符串string1、整数n、一个填充字符,其间以空格分隔(填充字符不为空格)
异常处理:如果string1的长度大于等于n,则不填充任何字符。
31:对应cpy,第二行输入字符串src
32:对应cpy,第二行输入字符串src和整数startIndex,以空格分隔。复制从startIndex开始的子字符串,下标从0开始。
异常处理:如果startIndex不合法,则不复制任何字符,结果为空字符串。
33:对应cpy,第二行输入字符串src和整数startIndex、endIndex,以空格分隔。
异常处理:如果startIndex、endIndex不合法,则不复制任何字符,结果为空字符串。
41:对应remove,第二行输入字符串和一个字符(以空格分隔),将字符从字符串中删除。
42:对应remove,第二行输入字符串和index(以空格分隔),将index处的字符从字符串中删除。
异常处理:如果index不合法,则不删除字符。
43:对应remove,第二行输入字符串和startIndex、endIndex(以空格分隔),将从startIndex到endIndex范围内的字符从字符串中删除。
异常处理:如果startIndex、endIndex不合法,则不删除字符。
输出说明 :
对于每组测试数据,输出对应的结果。如果结果为空字符串,则输出一个空行。
每行行首与行尾无多余空格,第一行之前与最后一行之后无多余空行。
输入范例 :
11
abcdefgh 10
12
abcdefgh 10 *
21
abcdefgh 10
22
abcdefgh 10 *
31
abcdefgh
32
abcdef 1
33
abcdef 1 5
41
abcdef a
42
abcdef 1
43
abcdef 1 4
输出范例 :
abcdefgh
**abcdefgh
abcdefgh
abcdefgh**
abcdefgh
bcdef
bcdef
bcdef
acdef
af
#include <iostream>
#include <string>
using namespace std;
/*
* 3 函数的重载、默认形参练习
*/
class StringFunction {
private:
int num, length, index, startIndex, endIndex;
char padding, delChar;
string src,dest;
public:
string padLeft(string& ,const unsigned int& , char padding);
string padRight(string& ,const unsigned int& , char padding);
string cpy(string& , int startIndex, int endIndex);
string remove(string& , const char& );
string remove(string& , const int& i);
string remove(string& , const int& ,const int& );
bool checkLegality(string& , const int& );
bool checkLegality(string& , const int& , const int& );
bool isExsit(string& , const char& );
void initial();
void computing();
};
void StringFunction::initial() {
src.clear();
dest.clear();
}
bool StringFunction::checkLegality(string& str, const int& index) {
return index >= 0 && index < str.size();
}
bool StringFunction::checkLegality(string& str, const int& startIndex, const int& endIndex) {
return startIndex >= 0 && startIndex <= endIndex && endIndex < str.size();
}
bool StringFunction::isExsit(string& str, const char& ch) {
for (unsigned int i = 0; i < str.size(); i++) {
return str[i] == ch;
}
return false;
}
string StringFunction::padLeft(string& str,const unsigned int& n, char padding = ' ') {
if (str.size() > n) { return str; }
for (unsigned int i = str.size(); i < n; i++) {
str = padding + str;
}
return str;
}
string StringFunction::padRight(string& str,const unsigned int& n, char padding = ' ') {
if (str.size() > n) { return str; }
for (unsigned int i = str.size(); i < n; i++) {
str += padding;
}
return str;
}
string StringFunction::cpy(string& str, int startIndex = 0, int endIndex = -1) {
if (-1 == endIndex) {
endIndex = str.size() - 1;
}
if ( !checkLegality(str, startIndex, endIndex)) {
return dest;
}
dest = string (str, startIndex, endIndex - startIndex + 1);//第三个参数为个数
return dest;
}
/*
string StringFunction::remove(string& str,const char& delChar) {
//for (string::size_type index = 0; index != str.size(); index++) {
//cout << "str.size() = " << str.size() << endl;
while ( isExsit(str, delChar)) {
for (unsigned int index = 0; index < str.size(); index++) {
//for (unsigned int index = 0,length = str.size(); index < length; index++) {
if (str[index] == delChar) {
str.erase(str.begin() + index);//only delete one char which index is opposite
//错误原因,str长度在不断缩短……而且index还不归0初始化。。
//解决办法:外层嵌套while循环判断是否还有要删除的字符,continue加快效率
//cout << "str[" << index << "] = " << str[index] << endl << "str = " << str << endl;
//continue;//经测试有无continue效果一样
}
}
}
return str;
}
*/
//方法二:逆向思维,删很多的该字符不如拿其他的组新子串
string StringFunction::remove(string& str, const char& delChar) {
if(isExsit(str, delChar)) {
string str_temp;
for (unsigned int index = 0; index < str.size(); index++) {
if (str[index] != delChar) {
str_temp.push_back(str[index]);//cpy函数的实现也可以考虑使用 push_back()方法
}
}
return str_temp;
}
return str;
}
string StringFunction::remove(string& str,const int& index) {
if (!checkLegality(str, index)) {
return str;
}
//return str.erase(str.begin() + index);
str.erase(str.begin() + index);
return str;
}
string StringFunction::remove(string& str,const int& startIndex,const int& endIndex) {
if ( !checkLegality(str, startIndex, endIndex)) {
return str;
}
str.erase(str.begin() + startIndex, str.begin() + endIndex + 1);
return str;
}
void StringFunction::computing() {
while (cin >> num) {
initial();
switch (num) {
case 11:
cin >> src >> length;
cout << padLeft(src, length) << endl;
break;
case 12:
cin >> src >> length >> padding;
cout << padLeft(src, length, padding) << endl;
break;
case 21:
cin >> src >> length;
cout << padRight(src, length) << endl;
break;
case 22:
cin >> src >> length >> padding;
cout << padRight(src, length, padding) << endl;
break;
case 31:
cin >> src;
cout << cpy(src) << endl;
break;
case 32:
cin >> src >> startIndex;
cout << cpy(src, startIndex) << endl;
break;
case 33:
cin >> src >> startIndex >> endIndex;
cout << cpy(src, startIndex, endIndex) << endl;
break;
case 41:
cin >> src >> delChar;
cout << remove(src, delChar) << endl;
break;
case 42:
cin >> src >> index;
cout << remove(src, index) << endl;
break;
case 43:
cin >> src >> startIndex >> endIndex;
cout << remove(src, startIndex, endIndex) << endl;
break;
}
}
}
int main() {
StringFunction SF;
SF.computing();
return 0;
}
4 出现次数
作者: Turbo时间限制: 1S章节: OO:字符串
问题描述 :
输入两个字符串,计算第二个字符串在第一个字符串中出现的次数并输出。
输入说明 :
输入多组测试数据,每组测试数据占两行。
每个字符串中都不包含空格,也不为空字符串。
输出说明 :
对于每组测试数据,计算第二行的字符串在第一行中出现的次数,输出该数字。
每组输出占一行,每行首尾都无空格,也无多余空行。
输入范例 :
asdfghjasdfghjasdfghj
sdf
asdfasdfasdf
sdfas
输出范例 :
3
1
#include <iostream>
#include <string>
using namespace std;
class MyFind {
private:
unsigned int count;
string str, sub_str;
public:
void initial();
void setCount(const string& ,const string& );
void computing();
unsigned int getCount();
};
void MyFind::initial() {
count = 0;
str.clear();
sub_str.clear();
}
void MyFind::setCount(const string& str,const string& sub_str) {
unsigned int i, j;
for ( i = 0; i < str.size(); i++) {
if (str[i] == sub_str[0]) {
for (j = i; j - i < sub_str.size(); j++) {
if (str[j] != sub_str[j - i]) {
break;//子串未匹配,不对i处理
}
}
if (j - i == sub_str.size()) {
i += sub_str.size() - 1;//子串匹配,对i进行加值处理,但是要减1因为还要i++
count++;
}
}
//根据实际情况进行如下优化处理
if (str.size() - i < sub_str.size()) {
break;
}
}
}
unsigned int MyFind::getCount() {
return count;
}
void MyFind::computing() {
initial();
while (cin >> str >> sub_str) {
setCount(str, sub_str);
cout << getCount() << endl;
initial();
}
}
int main(){
//std::cout << "Hello World!\n";
MyFind MF;
MF.computing();
return 0;
}
5 最大相同子串
作者: Turbo时间限制: 1S章节: OO:字符串
问题描述 :
输入两个字符串,获取两个字符串中最大相同子串并输出。
如果有多个相同子串,则输出(按ASCII排序)最小的那个“最大相同子串”。
如果无相同子串,则输出空字符串(即空行)。
输入说明 :
输入多组测试数据,每组测试数据包含两行。
每行包含一个字符串,字符串中无空格,也无空字符串。
输出说明 :
对于每组测试数据,输出最大子串。如果最大子串为空,则输出一个空行。
每组输出占一行,行首与行尾无多余空格,也无多余空行。
输入范例 :
abcded123456aabbcc
abcdaa1234
abcdabcdabcd
abcda
输出范例 :
1234
abcda
#include <iostream>
#include <string>
#include <vector>
#include<algorithm>
using namespace std;
typedef pair<string, unsigned int> PSI;
typedef vector<PSI> VP;
class MyFind {
private:
string str1,str2,substr;
VP vp1,vp2;//子串,及其串长
public:
void initial();
bool isRepetition(string& , VP& );//判断该子串是否已存在
void generateSubstring(const string& , VP& );//填充子串
//bool cmp(const PSI& , const PSI& );
void sortVP(VP& );
void displaySortedVP(VP&);
bool subStringIsMatch(VP& ,VP& );
void outputSubstr();
void computing();
};
void MyFind::initial() {
str1.clear();
str2.clear();
substr.clear();
vp1.clear();
vp2.clear();
}
bool MyFind::isRepetition(string& str, VP& vp) {//判断该子串是否已存在
for (int i = 0; i < vp.size(); ++i) {
return (vp[i].first == str);//有重
}
return false;//无重
}
void MyFind::generateSubstring(const string& str, VP& vp) {//生成所以子串
int len = str.size();
for (int i=1; i<=len; ++i) { // i 子串元素个数
for (int j=0; j+i <= len; ++j) { // j 索引起点
string temp(&str[j], i);
// string temp(str, j, i);
if (!isRepetition(temp, vp))
vp.push_back( PSI(temp,temp.size()) );
// 说明,若是母串没有重复的字符,则可以借助匿名变量实现一步到位,如上
}
}
}
/*
bool MyFind::cmp(const PSI& a,const PSI& b) {
return a.first<b.first && a.second > b.second;串ASCLL码升序,串长降序
}
void MyFind::sortVP(VP& vp) {
sort(vp.begin(), vp.end(), cmp);
}
*///上诉排序算法,VS2017报错
//注意,对所有子串的排序,可以仅对其中一个母串执行即可,但是要注意subStringIsMatch函数中外层放的vp1必须是排序了的
//对2个VP都排序的话,则可以根据字串长度在subStringIsMatch中进行代码优化处理
void MyFind::sortVP(VP& vp) {
int n = vp.size();
for (int i = 0; i < n - 1; ++i) {//串长降序
//DirectSelectionSort
// 先用 k 来存储a[i+1]~a[n-1]之间的最大值的下标索引值,避免多余的数值交换操作swap,选择排序即选出a[MaxIndex]
int k = i;
for (int j = i + 1; j < n; ++j) {
if (vp[j].second > vp[k].second)
k = j; //不断更换成更大的元素值的下标,直至找到最大的
}
if (k != i) {
PSI temp(vp[i].first, vp[i].second);
vp[i].first = vp[k].first;
vp[i].second = vp[k].second;
vp[k].first = temp.first;
vp[k].second = temp.second;
}
}
for (int i = 0; i < n - 1; ++i) {//ASCLL码升序,注意只对等长子串排序
//DirectSelectionSort
// 先用 k 来存储a[i+1]~a[n-1]之间的最小值的下标索引值,避免多余的数值交换操作swap,选择排序即选出a[MinIndex]
int k = i;
for (int j = i + 1; j < n; ++j) {
if (vp[j].second < vp[k].second) {
break;
}
if (vp[j].first < vp[k].first && vp[j].second == vp[k].second) {
k = j; //不断更换成更小的元素值的下标,直至找到最小的
}
}
if (k != i) {
PSI temp(vp[i].first, vp[i].second);
vp[i].first = vp[k].first;
vp[i].second = vp[k].second;
vp[k].first = temp.first;
vp[k].second = temp.second;
}
}
}
void MyFind::displaySortedVP(VP& vp) {
for (int i = 0; i < vp.size(); ++i) {
cout << "i = " << i << '\t' << vp[i].first << '\t' << vp[i].second << endl;
}
cout << "----------------我是分割符-------------------" << endl;
}
bool MyFind::subStringIsMatch(VP& vp1, VP& vp2) {
//遍历vp2,依次与vp1从头至尾匹配
for (int i = 0; i < vp1.size(); ++i) {
for (int j = 0; j < vp2.size(); ++j) {
if (vp1[i].first == vp2[j].first) {
substr = vp1[i].first;
return true;
}
//vp2必须是也排序了,才可以如下break优化
if (vp1[i].second > vp2[j].second) {
break;
}
}
}
return false;
}
void MyFind::outputSubstr() {
cout << substr << endl;
}
void MyFind::computing() {
initial();
while (cin >> str1 >> str2) {
generateSubstring(str1, vp1);
generateSubstring(str2, vp2);
sortVP(vp1);
sortVP(vp2);
//displaySortedVP(vp1);
//displaySortedVP(vp2);
subStringIsMatch(vp1, vp2);
outputSubstr();
initial();
}
}
int main(){
//std::cout << "Hello World!\n";
MyFind MF;
MF.computing();
return 0;
}
6 解析XML文档
作者: Turbo时间限制: 1S章节: OO:字符串
问题描述 :
在网络上传输或者存储数据,经常使用xml文档。
一个书籍列表的xml文档可能如下:
<bookList>
<book>
<name>C++</name>
<author>yang</author>
<price>33</price>
</book>
<book>
<name>C</name>
<author>Tan</author>
<price>30.8</price>
</book>
<book>
<name>C programming</name>
<author>tan</author>
<price>28.9</price>
</book>
</bookList>
在这里,每一本书的信息包括书名、作者、价格。
通过解析该文档,根据一个书籍列表,输入书名,即可知道该书对应的价格。
输入说明 :
仅输入一组测试数据:
第一行为书籍列表的xml文档(文档中将不包含上述示例中的换行,除书名和作者名外,也不包括任何空格),第二行及以后的若干行为书名。
输出说明 :
根据第二行及其后的书名,针对每本书到xml文档中查找对应的价格,输出其价格。
如果有多本书同名,则输出第一本的价格。
如果书籍不存在,则输出"No"(不包括引号)。
每本书的价格单独占一行,输出价格时,保持其在xml文档中的格式。
不输出多余空格或空行。
输入范例 :
<bookList><book><name>C++</name><author>yang</author><price>33</price></book><book><name>C</name><author>Tan</author><price>30.8</price></book><book><name>C programming</name><author>tan</author><price>28.9</price></book></bookList>
C+
C
输出范例 :
No
30.8
#include <iostream>
#include <string>
using namespace std;
class XML {
private:
string xmlString;
string bookName;
public:
void init();
void computing();
};
void XML::init() {
getline(cin, xmlString, '\n');
}
void XML::computing() {
init();
//while (cin >> bookName) {//bookname也有空格的时候。。。C programming
while(getline(cin, bookName, '\n')){
string temp;
unsigned int index, startIndex, endIndex;
string::size_type found = xmlString.find( bookName ,0 );
check:
if (found == string::npos) {
cout << "No" << endl;
continue;
}
//cout << "found1 = " << found << endl;
if (xmlString[found + bookName.size()] != '<') {//确保书名正确,不能C或C+顶替了C++
found = xmlString.find(bookName, found + 1); //必须+1从在一个字符起再次查找,以免死循环
goto check;
}
//cout << "found2 = " << found << endl;
temp.assign(xmlString.begin() + found, xmlString.end());
//cout << "temp1 =" << temp << endl;
found = temp.find("price",0);
//cout << "found3 = " << found << endl;
temp.assign(temp.begin() + found, temp.end());
//cout << "temp2 =" << temp << endl;
for (index = 0; temp[index] != '<'; ++index) {
if (temp[index] == '>') {
startIndex = index + 1;
}
}
endIndex = index;
temp.assign(temp.begin() + startIndex, temp.begin() + endIndex);
cout << temp << endl;
//cout << "temp3 =" << temp << endl;
//bookName.clear();
}
}
int main(){
XML xml;
xml.computing();
return 0;
}
7 盒子类
作者: 冯向阳时间限制: 1S章节: OO:类
问题描述 :
定义盒子Box类,计算盒子的体积及表面积。Box类包括:
私有数据成员:
int Length //Box的长度
int Width //Box的宽度
int Height //Box的高度
公有成员函数:
void InitBox( int x, int y, int z); //设置Box的尺寸
void setVolume( ); //计算Box的体积
void setArea( ); //计算Box的表面积
void show( ); //输出盒子的信息,输出形式见“输出说明”
要求使用以下main函数测试Box类:
int main()
{
int intLength, intWidth, intHeight;
Box box;
cin>>intLength;
cin>>intWidth;
cin>>intHeight;
box.initBox(intLength,intWidth,intHeight);
box.setVolume();
box.setArea();
box.show();
return 0;
}
输入说明 :
输入三个整数:Length(长)、Width(宽)、Height(高),整数之间以空格分隔。
输入的整数都为非负数。
输出说明 :
输出三行:
第一行输出Length(长)、Width(宽)、Height(高),整数之间以一个空格分隔
第二行输出体积
第三行输出表面积
输出行之间无多余的空行和空格
输入范例 :
1 2 3
输出范例 :
1 2 3
6
22
#include <iostream>
using namespace std;
class Box {
private:
int Length; //Box的长度
int Width; //Box的宽度
int Height; //Box的高度
int Volume;
int Area;
public:
void initBox(const int& x,const int& ,const int& ); //设置Box的尺寸
void setVolume(); //计算Box的体积
void setArea(); //计算Box的表面积
void show(); //输出盒子的信息,输出形式见“输出说明”
};
void Box::initBox(const int& x,const int& y,const int& z) {
Length = x;
Width = y;
Height = z;
}
void Box::setVolume() {
Volume = Length * Width * Height;
}
void Box::setArea() {
Area = 2 * ( Length * Width + Length * Height + Width * Height );
}
void Box::show() {
cout << Length <<" "<< Width <<" "<< Height << endl;
cout << Volume << endl;
cout << Area << endl;
}
int main(){
int intLength, intWidth, intHeight;
Box box;
cin >> intLength;
cin >> intWidth;
cin >> intHeight;
box.initBox(intLength, intWidth, intHeight);
box.setVolume();
box.setArea();
box.show();
return 0;
}
8 类和对象:使用日期类计算相隔天数
作者: 冯向阳时间限制: 1S章节: OO:类
问题描述 :
现有日期类Date。Date类定义如下:
class Date{
int year;
int month;
int day;
public:
Date(int y,int m,int d):year(y),month(m),day(d){};
int getYear() const {return year;}
int getMonth() const {return month;}
int getDay() const {return day;}
};
要求:使用日期类,设计1个用户函数CalDay,计算出两个日期之间的相隔天数,在屏幕上输出结果。
CalDay函数的原型定义如下:
int CalDay(const Date &d1, const Date &d2) //d1:较小的日期赋给d1,d2:较大的日期
要求使用以下main函数测试:
int main(){
int y1,m1,d1,y2,m2,d2;
cin>>y1>>m1>>d1;
cin>>y2>>m2>>d2;
Date date1(y1,m1,d1);
Date date2(y2,m2,d2);
cout<<CalDay(date1,date2);
return 0;
}
输入说明 :
测试数据为2行,
第一行:开始日期(分别为年、月、日的值,值与值之间用空格分隔),例如:2010 4 7
第一行:结束日期(分别为年、月、日的值,值与值之间用空格分隔),例如:2017 4 7
注意:开始日期在结束日期之前
输出说明 :
输出结果为截止日期与开始日期的相隔天数。
输入范例 :
2010 2 3
2017 3 17
输出范例 :
2599
9 函数模板:两点间的距离
作者: 冯向阳时间限制: 1S章节: OO:其它
问题描述 :
使用模板函数,分别求出int型数的两点间的距离和浮点型数的两点间的距离。在main函数中测试运用模板函数。
函数原型为:
template <class T>
T distance( T, T, T, T);
main函数可参考以下代码编写:
int main( ){
int i_x1, i_y1, i_x2, i_y2;
double d_x1, d_y1, d_x2, d_y2;
cin>>i_x1>>i_y1>>i_x2>>i_y2;
cin>>d_x1>>d_y1>>d_x2>>d_y2;
cout<<distance( i_x1, i_y1, i_x2, i_y2 )<<endl;
cout<<distance(d_x1, d_y1, d_x2, d_y2 )<<endl;
return 0;
}
输入说明 :
每组测试数据为两行,格式如下:
i_x1 i_y1 i_x2 i_y2 //两个int型测试点的x坐标,y坐标,坐标之间用空格分隔
d_x1 d_y1 d_x2 d_y2 //两个double型测试点的x坐标,y坐标,坐标之间用空格分隔
行与行之间无多余的空行和空格。
输出说明 :
输出数据分两行,分别对应int型和double型的两点间的距离
行与行之间无多余的空行和空格。
输入范例 :
1 1 2 1
10.0 20.0 5.0 5.0
输出范例 :
1
15.8114
#include <iostream>
#include <cmath>
using namespace std;
template <class T>
T distance(T a1, T b1, T a2, T b2) {
return sqrt((a1 - a2)*(a1 - a2) + (b1 - b2)*(b1 - b2));
}
int main() {
int i_x1, i_y1, i_x2, i_y2;
double d_x1, d_y1, d_x2, d_y2;
cin >> i_x1 >> i_y1 >> i_x2 >> i_y2;
cin >> d_x1 >> d_y1 >> d_x2 >> d_y2;
cout << distance(i_x1, i_y1, i_x2, i_y2) << endl;
cout << distance(d_x1, d_y1, d_x2, d_y2) << endl;
return 0;
}
10 寻找素数
作者: 冯向阳时间限制: 1S章节: OO:其它
问题描述 :
寻找出任意两个整数之间的所有素数,在屏幕上输出所有的素数以及个数。
提示:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数。
输入说明 :
每组输入分两行。
第一行是开始数