PAT相关的基础知识

PAT相关的基础知识

一.sort函数

下面记录最基础的sort函数的用法:

#include <algorithm>//头文件

//最简单的比较函数
bool cmp(int a,int b)
{
	return a<b;	//注意大于小于
}
//复杂一点的比较函数
bool cmp2(Student a, Student b) {
	if (a.score != b.score)
		return a.score > b.score;
	else if (a.solve != b.solve) 
		return a.solve > b.solve;
	else return a.id < b.id;
}
int main()
{
	int a[10];
	for(int i = 0; i < 10; i++)
		scanf("%d",&a[i]);
	sort(a, a + 10, cmp);
	return 0;
}

二.set的用法

set的特性是,所有元素都会根据元素的键值自动排序,set的元素不像map那样可以同时拥有实值(value)和键值(key),set元素的键值就是实值,实值就是键值。set不允许两个元素有相同的键值。
set的各成员函数列表如下:

  1. begin()–返回指向第一个元素的迭代器

  2. clear()–清除所有元素

  3. count()–返回某个值元素的个数

  4. empty()–如果集合为空,返回true

  5. end()–返回指向最后一个元素的迭代器

  6. equal_range()–返回集合中与给定值相等的上下限的两个迭代器

  7. erase()–删除集合中的元素

  8. find()–返回一个指向被查找到元素的迭代器

  9. get_allocator()–返回集合的分配器

  10. insert()–在集合中插入元素

  11. lower_bound()–返回指向大于(或等于)某值的第一个元素的迭代器

  12. key_comp()–返回一个用于元素间值比较的函数

  13. max_size()–返回集合能容纳的元素的最大限值

  14. rbegin()–返回指向集合中最后一个元素的反向迭代器

  15. rend()–返回指向集合中第一个元素的反向迭代器

  16. size()–集合中元素的数目

  17. swap()–交换两个集合变量

  18. upper_bound()–返回大于某个值元素的迭代器

  19. value_comp()–返回一个用于比较元素间的值的函数

建立

#include <set>
set <int> list[51];//set的数组
set <int> list2;

遍历

set<int>::iterator it;
for(it = list2.begin(); it! = list2.end(); it++)
{
	cout << *it;
}

反向遍历

set<int>::reverse_iterator it;
for(it = list.rbegin(); it != list.rend(); it++)
{
	cout << *it;
}

注意反向遍历用的指针类型不同,所指向的也不同,虽然是反向遍历,但是指针还是++而非- -

查找

if( list2.find (findnum) != list2.end() )
{
	cout<<" The number is in list2"<<endl;
}

三.输出百分比

printf("%.1f%% \n", 100 * (double)comnum);

四.数的科学计数法

数的情况有以下几种:
0
0.12345
0.0012345
123.45
12345
001234.5
0012345
首先判断数的指数
该判断分为小于1的数和大于等于1的数
小于1的数,小数点后面连续0的个数即为数的指数的负数
大于等于1的数,小数点前面的数的个数即为数的指数(正数)
但在此之前要去掉数最前面的0,避免它也被算入其中

接着判断底,底只是非0数开头的要求长度的字符串
例如上述数字中,要求0后面保留4位,则(以下皆是科学计数法0.后面的数字)

0 -> 0000
0.12345 -> 1234
0.0012345 ->1234
123.45 ->1234

此时的底已经与小数点没有关系了
但要注意,当字符串的长度不足要求时,要在后面补上对应个数的0

接下来就是处理步骤:
数字是保存在字符串或者字符数组中的,这样才能保证对数的每一位直接处理
1.把开头的0去掉
此时小于1的是就是小数点开头,大于等于1的数就是非0的数字开头
2.通过上述判断数是小于1的数还是大于等于1
这要分开处理,因为小于1的数指数是负的,大于等于1的数指数是正的
3.若该数是小于1的数
则将字符串开头的小数点和连续的0都删除并且记录0的个数
此时0的个数即为10^-k中的k
例如:0.001234 -> 0.1234*10^-2
4.若该数是大于等于1的数
则计算小数点之前的数的个数并记录
此时该个数即为10^k中的k
例如:123.45 -> 0.12345*10^3
在这个部分还需要将小数点从字符串中去掉,方便后面底的提取
5.判断了上述3和4,还需要判断输入的数是不是0,因为如果是0,则k是未知的,因为在第1步时已经把0去掉了
因此还需要判断是不是0,如果是0则指数k为0
如何判断是不是0:判断字符串是不是空即长度是否为0即可
6.最后就是底数的处理了
在剩下的字符串提取要求个数的字符,如果字符串的长度小于要求的个数则在后面补0
7.最后处理得出的结果,底数和指数可以建立一个结构体保存
最后比较两个结构体的底和指数就可以了

代码:

struct science_num {
	string di;
	int zhi;
} na, nb;

science_num change(string a, int N) {
	int k = 0;
	science_num na;
	na.zhi = 0;
	na.di.clear();
	
	//去除前导0 
	while (a.length() > 0 && a[0] == '0') {
		a.erase(a.begin());
	}

	//若a是小于1的数 
	if (a[0] == '.') {
		a.erase(a.begin());//将小数点删除
		while (a.length() > 0 && a[0] == '0') {
			a.erase(a.begin());//将小数点后面连续的0删除
			na.zhi--;//记录0的个数
		}
	}
	//若a不小于,找到可能存在的小数点并删除 
	else {
		while (k < a.length() && a[k] != '.') {
			k++;
			na.zhi++;//记录小数点前数字的个数
		}
		if (k < a.length()) {
			a.erase(a.begin() + k);
		}
	}

	//若a为0,将指数置0 
	if (a.length() == 0) {
		na.zhi = 0;
	}

	//预处理完毕,规格化
	if (a.length() >= N) {
		na.di.insert(na.di.begin(), a.begin(), a.begin() + N);//提取要求长度的字符串作为底
	}
	else {
		na.di.insert(na.di.begin(), a.begin(), a.end());
		for (int i = 0; i < N - a.length(); i++) {
			na.di += '0';//当长度不满足要求的时候在后面补0
		}
	}
	return na;//返回结果结构体
}

补充:字符串的处理

删除字符串指定位置的函数:

a.erase(a.begin() + k);

将字符串一部分添加到另一个字符串:

str1.insert(str1.begin(), str2.begin(), str2.begin() + N);

清空字符串:

str1.clear();

五.lower_bound和upper_bound函数用法

在从小到大的排序数组中
lower_bound(begin,end,num)表示从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字
upper_bound(begin,end,num)表示从数组的begin位置到end-1位置二分查找第一个大于num的数字
在从大到小的排序数组中
lower_bound(begin,end,num,greater<type>())表示从数组的begin位置到end-1位置二分查找第一个小于或等于num的数字
upper_bound(begin,end,num,greater<type>())表示从数组的begin位置到end-1位置二分查找第一个小于num的数字
以上若找到返回该数字的地址,不存在则返回end

因此需要通过返回地址减去起始地址begin,得到该数字在数组中的下标

六.最大公约数

int gcd(int a,int b){
	if(b == 0)
		return a;
	else
		return gcd(b, a % b);
}

七.最小公倍数

辗转相除法求最小公倍数:

int lcm(int x,int y){
	int a = 0, b = 0;
	int temp = 0;
	if(x < y)
	{
		temp = x;
		x = y;
		y = temp;
	}
	a = x * y;
	while(y != 0)
	{
		b = x % y;
		x = y;
		y = b;
	}
	return a/x;
}

八.分母的四则运算

分数的表示和化简

分数的表示

对一个分数来说,最简洁的写法就是写成假分数的形式,无论分子比分母大或者小,都保留其原数
因此可以使用一个结构体来存储这种只有分子和分母的分数:

struct Fraction{
	int up,down;
};

对这种表示制订三项原则:
1.使down为非负数,如果分数为负,那么令分子up负即可
2.如果该分数恰为0,那么规定其分子为0,分母为1
3.分子和分母没有除了1以外的公约数

分数的化简

分数的化简主要用来使Fraction变量满足分数表示的三项规定,因此此步骤也分为三步:
1.如果分母down为负数,那么令分子up和分母down都变为相反数
2.如果分子up为0,那么令分母down为1
3.约分:求出分子绝对值与分母绝对值的最大公约数d,然后令分子分母同时除以d

代码如下:

Fraction reduction(Fraction result){
	if(result.down < 0)
	{
		result.up = -result.up;
		result.down = -result.down;
	}
	if(result.up == 0)
	{
		result.down = 1;
	}
	else
	{
		int d = gcd(abs(result.up), abs(result.down));
		result.up /= d;
		result.down /= d;
	}
	return result;
}

分数的四则运算

分数的加法

对两个分数f1f2,其加法计算公式为
result = ( f1.up * f2.down +f2.up * f1.down ) / (f1.down * f2.down)

代码如下:

Fraction add( Fraction f1, Fraction f2)
{
	Fraction result;
	result.up = f1.up * f2.down + f2.up * f1.down;
	result.down = f1.down * f2.down;
	return red
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值