常用代码&细节备忘

本篇适合初学或基础较薄弱的人,大佬们自动绕行

常用头文件

#include<iostream> 
#include<sstream>
#include<cmath>
#include<algorithm> 
#include<string>

字符串的各种操作

创建读取对象

string s;
char ss[5000];//scanf不支持string对象
scanf("%s",&ss);//scanf的速度要比cin快很多
string s3(4, 'K');  // s3 = "KKKK",
string s4("12345", 1, 3);  //s4 = "234",即 "12345" 的从下标 1 开始,长度为 3 的子串
string s1("12345");
s3.assign(s1);  // s3 = s1
s2.assign(s1, 1, 2);  // s2 = "23",即 s1 的子串(1, 2)
s2.assign(4, 'K');  // s2 = "KKKK"
s2.assign("abcde", 2, 3);  // s2 = "cde",即 "abcde" 的子串(2, 3)

查看大小

s.length();

添加

尾部直接相加
s.append("balabala");
中间添加
string s1("Limitless"), s2("00");
s1.insert(2, "123");  //在下标 2 处插入字符串"123",s1 = "Li123mitless"
s1.insert(3, s2);  //在下标 2 处插入 s2 , s1 = "Li10023mitless"
s1.insert(3, 5, 'X');  //在下标 3 处插入 5 个 'X',s1 = "Li1XXXXX0023mitless"
string::iterator it;
it=s.begin();
s.insert(it+x,'c');//这里只能是一个字符,若添加多个字符有警告但正常运行,添加了多个字符中的最后一个。多个字符可使用for循环实现。

访问

s[0]
s[0]-'a'
string s1 = "this is ok";
string s2 = s1.substr(2, 4);  // s2 = "is i"
s2 = s1.substr(2);  // s2 = "is is ok"

删除

s.erase(it+x);
s.erase(it+x,it+x+y);//删除区间
s="";//清空

替换

string s1("West”), s2("East");
s1.swap(s2);  // s1 = "East",s2 = "West"
s.replace(x,y,str,a,b);//s的第x个开始,连续y个替换为str的第a个开始的b个。

翻转

string s="123456";
reverse(s.begin(),s.end());//s="654321"

搜索

  • find:从前往后查找子串或字符出现的位置。
  • rfind:从后往前查找子串或字符出现的位置。
  • find_first_of:从前往后查找何处出现另一个字符串中包含的字符。例如:
  • s1.find_first_of(“abc”); //查找s1中第一次出现"abc"中任一字符的位置
  • find_last_of:从后往前查找何处出现另一个字符串中包含的字符。
  • find_first_not_of:从前往后查找何处出现另一个字符串中没有包含的字符。
  • find_last_not_of:从后往前查找何处出现另一个字符串中没有包含的字符。
  • s.find(“xxx”);//找不到返回string::npos

比较

s.compare("xxx");s比字符串大,返回1,相等返回0,小于返回-1
s1.compare(1, 2, s2, 0, 3);  //比较s1的子串 (1,2) 和s2的子串 (0,3)

分离子串

string s1,s2,s3;
char sa[100],sb[100],sc[100];
char haha[]="abc 123 pc";
sscanf(haha,"%s %s %s",sa,sb,sc);//对应sa sb sc子串
s1=sa;
s2=sb;
s3=sc;
//当用到数字的时候,跟scanf一样,他要传送指针地址
//字符串分离为数字
int a,b,c;
sscanf("1 2 3","%d %d %d",&a,&b,&c);

类型转换

//将string字符串转换为字符串数组
#include<string.h>  //调用strcpy()函数所需头文件
char c[20];
string str="abcd";
strcpy(c,str.c_str());

//int转string
int n = 0;
stringstream ss;
string str;
ss<<n;
ss>>str;
ss.clear();//清空
//string转int
std::string str = "123";
int n = atoi(str.c_str());

下面这个是简易版的正数转换
int strtoint(string s)
{
	int len=s.length();
	int x=0;
	for(int i=0;i<s.length();i++)
	{
		int t=1;
		for(int j=1;j<=len-1-i;j++)
		{
			t=t*10;
		}
		x+=(s[i]-'0')*t;
	}
	return x;
} 

string inttostr(int t)
{
	string s="";
	while(t!=0)
	{
		s+=t%10+'0';
		t=t-t%10;
		t=t/10;
	}
	reverse(s.begin(),s.end());
	return s;
} 

查找子示例

	string a,b;
    cin>>a>>b;
    int res=0;
    for(int i=0;i<a.length()-b.length()+1;i++)
    {
        if(b==a.substr(i,b.length()))
        {
            res++;
        }
    }
    cout<<res<<endl;
    return 0;

其他操作

字符字母转换

char类型的大写字母直接+32变为相应小写,相反,char类型的小写字母直接-32变为相应大写(‘A’:64,‘0’:48)
char类型的数字与int类型数字转化

char a='6';
int b=a-'0';//b=6
===================
int a=6;
char b=a+'0';//b='6'

scanf,cin

scanf的返回值由后面的参数决定scanf("%d%d", &a, &b);
如果a和b都被成功读入,那么scanf的返回值就是2
如果只有a被成功读入,返回值为1
如果a和b都未被成功读入,返回值为0

while(cin>>a)的调用,这里并不是cin的返回值,而是>>操作重载函数
istream& operator>>(istream&, T &);的返回值,其中第二个参数由cin>>后续参数类型决定。其返回值类型为istream&类型,大多数情况下其返回值为cin本身(非0值),只有当遇到EOF输入时,返回值为0。
输入EOF的方法,windows下输入ctrl+z, Linux下输入ctrl+d。

while (cin >> n, n)表示输入n,并且n不为零,则运行while循环里面的,如果为零,则跳出循环
相当于

while (cin >> k) {
	n = k;
	if (n == 0)
		break;
}

小数点

cout.precision(3);
cout<<fixed<<x<<endl;
//或
cout<<setprecision(3)<<s<<endl;//需要#include <iomanip>

iomanip输出格式控制

这里面#include <iomanip>的作用比较多:主要是对cin,cout之类的一些操纵运算子,比如setfill,setw,setbase,setprecision等等。它是I/O流控制头文件,就像C里面的格式化输出一样.以下是一些常见的控制函数的:
dec 置基数为10 相当于"%d"
hex 置基数为16 相当于"%X"
oct 置基数为8 相当于"%o"
setfill(c) 设填充字符为c
setprecision(n) 设显示小数精度为n位
setw(n) 设域宽为n个字符,这个控制符的意思是保证输出宽度为n
setioflags(ios::fixed) 固定的浮点显示
setioflags(ios::scientific) 指数表示
setiosflags(ios::left) 左对齐
setiosflags(ios::right) 右对齐
setiosflags(ios::skipws) 忽略前导空白
setiosflags(ios::uppercase) 16进制数大写输出
setiosflags(ios::lowercase) 16进制小写输出
setiosflags(ios::showpoint) 强制显示小数点
setiosflags(ios::showpos) 强制显示符号
如:
cout<<setw(3)<<1<<setw(3)<<10<<setw(3)<<100; 输出结果为
1 10100 (默认是右对齐)当输出长度大于3时(<<1000),setw(3)不起作用
cout<<setiosflags(ios::fixed)<<setiosflags(ios::right)<<setprecision(2);
合在一起的意思就是,输出一个右对齐的小数点后两位的浮点数

等比数列

等比数列前n项和 S n = a 1 ( 1 − q n ) 1 − q , ( q ≠ 1 ) S_n=\frac{a_1(1-q^n)}{1-q},(q\neq1) Sn=1qa1(1qn),(q=1)

最大公约数

欧几里得方法:只要两数不相等,就反复用大数减小数,直到相等为止,此相等的数就是两数的最大公约数

int gcd(int x,int y)
{
	while(x!=y)
	{
		if(x>y)
		{
			x=x-y;
		}
		else
		{
			y=y-x;
		}
	} 
	return x;
} 

最小公倍数

最 小 公 倍 数 = x / g c d ( x , y ) ∗ y \mathrm{最小公倍数}=x/gcd(x,y)\ast y =x/gcd(x,y)y

res=x/gcd(x,y)*y;//gcd定义见上方

素数

bool isprime(int n)
{
	int sqr=sqrt(n*1.0);
	for(int i=2;i<=sqr;i++)
	{
		if(n%i==0)
		{
			return false;
		}
	}
	return true;
}

十进制转化为二进制

string trans(int n)
{
	string s="";
	for(int a=n;a;a=a/2)
	{
		s=s+(a%2?'1':'0');
	}
	reverse(s.begin(),s.end());
	return s;
}

溢出问题

标准只规定long不小于int的长度,int不小于short的长度
double与int类型的存储机制不同,long int的8个字节全部都是数据位,而double是以尾数,底数,指数的形式表示的,类似科学计数法,因此double比int能表示的数据范围更广。

long long在win32中是确实存在,长度为8个字节;定义为LONG64。
为什么会出现long int呢?在win32现在系统中,长度为4;在历史上,或者其他某些系统中,int长度为2,是short int。
即便是long long,在TI的有款平台中,长度为5也就是说,每种类型长度,需要sizeof才知道,如果可能,最好用union看看里面的数据,可以消除一些类型的假象长度。

类型名称字节数取值范围
signed char1-128~+127
short int2-32768~+32767
int4-2147483648~+2147483647
long int4-2147483648~+2141483647
long long long int8-9223372036854775808~+9223372036854775807
  • unsigned int (unsigned long)
    4字节8位可表达位数:2^32=42 9496 7296
    范围:0 ~ 42 9496 7295 (42*10^8)
  • int (long)
    4字节8位可表达位数:2^32=42 9496 7296
    范围:-21 4748 3648 ~ 21 4748 3647 (21*10^8)
  • long long (__int64)
    8字节8位可表达位数:2^64=1844 6744 0737 0960 0000
    范围:-922 3372 0368 5477 5808 ~ 922 3372 0368 5477 5807 (922*10^16)
  • unsigned long (unsigned __int64)
    8字节8位可表达位数:2^64=1844 6744 0737 0960 0000
    范围:0 ~ 1844 6744 0737 0955 1615 (1844*10^16)

贴一个解决100!的代码,把每个数分开存储,数字逐位计算

#include<stdio.h>
#define max 1000
int a[max]={0};
int main()
{
	a[0]=1;
	for(int i=2;i<=100;i++)
	{
		int carry=0;
		for(int j=0;j<max;j++)
		{
			int s=a[j]*i+carry;
			a[j]=s%10;
			carry=s/10;
		}
	}
	int i=0;
	for(i=max-1;i>0;i--)
	{	
		if(a[i]!=0)
		{
			break;
		}
	}
	for(int j=i;j>=0;j--)
	{
		printf("%d",a[j]);
	}
	printf("\n");
}

三角形面积坐标公式

在△ABC中,若A(x1,y1),B(x2,y2),C(x3,y3) 则△ABC的面积
S = 1 2 × ∣ ( x 1 y 2 + x 2 y 3 + x 3 y 1 − x 2 y 1 − x 3 y 2 − x 1 y 3 ) ∣ \begin{array}{l}S=\frac12\times\vert(x_1y_2+x_2y_3+x_3y_1-x_2y_1-x_3y_2-x_1y_3)\vert\\\end{array} S=21×(x1y2+x2y3+x3y1x2y1x3y2x1y3)
S = 1 2 × ∣ ( ( x 2 −    x 1 ) × ( y 3 − y 1 ) × ( x 3 − x 1 ) × ( y 2 − y 1 ) ) ∣ \begin{array}{l}S=\frac12\times\vert((x_2-\;x_1)\times(y_3-y_1)\times(x_3-x_1)\times(y_2-y_1))\vert\\\end{array} S=21×((x2x1)×(y3y1)×(x3x1)×(y2y1))
海伦公式:
p = ( a + b + c ) / 2 p=(a+b+c)/2 p=(a+b+c)/2
S = p ( p − a ) ( p − b ) ( p − c ) S=\sqrt{p(p-a)(p-b)(p-c)} S=p(pa)(pb)(pc)

数学函数

分解

double modf (double x, double* y); 将参数的整数部分通过指针(y)回传,函数返回小数部分

起到分解函数的作用
取余

double fmod (double, double); 返回两参数相除的余数: 

取整

double ceil (double); 取上整   2.345->3
​double floor (double); 取下整  2.345->2

指数与对数

​double exp (double);
​double pow (double, double);
​double sqrt (double);
​double log (double); 以e为底的对数
​double log10 (double);c++中自然对数函数:log(N)   以10为底:
log10(N)但没有以2为底的函数但是可以用换底公式解决:log2(N)=log10(N)/log10(2)

时间与日期计算

闰年判断

(year%400 || year%4==0 && year%100!=0)

关于时间计算的time.h

#include<time.h>
#include<stdio.h>
#include<stdlib.h>

time_t convert(tm* tp,int year, int month, int day, int hour,
	int minute, int second) {
	tm info;
	info.tm_year = year - 1900;
	info.tm_mon = month - 1;
	info.tm_mday = day;
	info.tm_hour = hour;
	info.tm_min = minute;
	info.tm_sec = second;
	time_t miaoshu= mktime(&info);
	*tp = info;
	return miaoshu;
}

int main() {
	time_t now = time(NULL);
	printf("%d\n", now); //打印当前时间的秒数

	tm info = *localtime(&now);  //把秒数转换为年月日时分秒还有周几 tm是一个结构体

	now += 300 * 24 * 3600;
	info = *localtime(&now); //计算300天后的信息

	tm* f_info=(tm*)malloc(sizeof(tm*));
	time_t start = convert(f_info,2013, 2, 5, 0, 0, 0);  //将输入的日期转化为秒数,同时也会得到日期信息
	printf("%d", (*f_info).tm_wday);

	time_t end = convert(f_info, 2015, 4, 6, 0, 0, 0);
	// 差值
	int  diff = (int)(end - start);
	// 计算是多少天
	int  days = diff / (24 * 3600);
	printf("%d\n", days);
	return 0}

表达式求值

先贴一个简单版的

#include <iostream>
#include <string.h>
using namespace std;
int main()
{
    int n;
    scanf("%d",&n);
        while(n--)
        {
            double a[100],sum=0;
            char c;
            int i=0;
            scanf("%lf",&a[0]);
            c=getchar();
            while(c!='\n')
            {
                double temp;
                scanf("%lf",&temp);
                switch(c)
                {
                    case '+':a[++i]=temp;break;
                    case '-':a[++i]=-temp;break;
                    case '*':a[i]*=temp;break;
                    case '/':a[i]/=temp;break;
                }
                c=getchar();
            }
            for(int j=0;j<=i;j++)
            {
                sum=sum+a[j];
            }
            if(sum-int(sum)<=1e-6) printf("%.0f\n",sum);
            else printf("%.1f\n",sum);
        }
    return 0;
}

持续更新中!

Ref

字符串:http://c.biancheng.net/view/400.html
https://www.cnblogs.com/helloforworld/p/5655493.html
https://www.cnblogs.com/aminxu/p/4704281.html
溢出:https://blog.csdn.net/qq_16234613/article/details/77541722
常用技巧:
https://blog.csdn.net/weixin_36406616/article/details/89381176
dev:
支持c++11:https://blog.csdn.net/u011500062/article/details/44628441
时间:
https://blog.csdn.net/l773575310/article/details/53258230
https://blog.csdn.net/momingqimiao71/article/details/84728845

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值