c++篇
1.数组的长度:sizeof()
字符串的长度:length()
memset
2、memset()需要调用cstring的库
只能放在函数里面
void *memset(void *str, int c, size_t n)
有可能出错的地方: 如果对int数组进行初始化为非0的整数,会出现错误,如:
memset(arr, 1, sizeof(int)*length)
每个数都被初始化为00000001 00000001 00000001 00000001。而不是1
因此c->0-1\字符
3、字符串到数组的迁移要有 -“0”
for(int i = 0; i < s.length(); i++) {
int temp = s[i] - '0';
}
4、注意数组的下标是从0开始的
sort
5、sort 函数在头⽂件 #include ⾥⾯,主要是对⼀个数组进⾏排序( int arr[] 数组或
者 vector 数组都⾏), vector 是容器,要⽤ v.begin() 和 v.end() 表示头尾;⽽ int arr[] ⽤ arr 表示数
组的⾸地址, arr+n 表示尾部~
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool cmp(int a, int b) { // cmp函数返回的值是bool类型
return a > b; // 从⼤到⼩排列
}
int main() {
vector<int> v(10);
for (int i = 0; i < 10; i++) {
cin >> v[i];
}
sort(v.begin(), v.end());// 因为这⾥没有传⼊参数cmp,所以按照默认,v从⼩到⼤排列
int arr[10];
for (int i = 0; i < 10; i++) {
cin >> arr[i];
}
sort(arr, arr + 10, cmp); // arr从⼤到⼩排列,因为cmp函数排序规则设置了从⼤到⼩
return 0;
}
动态数组
6、动态数组的创建
int *temp=new int [n];
for(int j=0;j<n;j++)
temp[j]=a[j];
sort(temp+l-1,temp+r,cmp);
delete []temp;
使用new进行数组的创建要记得删除指针
以三维整型数组array[n1][n2][n3]为例。
先遵循从外层到里层,逐层申请的原则:
最外层指针是array,它是个三维指针,所指向的是array[],其为二维指针。所以给array
申请内存应:
array=(int***)calloc(n1,sizeof(int**));
次层指针是array[],它是个二维指针,所指向的是array[][],其为一维指针。所以给array[]
申请内存应:
for(i=0;i<n1;i++)
{
array[i]=(int**)calloc(n2,sizeof(int*));
}
最内层指针是array[][],它是个一维指针,所指向的是array[][][],其是个整型常量。所以给array[][]申请内存应:
for(i=0;i<n1;i++)
{
for(j=0;j<n2;j++)
{
array[i][j]=(int*)calloc(n3,sizeof(int));
}
}
当然,你可以把它们整合在一起为:
int i,j,k;
int n1,n2,n3;
int ***array;
scanf("%d%d%d",&n1,&n2,&n3);
array=(int***)calloc(n1,sizeof(int**));
for(i=0;i<n1;i++)
{
array[i]=(int**)calloc(n2,sizeof(int*));
for(j=0;j<n2;j++)
{
array[i][j]=(int*)calloc(n3,sizeof(int));
for(k=0;k<n3;k++)
{
array[i][j][k]=i+j+k+1;
}
}
vector
7、vector用法:
构建动态数组:
2.1) 建立空的 vector: vector f1; // 建立空的 vector
(2.2) 建立 4 个元素为 100 的 v: vector f2(4, 100);
(2.3) 用 iterator 直接从 f2 复制元素: vector f3(f2.begin(), f2.end());
vector<int>v(v1);//复制v1到v
(2.4) 从 array(stack) 复制: vector f4(array, array + sizeof(array)/sizeof(int));
(2.5) 从 array(heap) 复制: vector f5(arr2, arr2+CNT)
vector的一些函数
reverse(v.begin(),v.end());//反置
insert(v.begin(),0)//在头部插入0
push()//尾部插入
pop()//尾部删除
push()//尾部插入
在末尾添加元素
在当前最后一个元素之后,在vector 的末尾添加一个新元素。val的内容被复制(或移动)到新元素。
这有效地将容器大小增加了一倍,当且仅当新向量大小超过当前向量容量时,这会导致分配的存储空间的自动重新分配。
这里的push_back是在vector容器的末尾增添元素,所以容器的容量会增大。如果要填充容器的话,!!!请用cin>>v[i]/头部插入insert
setprecision
8、setprecision()结和fixed一起使用可以表示显示有效数位后几位数
#include <bits/stdc++.h>
使用setprecision(n)可控制输出流显示浮点数的数字个数。C++默认的流输出数值有效位是6。
#include <iostream.h>
#include <iomanip.h> //要用到格式控制符
void main()
{
double amount = 22.0/7;
cout <<amount <<endl;
cout <<setprecision(0) <<amount <<endl
<<setprecision(1) <<amount <<endl
<<setprecision(2) <<amount <<endl
<<setprecision(3) <<amount <<endl
<<setprecision(4) <<amount <<endl;
cout <<setiosflags(ios::fixed);
cout <<setprecision(8) <<amount <<endl;
cout <<setiosflags(ios::scientific)
cout <<setprecision(6); //重新设置成原默认设置
}
运行结果为:
3.14286
3
3
3.1
3.14
3.143
3.14285714
3.14285714e+00
该程序在32位机器上运行通过。
在用浮点表示的输出中,setprecision(n)表示有效位数。(不结合fixed是指有效位数)
第1行输出数值之前没有设置有效位数,所以用流的有效位数默认设置值6:第2个输出设置了有效位数0,C++最小的有效位数为1,所以作为有效位数设置为1来看待:第3~6行输出按设置的有效位数输出。
next_permutation 全排列算法
9、next_permutation 全排列算法
头文件<algorithm>
next_permutation(start,end),和prev_permutation(start,end)。这两个函数作用是一样的,区别就在于前者求的是当前排列的下一个排列,后一个求的是当前排列的上一个排列。就是按顺序排列字典的后一个\前一个
当前序列不存在下一个排列时,函数返回false,否则返回true
例子:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int num[3]={1,2,3};
do
{
cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<endl;
}while(next_permutation(num,num+3));
return 0;
}
输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
其中的序列一定要按顺序排好
若数组里面的是{2,1,3}
结果就会变成
输出:
2 3 1
3 1 2
3 2 1
若排列本来就是最大的了没有后继,则next_permutation执行后,会对排列进行字典升序排序,相当于循环
若数组里面的是{3,2,1}
结果就会变成
输出: 1 2 3
由此可以看出,next_permutation(num,num+n)函数是对数组num中的前n个元素进行全排列,同时并改变num数组的值。
unique、erase
10、
找相邻的元素是否重复unique(如果要去除数组里面的相同的元素,也可以使用这个语句,不过要先进行排序)
删除erase
#include<algorithm>
unique
返回值:指向未删除的最后一个元素之后的元素的迭代器
vecSrc.erase( unique( vecSrc.begin(), vecSrc.end() ), vecSrc.end() );
// unique algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::unique, std::distance
#include <vector> // std::vector
bool myfunction (int i, int j) {
return (i==j);
}
int main () {
int myints[] = {10,20,20,20,30,30,20,20,10}; // 10 20 20 20 30 30 20 20 10
std::vector<int> myvector (myints,myints+9);
// using default comparison:
std::vector<int>::iterator it;
it = std::unique (myvector.begin(), myvector.end()); // 10 20 30 20 10 ? ? ? ?
// ^
myvector.resize( std::distance(myvector.begin(),it) ); // 10 20 30 20 10
// using predicate comparison:
std::unique (myvector.begin(), myvector.end(), myfunction); // (no changes)
// print out content:
std::cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
输出:
myvector 包含:10 20 30 20 10
erase
int main( )
{
std::vector<int> c{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
print_container(c);
c.erase(c.begin());
print_container(c);
c.erase(c.begin()+2, c.begin()+5);
print_container(c);
// Erase all even numbers (C++11 and later)
for (std::vector<int>::iterator it = c.begin(); it != c.end(); ) {
if (*it % 2 == 0) {
it = c.erase(it);
} else {
++it;
}
}
print_container(c);
}
Output:
0 1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 6 7 8 9
1 7 9
删除一定是v.erase(v.begin
优先队列 priority_queue
11、algo_38
优先队列 priority_queue
#include<queue>
priority_queue<Type,Container,Functional>
其中:
Type是数据类型
Container是容器类型(Container必须是用数组实现的容器,比如vector等默认为vector
Functional就是比较的方式,也是我们后边实现排序的重要角色
可以自动给队列进行升序\降序排列
priority_queue<int, vector<int>, greater<int>> q;//升序
priority_queue<int, vector<int>, less<int>> q;//降序
//greater和less是std中实现的两个仿函数
当然如果对排序有要求的话
auto cmp = [&](const auto& a, const auto& b) {
return a.first < b.first ;
//first+second之和小的在后大的在前
};
priority_queue < pair<int, int>, vector<pair<int, int>>, decltype(cmp)> PairQueue(cmp);
//decltype是自动识别类型
string的substr函数、find函数
substr函数:
头函数
#include<string>
分割字符串
原型: string substr (size_t pos = 0, size_t len = npos) const;
功能:在原字符串中截取子字符串。
参数说明:pos为起始位置,len为要截取子字符串的长度。
返回值:子字符串。
string s = strs.substr(i, pos - i);
find函数
头函数
#include<string>
函数原型:size_t find(const string& str, size_t pos = 0) const;
功能说明:从pos位置开始查找子字符串str第一次出现的位置
参数说明:str为要查找的子字符串,pos从为初始查找位置
返回值:找到的话返回子字符串第一次出现的位置,否则返回string::npos
swap 函数
头函数
#include <utility>
就是两个数之间/ 两个数组之间 /同一个数组中间的两个元素可以相互替换
swap(x,y)/swap(foo,bar)/swap(a[x],a[y])
// swap algorithm example (C++11)
#include <iostream> // std::cout
#include <utility> // std::swap
int main () {
int x=10, y=20; // x:10 y:20
std::swap(x,y); // x:20 y:10
int foo[4]; // foo: ? ? ? ?
int bar[] = {10,20,30,40}; // foo: ? ? ? ? bar: 10 20 30 40
std::swap(foo,bar); // foo: 10 20 30 40 bar: ? ? ? ?
std::cout << "foo contains:";
for (int i: foo) std::cout << ' ' << i;
std::cout << '\n';
return 0;
}
toupper 、tolower、isupper、islower、isalpha函数
头函数
#include<cctype>
toupper
将小写字母转换为大写
如果c是小写字母并且具有等效的大写字母,则将c 转换为其等效的大写字母。如果不可能进行这样的转换,则返回的值是c不变。
返回值
如果存在这样的值,则等效于c 的大写,否则为c(未更改)。该值作为int值返回,可以隐式转换为char。
/* toupper example */
#include <stdio.h>
#include <ctype.h>
int main ()
{
int i=0;
char str[]="Test String.\n";
char c;
while (str[i])
{
c=str[i];
putchar (toupper(c));
i++;
}
return 0;
}
putchar是将char转换为int型,再直接输出
tolower
将大写字母转换为小写字母
如果c是大写字母并且具有等效的小写字母,则将c 转换为其等效的小写字母。如果不可能进行这样的转换,则返回的值是c不变。
与上同理
islower
检查c是否为小写字母。
请注意,被视为字母的内容可能取决于所使用的语言环境;在默认的“C”语言环境中,小写字母可以是:abcdefghijklmnopqrstu vwxyz。
返回值
如果确实c是小写字母,则 该值不同于零(即true )。否则为零(即false )
最小公倍数、最小公因数
最大公因数
辗转相除法
计算gcd(18,48)}时,先将48除以18得到商2、余数12,然后再将18除以12得到商1、余数6,再将12除以6得到商2、余数0,即得到最大公因数6。我们只关心每次除法的余数是否为0,为0即表示得到答案。
int GCD(T a, T b) {
if(b) while((a %= b) && (b %= a));
return a + b;
}
最小公倍数
int GCD(int a, int b) {
if(b) while((a %= b) && (b %= a));
return a + b;
}
int LCM(int a, int b) {
return a * b / GCD(a, b);
}
强转
#include<iostream>
#include<iostream>
static_cast (expression) 函数能够将括号中的表达式转换成new_type类型的数
值,⽐比如static_cast (c[i])能将c[i]以int类型返回~
int->string
用for循环吧
string->int
#include <iostream>
#include <string>
int main() {
std::string str = "123";
int num;
// 使用stoi()将str1的值存储到x
num = std::stoi(str);
std::cout << num;
return 0;
}
char->int
直接转换
char a = '0';
int ia = a - '0';
/* check here if ia is bounded by 0 and 9 */
string->char
#include<cstring>
s.c_srt();
set、map
string的插入、替换、删除
string 插入insert
#include <iostream>
#include <string>
int main ()
{
std::string str="to be question";
std::string str2="the ";
std::string str3="or not to be";
std::string::iterator it;
// used in the same order as described above:
str.insert(6,str2); // to be (the )question 位置,字符串
str.insert(6,str3,3,4); // to be (not )the question 位置,字符串,子字符串起始位置,子字符串的长度
str.insert(10,"that is cool",8); // to be not (that is )the question 位置,字符串,子字符串长度
str.insert(10,"to be "); // to be not (to be )that is the question 位置,字符串
str.insert(15,1,':'); // to be not to be(:) that is the question
it = str.insert(str.begin()+5,','); // to be(,) not to be: that is the question
str.insert (str.end(),3,'.'); // to be, not to be: that is the question(...)
str.insert (it+2,str3.begin(),str3.begin()+3); // (or )
std::cout << str << '\n';
return 0;
}
stirng replace
// replacing in a string
#include <iostream>
#include <string>
int main ()
{
std::string base="this is a test string.";
std::string str2="n example";
std::string str3="sample phrase";
std::string str4="useful.";
// replace signatures used in the same order as described above:
// Using positions: 0123456789*123456789*12345
std::string str=base; // "this is a test string."
str.replace(9,5,str2); // "this is an example string." (1) 位置,被替换的长度,要替换的字符串
str.replace(19,6,str3,7,6); // "this is an example phrase." (2) 位置,被替换的长度,要替换的字符串,要替换字符串的位置,要替换的字符串的长度
str.replace(8,10,"just a"); // "this is just a phrase." (3) 位置,被替换的长度,要替换的字符串
str.replace(8,6,"a shorty",7); // "this is a short phrase." (4)位置,被替换的长度,要替换的字符串,要替换字符串的位置,要替换的字符串的长度
str.replace(22,1,3,'!'); // "this is a short phrase!!!" (5)位置,被替换的长度,要重复的次数,字符
// Using iterators: 0123456789*123456789*
str.replace(str.begin(),str.end()-3,str3); // "sample phrase!!!" (1)
str.replace(str.begin(),str.begin()+6,"replace"); // "replace phrase!!!" (3)
str.replace(str.begin()+8,str.begin()+14,"is coolness",7); // "replace is cool!!!" (4)
str.replace(str.begin()+12,str.end()-4,4,'o'); // "replace is cooool!!!" (5)
str.replace(str.begin()+11,str.end(),str4.begin(),str4.end());// "replace is useful." (6)
std::cout << str << '\n';
return 0;
}
string erase
// string::erase
#include <iostream>
#include <string>
int main ()
{
std::string str ("This is an example sentence.");
std::cout << str << '\n';
// "This is an example sentence."
str.erase (10,8); // ^^^^^^^^ 位置,删除长度
std::cout << str << '\n';
// "This is an sentence."
str.erase (str.begin()+9); // ^ 删除的位置
std::cout << str << '\n';
// "This is a sentence."
str.erase (str.begin()+5, str.end()-9); // ^^^^^ 删除的起始位置,删除的最终位置
std::cout << str << '\n';
// "This sentence."
return 0;
}
scanf
switch
switch(expression){
case constant-expression :
statement(s);
break; // 可选的
case constant-expression :
statement(s);
break; // 可选的
// 您可以有任意数量的 case 语句
default : // 可选的
statement(s);
}
**switch⾥里里⾯面只能char型或者int型