C++常用方法

背景

下周数据结构实验就要开始考试了,所以总结一点C++的常用方法来学习,希望下周的考试全都会
(#^.^#)(#^.^#)(#^.^#)

1 输出小数点后2位

1.1 C

1
printf("num = %.2f\n", num);

输出结果为:
num = 3.00

1.2 C++头文件#include < iomanip>

1
cout << "num = " << fixed << setprecision(2) << num << endl;

输出结果为:
num = 3.00

2 sort()函数

2.1 背景

最近在刷ACM经常用到排序,以前老是写冒泡,可把冒泡带到OJ里后发现经常超时,所以本想用快排,可是很多学长推荐用sort函数,因为自己写的快排写不好真的没有sort快,所以毅然决然选择sort函数。

2.2 用法

1、sort函数可以三个参数也可以两个参数,必须的头文件#include < algorithm>
2、它使用的排序方法是类似于快排的方法,时间复杂度为n*log2(n)
3、sort函数有三个参数:(第三个参数可不写)

  • 第一个是要排序的数组的起始地址。
  • 第二个是结束的地址(最后一位要排序的地址)
  • 第三个参数是排序的方法,可以是从大到小也可是从小到大,还可以不写第三个参数,此时默认的排序方法是从小到大排序。

2.3 示例

1 以int为例的基本数据类型的sort()使用

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int a[5] = {1, 3, 4, 2, 5};
sort(a, a + 5);
for (int i = 0; i < 5; i++)
cout << a[i] << ' ';
cout << endl;
return 0;
}

输出结果为:
1 2 3 4 5

2 自定义cmp参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{

bool cmp(int x, int y);
int a[5] = {1, 3, 4, 2, 5};
sort(a, a + 5, cmp);
for (int i = 0; i < 5; i++)
cout << a[i] << ' ';

cout << endl;
return 0;
}
bool cmp(int x, int y)
{
return x > y;
}

输出结果为:
5 4 3 2 1

3 memset()函数

3.1 标准库#include <string.h>

3.2 描述

C 库函数 void *memset(void *str, int c, size_t n) 复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符。

3.3 声明

void *memset(void *str, int c, size_t n)

3.4 参数

  • str 指向要填充的内存块。
  • c 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。
  • n 要被设置为该值的字节数。

3.5 返回值

该值返回一个指向存储区 str 的指针。

3.6 程序实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
using namespace std;
int main()
{
char str[30] = "ikun, Hello, world!!!";

cout << "将已开辟内存空间 str 的首 n 个字节的值设为值 c" << endl;
cout << "str before memset: ";
puts(str);
memset(str, '*', 6);
cout << "str after memset: ";
puts(str);

cout << "用于内存空间初始化" << endl;
int demo[10], i;
memset(demo, 0, 40);
for(i = 0; i < 10; i++)
cout << demo[i] << " ";
cout << endl;

return 0;
}

3.7 关于memset初始化与赋值问题

memset是C/C++提供的函数初始化函数,在C中头文件是<string.h>,在C++中头文件是。在此强调一下,可以用memset给一个数组初始化为0、-1或一个很大的数,但是不要用memset函数来赋具体的值,原因如下

  • void *memset(void *s, int ch, size_t n);
    memset是将从地址s开始,字节长度为n的内存全部赋值为ch(注意是每一个字节都赋值为ch)

  • char B[20]; memset(B, 1, sizeof(B));
    因此,当memset(内存地址,1,字节数)这句的意思是要把指定的内存空间的值设置为0x01。对于char型数组B,正好是每个元素占一个字节,所以这样赋值就是将数组B中所有的元素都赋值为1,没有问题。

  • int C[20]; memset(C, 1, sizeof(C));
    但是对于int型数组C,每个元素占四个字节。也就是说将数组C中的每个元素赋值成0x01010101,对应的十进制就是16843009。

4 string类型

4.1 初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s; //默认初始化,一个空字符串
string s1("ssss"); //s1是字面值“ssss”的副本
cout << s1 << endl;

string s2(s1); //s2是s1的副本
cout << s2 << endl;

string s3 = s2; //s3是s2的副本
cout << s3 << endl;

string s4(10, 'c'); //把s4初始化
cout << s4 << endl;

string s5 = "hiya"; //拷贝初始化
cout << s5 << endl;

string s6 = string(10, 'c'); //拷贝初始化,生成一个初始化好的对象,拷贝给s6
cout << s6 << endl;

char cs[] = "12345";
string s7(cs, 3); //复制字符串cs的前3个字符到s当中
cout << s7 << endl;

string s8 = "asac";
cout << s8 << endl;

string s9 = "abcdefghijklmn";
cout << s9 << endl;

string s10(s9, 3, 4); //s10是s9从下标3开始4个字符的拷贝,超过s3.size出现未定义
cout << s10 << endl;
return 0;
}

输出结果为:

4.2 字符串处理操作

4.2.1 substr操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s = "abcdefg";

//s.substr(pos1, n)返回字符串位置为pos1后面的n个字符组成的串
string s2 = s.substr(1, 5);//bcdef
cout << s2 << endl;

//s.substr(pos)//得到一个pos到结尾的串
string s3 = s.substr(4);//efg
cout << s3 << endl;

return 0;
}

输出结果为:
bcdef
efg

4.2.2 insert操作

插入操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str = "to be question";
string str2 = "the ";
string str3 = "or not to be";
string::iterator it;

//s.insert(pos, str)//在s的pos位置插入str
str.insert(6, str2); // to be the question

//s.insert(pos, str, a, n)在s的pos位置插入str中插入位置a到后面的n个字符
str.insert(6, str3, 3, 4); // to be not the question

//s.insert(pos, cstr, n)//在pos位置插入cstr字符串从开始到后面的n个字符
str.insert(10, "that is cool", 8); // to be not that is the question
cout << str << endl;

//s.insert(pos, cstr)在s的pos位置插入cstr
str.insert(10, "to be "); // to be not to be that is the question

//s.insert(pos, n, ch)在s的pos位置上面插入n个ch
str.insert(15, 1, ':'); // to be not to be: that is the question

//s.insert(s.it, ch)在s的it指向位置前面插入一个字符ch,返回新插入的位置的迭代器
it = str.insert(str.begin() + 5, ','); // to be, not to be: that is the question

//s.insert(s.it, n, ch)//在s的it所指向位置的前面插入n个ch
str.insert (str.end(), 3, '.'); // to be, not to be: that is the question...

//s.insert(it, str.ita, str.itb)在it所指向的位置的后面插入[ita,itb)的字符串
str.insert (it+2, str3.begin(), str3.begin() + 3); // to be, or not to be: that is the question...

return 0;
}

4.2.3 erase操作

用来执行删除操作,删除操作有三种

  1. 指定pos和len,其中pos为起始位置,pos以及后面len-1个字符串都删除
  2. 迭代器,删除迭代器指向的字符
  3. 迭代器范围,删除这一范围的字符串,范围左闭右开
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str ("This is an example sentence.");
cout << str << '\n';
// "This is an example sentence."
str.erase (10,8); // ^^^^^^^^
//直接指定删除的字符串位置第十个后面的8个字符
cout << str << '\n';
// "This is an sentence."
str.erase (str.begin()+9);// ^
//删除迭代器指向的字符
cout << str << '\n';
// "This is a sentence."
// ^^^^^
str.erase (str.begin()+5, str.end()-9);
//删除迭代器范围的字符
cout << str << '\n';
// "This sentence."
return 0;
}

4.2.4 append和replace操作

1 append操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str;
string str2 = "Writing ";
string str3 = "print 10 and then 5 more";

//直接追加一个str2的字符串
str.append(str2);
cout << str << endl;

//后面追加str3第6个字符开始的3个字符串
str.append(str3, 6, 3);
cout << str << endl;

//追加字符串形参的前5个字符
str.append("dots are cool", 5);
cout << str << endl;

//直接添加
str.append("here: ");
cout << str << endl;

//添加10个'.'
str.append(10, '.');
cout << str << endl;

//添加str3迭代器范围的字符串
str.append(str3.begin() + 8, str3.end());
cout << str << endl;

str += "lalala";
cout << str << '\n';
return 0;
}

输出结果为:

2 replace操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string base = "this is a test string.";
string str2 = "n example";
string str3 = "sample phrase";
string str4 = "useful.";

string str = base; // "this is a test string."
cout << str << endl;

//第9个字符以及后面的5个字符被str2代替
str.replace(9, 5, str2);
cout << str << endl;

//第19个字符串以及后面的6个字符用str的第7个字符以及后面的6个字符代替
str.replace(19, 6, str3, 7, 6);
cout << str << endl;

//第8个字符以及后面的10个字符用字符串参数代替
str.replace(8, 10, "just a");
cout << str << endl;

//第8个字符以及后面的6个字符用字符串参数的前7个字符替换
str.replace(8, 6, "a shorty", 7);
cout << str << endl;

//第22以及后面的1个字符用3个叹号替换
str.replace(22, 1, 3, '!');
cout << str << endl;

//迭代器的原理同上
// Using iterators:
str.replace(str.begin(), str.end() - 3, str3);
cout << str << endl;

str.replace(str.begin(), str.begin() + 6, "replace");
cout << str << endl;

str.replace(str.begin() + 8, str.begin() + 14, "is coolness",7);
cout << str << endl;

str.replace(str.begin() + 12, str.end() - 4, 4, 'o');
cout << str << endl;

str.replace(str.begin() + 11, str.end(), str4.begin(), str4.end());
cout << str << endl;
return 0;
}

输出结果为:

4.3 字符串搜索操作

4.3.1 find

find函数主要是查找一个字符串是否在调用的字符串中出现过,大小写敏感。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str ("There are two needles in this haystack with needles.");
string str2 ("needle");

// different member versions of find in the same order as above:
//在str当中查找第一个出现的needle,找到则返回出现的位置,否则返回结尾
int found = str.find(str2);
if (found != string::npos)
cout << "first 'needle' found at: " << found << '\n';

//在str当中,从第found+1的位置开始查找参数字符串的前6个字符
found = str.find("needles are small", found + 1, 6);
if (found != string::npos)
cout << "second 'needle' found at: " << found << '\n';

//在str当中查找参数中的字符串
found = str.find("haystack");
if (found != string::npos)
cout << "'haystack' also found at: " << found << '\n';

//查找一个字符
found = str.find('.');
if (found != string::npos)
cout << "Period found at: " << found << '\n';

//组合使用,把str2用参数表中的字符串代替
// let's replace the first needle:
str.replace(str.find(str2), str2.length(), "preposition");
cout << str << '\n';

return 0;
}

输出结果为:

4.3.2 rfind

rfind函数就是找最后一个出现的匹配字符串,返回的位置仍然是从前往后数的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str ("The sixth sick sheik's sixth sheep's sick.");
string key ("sixth");// ^
//rfind是找最后一个出现的匹配字符串
int found = str.rfind(key);
if (found != string::npos)
{
cout << found << endl; //输出23
str.replace (found,key.length(),"seventh"); //找到的sixth替换成seventh
}
cout << str << '\n';
return 0;
}

输出结果为:

4.4 compare

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1 = "123", s2 = "123";
cout << s1.compare(s2) << endl; //0

s1 = "123", s2 = "1234";
cout << s1.compare(s2) << endl; //-1

s1 = "1234", s2 = "123";
cout << s1.compare(s2) << endl; //1

string str1 ("green apple");
string str2 ("red apple");

if(str1.compare(str2) != 0)
cout << str1 << " is not " << str2 << '\n';
//str1的第6个字符以及后面的5个字符和参数比较
if(str1.compare(6, 5, "apple") == 0)
cout << "still, " << str1 << " is an apple\n";

if(str2.compare(str2.size() - 5, 5, "apple") == 0)
cout << "and " << str2 << " is also an apple\n";

//str1的第6个字符以及后面的5个字符和str2的第4个字符以及后面的5个字符比较
if(str1.compare(6, 5, str2, 4, 5) == 0)
cout << "therefore, both are apples\n";

return 0;
}

由于string重载了运算符,可以直接用>,<,==来进行比较,也很方便。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,可以邮件至 xingshuaikun@163.com。

×

喜欢就点赞,疼爱就打赏