C++全系列学习(基础篇)

RechoYit 2024-10-25 10:35:02 阅读 90

一、基础语法

1、数据类型

基本数据类型:

int 用于表示整数
float 用于表示单精度浮点数
double 用于表示双精度浮点数
char 用于表示字符
bool 用于表示布尔值,只能取 <code>true 或 false
void 表示无类型,通常用于函数返回类型或指针类型

复合数据类型:

数组 由相同类型的元素组成的集合
结构体(<code>struct) 由不同类型的成员组成的复合类型
枚举(enum 一组具有命名值的常量
类(class 一种封装数据和操作的方式,支持面向对象编程
指针(pointer 存储内存地址的变量,用于间接访问内存中的数据
引用(reference 提供现有变量的别名,用于简化代码和避免复制

引例:

int a = 10;

cout<<sizeof(a)<<endl; //统计该变量所占内存大小

//科学计数法

float a = 3e2; //表示3*10^2

float a = 3e-2; //表示3*10^-2

//字符串

a = 'b'

a = "b"

a = "hello" //单个字符时可用''或"",字符串只能用""

//转义字符

cout<<"hello\n"<<endl; \n为换行符

cout<<"aa\thello"<<endl;

cout<<"aaaa\thello"<<endl;

cout<<"a\thello"<<endl; //\t为水平制表符,可整齐输出数据

2、运算符

算数运算符

/可以是两个小数相除,若是两个整数相除则结果向下取整

%为取模

递增递减

++ 前置递增 a=2,b=++a a=3,b=3
++ 后置递增 a=2,b=a++ a=3,b=2
-- 前置递减 a=2,b=--a a=1,b=1
-- 后置递减 a=2,b=a-- a=1,b=2

所谓前置就是先加1,后置就是先运算

逻辑运算符

运算符 术语 示例 结果
!a 若a为假则!a为真
&& a&&b 若a与b都为真则为真,否则为假
|| a||b 若a与b有一个为真则为真,否则为假

3、数组

一维数组

3种定义方式:

1)数据类型 数组名[数组长度];

2)数据类型 数组名[数组长度] = {值1,值2,……}

注意:若实际值与长度不同时,自动用0补足

3)数据类型 数组名[] = {值1,值2,……}

<code>int arr[10];

arr[0] = 1;

int arr2[4] = {1,2,3,4};

int arr3[] = {1,2,3};

获取首地址

两种方式:arr或&arr[0]

数组长度统计

数组占用内存空间大小:sizeof(arr)

数组单个元素占用内存空间大小:sizeof(arr[0])

数组长度:sizeof(arr) / sizeof(arr[0])

冒泡排序(后文具体介绍)

比较相邻元素: 从第一个元素开始,比较相邻的两个元素,如果它们的顺序不正确(比如在升序排序中,前一个元素大于后一个元素),则交换它们。

一次遍历完成: 经过一次遍历,最大(或最小)的元素会被移到序列的最后位置。

重复步骤1和2: 重复进行上述步骤,直到序列完全有序。在每次遍历中,待排序序列的长度减一,因为每次遍历都会将一个元素放置到了正确的位置上

二维数组

定义方式

二维数组定义的4种方式:

1)数据类型 数组名[ 行数 ][ 列数 ];

2)数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2} ,{数据3,数据4} };

3)数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};

4)数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4}

注意:常用第二种,可读性较强

int array2D[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

cout << "Array elements:" << endl;

for(int i = 0; i < 3; ++i) {

for(int j = 0; j < 3; ++j) {

cout << array2D[i][j] << " ";

}

cout << endl;

}

Array elements:

1 2 3

4 5 6

7 8 9

计算行数与列数

二维数组的行数:sizeof(arr) / sizeof(arr[0])

二维数组的列数:sizeof(arr[0]) / sizeof(arr[0][0])

地址

二维数组首地址:arr[0] 或 &arr[0][0]

二维数组第1个元素的地址: arr[0] 或 &arr[0][0]

二维数组第 0 行的地址: arrarr[0]arr + 0 

二维数组第 i 行的地址:arr[i]arr + i

二维数组第 i 行首元素的地址:arr[i]arr + i*(arr + i)&a[0] + i

二维数组第 i 行第 j 列元素的地址:&arr[i][j]*(arr + i) + j

4、循环

for循环

<code>#include<bits/stdc++.h>

using namespace std;

int main ()

{ int sum=0;

for (int i=1; i<=100 ; ++i)

sum+=i;

cout<<sum;

return 0;

}

while循环

while(表达式)语句;

while(表达式){

    语句1;

    语句2;

}

例:用while打印数组

#include <iostream>

using namespace std;

int main() {

int array[] = {1, 2, 3, 4, 5};

int length = sizeof(array) / sizeof(array[0]); // 计算数组的长度

cout << "Array elements: ";

int i = 0; // 初始化计数器

while (i < length) {

cout << array[i] << " ";

i++; // 更新计数器

}

cout << endl;

return 0;

}

do-while循环

do{

    语句1;

    语句2;

}

while(条件表达式)

示例:获取输入,直到输入的值为正数为止

#include <iostream>

using namespace std;

int main() {

int num;

do {

cout << "请输入一个正数:";

cin >> num;

} while (num <= 0);

cout << "你输入的正数是:" << num << endl;

return 0;

}

while和do-while的区别

while 循环

while 循环中,循环条件会在每次循环开始之前被检查。如果条件为真,循环体会执行,然后再次检查条件。如果条件为假,循环终止。这意味着,如果条件一开始就为假,循环体可能一次都不会执行。

do-while 循环

do-while 循环中,循环体会先执行一次,然后再检查循环条件。只要条件为真,循环体会继续执行,否则循环终止。这意味着,do-while 循环至少会执行一次循环体,即使条件一开始就为假。

嵌套循环

示例:水仙花数字

#include<bits/stdc++.h>

using namespace std;

int main()

{ for (int a=1; a<=9; ++a)

for (int b=0; b<=9; ++b)

for (int c=0; c<=9; ++c)

{ if (a*a*a+b*b*b+c*c*c==a*100+b*10+c)

cout<<setw(6)<<a*100+b*10+c; //setw函数控制输出场宽

}

return 0;

}

5、条件语句(if)

单行格式if

#include <iostream>

using namespace std;

int main() {

int num;

cout << "请输入一个整数:";

cin >> num;

if (num > 0) {

cout << "这是一个正数。" << endl;

}

return 0;

}

多行格式if

#include <iostream>

using namespace std;

int main() {

int num;

cout << "请输入一个整数:";

cin >> num;

if (num > 0) {

cout << "这是一个正数" << endl;

}

else if (num == 0){

cout << "0" << endl;

}

else{

cout << "这是一个负数" << endl;

}

return 0;

}

6、结构体

语法

struct 结构体名 { 结构体成员列表 };

结构体创建变量

#include <iostream>

using namespace std;

// 定义一个名为 Person 的结构体

struct Person {

string name;

int age;

double height;

};

int main() {

// 创建一个 Person 类型的对象

struct Person person1;

// 给结构体成员赋值

person1.name = "Alice";

person1.age = 30;

person1.height = 5.6;

// 输出结构体成员的值

cout << "Name: " << person1.name << endl;

cout << "Age: " << person1.age << endl;

cout << "Height: " << person1.height << endl;

struct Person person2 = {"BEN",40,4.4};

return 0;

}

结构体数组

#include <iostream>

#include <string>

using namespace std;

// 定义一个名为 Person 的结构体

struct Person {

string name;

int age;

double height;

};

int main() {

// 使用大括号初始化结构体数组

Person people[3] = {

{"Alice", 30, 5.6},

{"Bob", 25, 6.0},

{"Charlie", 35, 5.9}

};

// 输出结构体数组中每个结构体的成员值

for (int i = 0; i < 3; ++i) {

cout << "Person " << i+1 << ":" << endl;

cout << "Name: " << people[i].name << endl;

cout << "Age: " << people[i].age << endl;

cout << "Height: " << people[i].height << endl;

cout << endl;

}

return 0;

}

结构体指针

#include <iostream>

using namespace std;

// 定义一个名为 Person 的结构体

struct Person {

string name;

int age;

double height;

};

int main() {

// 创建一个 Person 类型的结构体指针

struct Person* p = new Person;

// 使用 -> 运算符给结构体成员赋值

p->name = "Alice";

p->age = 30;

p->height = 5.6;

// 使用 -> 运算符访问结构体成员并输出

cout << "Name: " << p->name << endl;

cout << "Age: " << p->age << endl;

cout << "Height: " << p->height << endl;

// 记得释放动态分配的内存

delete p;

return 0;

}

结构体嵌套

结构体中成员是另一个结构体

7、函数

主函数为main(),但可以创作其他函数进行运算,只需在主函数中调用即可,以下以阶乘为例

#include <iostream>

using namespace std;

int factorial(int n){

if(n==1)

return n;

else

return n*factorial(n-1);

}

int main()

{

int n;

cout << "请输入整数:" << endl;

cin >> n;

cout << "整数:" << n << "的阶乘为:" << factorial(n) << endl;

cout << "\n" << endl;

return 0;

}

二、STL库

STL(Standard Template Library)是 C++ 标准库的一部分,它提供了一组通用的模板类和函数,用于实现常见的数据结构和算法。STL 的设计旨在提供一种高效、灵活和可重用的方法来处理数据结构和算法问题。总的来说,STL库装了许多算法和组件,包含多种函数,可用于开发各类应用程序

1、快速排序(Sort)

基本用法

格式:

void sort(起始地址,结束地址,比较函数);

#include<algorithm>

#include<iostream>

using namespace std;

int main(){

int a[] = {2,3,5,4,1,8,6,9};

sort(a,a+8);//a为数组的开头,a+8就等于排序到数组的第8个元素

for(int i=0;i<6;i++)

cout<<a[i]<<" ";

}

cmp用法

在sort比较函数中传入排序函数,>为降序,<为升序

#include<algorithm>

#include<iostream>

using namespace std;

bool cmp(int x,int y)

{

if(x>y)return true;//降序

return false;

}

int main(){

int a[] = {2,3,5,4,1,8,6,9};

sort(a,a+8,cmp);//a为数组的开头,a+8就等于排序到数组的第8个元素

for(int i=0;i<6;i++)

cout<<a[i]<<" ";

}

2、关联容器(Map)

map是一个关联容器,它提供了一种将键与值关联起来的方式,map中的每个元素都是一个键(key-value pair),其中键(key)是唯一的,值(value)则可以不唯一。它基于红黑树(Red-Black Tree)实现。

注意:map不允许容器中有重复的key值,multimap允许容器中有重复的key

格式:

map(数据类型,数据类型)一个自定义的名称;

#include <iostream>

#include <map>

int main() {

map<string, int> phonebook;

phonebook["Alice"] = 123456;

phonebook["Bob"] = 789012;

phonebook["Charlie"] = 345678;

cout << "Bob's phone number: " << phonebook["Bob"] << endl;

phonebook["Alice"] = 111111;

phonebook.erase("Charlie");

// 遍历元素

for (const auto& pair : phonebook) {

cout << pair.first << "'s phone number: " << pair.second <<endl;

}

return 0;

}

1)构造

map<T1,T2> mp; map对象默认构造形式
map(const map &qmp); 拷贝构造函数

2)赋值

map& operator=(const map &mp); 重载等号操作符

3)大小和交换

size();

返回容器中元素数目
empty(); 判断容器是否为空
swap(st); 交换两个集合容器

4)插入和删除

insert(elem); 在容器中插入元素
clear(); 清除所有元素
erase(pos); 删除pos迭代器所指的元素,返回下一个元素的选代器
erase(beg,end); 删除区间[beg,end)的所有元素,返回下一个元素的迭代器
erase(elem); 删除容器中值为elem的元素。

5)查找和统计

find(key); 查找是否存在key,若存在返回该键的元素的迭代器,若不存在,返回set.end()
count(key); 统计key的元素的个数

3、栈(stack)

相当于是一个小箱子,每次向箱子顶部塞入数据,遵循先进后出(Last In, First Out,LIFO)的原则。栈可以被看作是一种容器,其中元素按照后进先出的顺序进行插入和删除。

格式:

<code>#include<stack>

stack<数据类型>一个自定义的名字;

或:

stack 一个自定义的名字;

栈的成员函数

.empty() 判断栈是否为空,空则返回true
.push(…) 在栈顶增加元素
.pop() 在栈顶移除元素
.top() 返回栈顶元素
.size() 返回栈的元素数量

代码示例:

<code>#include<stack>

#include<iostream>

using namespace std;

stack<int> st;

int main(){

st.push(1);

st.push(2);

st.push(3);

cout<<st.top();

return 0;

}

输出:

3

4、动态数组容器(Vector)

使用的时候可以看作数组,但他相对于数组来说可以动态扩展,增加长度

1)构造

头文件:#include<vector>

构造:vector<T> v ;

放入数据:v.push_back(…);

迭代器:vector<int>::iterator

将[v.begin(),v.end())区间中的元素拷贝给本身:vector(v.begin(),v.end());

将n个elem拷贝给本身:vextor(n,elem);

拷贝构造函数:vector(const vector &v) ;

void printVector(vector<int>& v)

{//利用迭代器打印 v

for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)

{

cout << *it << " ";

}

cout << endl;

}

void text01()

{

vector<int> v1;

for (int i = 0; i < 5; ++i)

{

v1.push_back(i);//向v1末尾添加数据

}

vector<int> v2(v1.begin(), v1.end()); //构造2

vector<int> v3(5, 5); //构造3

vector<int> v4(v3); //构造4

cout << "打印v2: ";

printVector(v2);

cout << "打印v3: ";

printVector(v3);

cout << "打印v4: ";

printVector(v4);

}

2)遍历

v.begin() 返回迭代器,这个迭代器指向容器中第一个数据
v.end() 返回迭代器,这个迭代器指向容器元素的最后元素的下一个位置
vector<int>::iterator  拿到这种容器的迭代器类型

第一种遍历方式

<code>vector<int>::iterator pBegin = v.begin();

vector<int>::iterator pEnd = v.end();

while(pBegin != pEnd){

cout<<*pBegin<<endl;

pBegin++;

}

第二种遍历方式

for (vector<int>::iterator it = v.begin();it != v.end();it++){

cout<<*it<<endl;

}

3)赋值

vector& operator=(const vector &v);  重载赋值运算符
assign(v.begin(),v.end()); 将[v.begin(),v.end())区间中的元素赋值给本身
assign(n,elem); 将n个elem赋值给本身

<code>void printVector(vector<int>& v)

{//利用迭代器打印 v

for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)

{

cout << *it << " ";

}

cout << endl;

}

void text02()

{

vector<int> v1,v2;

for (int i = 0; i < 5; ++i)

{

v1.push_back(i);

}

v2 = v1;

vector<int> v3,v4;

v3.assign(v1.begin(), v1.end());

v4.assign(10,100);

cout << "打印v2: ";

printVector(v2);

cout << "打印v3: ";

printVector(v3);

cout << "打印v4: ";

printVector(v4);

}

4)容量和大小

empty(); 判断容器是否为空
capacity(); 容器容量
size(); 容器中元素个数
resize(int num); 重新指定长度num,变短删末尾元素,变长以默认值填充新位置
resize(int num,elem); 重新指定长度num,变短删末尾元素,变长以elem填充新位置

5)插入和删除

push_back(elem); 尾部插入元素elem
pop_back(); 删除最后一个元素
insert(const_iterator pos,elem); 指向的位置pos处插入一个元素elem
insert(const_iterator pos,int count,elem); 指向的位置pos处count元素elem
erase(const_iterator pos); 指向的位置pos处删除元素
erase(const_iterator start,const_iterator end);

删除start到end之间的元素

clear(); 清空所有元素

6)数据存取

at(int id); 返回id处数据

operator[];

返回[]处数据
front(); 返回第一个数据
back(); 返回最后一个数据

7)互换容器

swap(vec); 将vec与本身元素互换

<code>v1.swap(v2)

8)预留空间

reserve(int len); 预留len个元素长度

当数据量较大时可以一开始就利用reserve预留空间

5、String

string内部封装了许多成员方法,如find,copy,delete,insert,replace等

头文件:#include<string>

1)构造

string(); 构造空字符串
string(const char* s); 拷贝s所指向的字符串序列,使字符串s初始化
string(const char* s, size_t n); 拷贝s所指向的字符串序列的第n个到结尾的字符
string(size_t n, char c); 将字符c复制n次
string(const string& str); 拷贝构造函数。使用一个string对象初始化另一个对象
string(const string& str, size_t pos, size_t n = npos); 拷贝s中从pos位置起的n个字符,若npos>字符串长度,就拷贝到字符串结尾结束

<code>#include<string>

void test1(){

string s1; //创建空字符串,使用无参构造函数

const char*str = "hello";

string s2(str);

string s3(s2); //调用拷贝构造函数

string s4(10,'a'); //将字符a复制10次

string s5(s2,1);//拷贝s2所指向的字符串序列的第1个到结尾的字符

}

2)赋值

string& operator=(const char* s); char*类型字符串赋值给当前的字符串
string& operator=(const string &s); 把字符串s赋给当前的字符串
string& operator=(char c); 字符赋值给当前的字符串
string& assign(const char *s); 把字符串s赋给当前的字符串
string& assign(const char *s, int n); 把字符串s的前n个字符赋给当前的字符串
string& assign(const string &s); 把字符串s赋给当前字符串
string& assign(int n, char c); 用n个字符c赋给当前字符串

3)字符串插入、拼接和删除

插入:

void push_back (char c); 向字符串末尾追加一个字符

string& insert(size_t pos, const string& str);

插入字符串拷贝
string& insert (size_t pos, const char* s); 插入c形式的字符串
string& insert (size_t pos, const char* s, size_t n); 将字符串s的前n个字符插到pos位置

<code>#include<iostream>

#include<string>

using namespace std;

int main()

{

string s0("");

s0.push_back('a');//s0尾插入a

string s1("b");

s0.insert(1, s1);//在下标为1的位置插入s1的拷贝

s0.insert(4, "c");//在下标为4的位置插入字符串o

s0.insert(0, "hello",2);//在下标为0的位置插入"hello"的前2个字符

return 0;

}

拼接:

string& operator+=(const char* str); 重载+=操作符
string& operator+=(const char c); 重载+=操作符
string& operator+=(const string& str); 重载+=操作符
string& append(const char *s); 把字符串s连接到当前字符串结尾
string& append(const char *s, int n); 把字符串s的前n个字符连接到当前字符串结尾
string& append(const string &s); 同operator+"(const string& str)
string& append(const string &s,int pos,int n);

字符用s中从pos开始的n个字符连接到字符串结尾

删除:

string& erase(int pos, int n = npos); 删除从pos开始的第n个字符

<code>str.erase(1,3); //从1号位置开始删除3个字符

4)查找和替换

int find(const string& str, int pos = 0) const; 查找str最后一次位置,从pos开始查找
int find(const char*s, int pos =0)const; 查线s第一次出现位置,从pos开始查找
int find(const char* s, int pos, int n) const; 从pos位置查找s的前n个字符第一次位置
int find(const char c, int pos=0) const; 查找字符c第一次出现位置
int rfind(const string& str, int pos = npos) const; 查找str最后一次位置,从pos开始查找
int rfind(const char* s, int pos = npos) const; 查找s最后一次出现位置.从pos开始查找
int rfind(const char* s, int pos, int n) const; 从pos查找s的前n个字符最后一次位置
int rfind(const char c, int pos = 0) const; 查找李符c最后一次出现位置
string& replace(int pos, int n, const string& str); 替换从pos开始n个字符为字符串str
string& replace(int pos, int n, const char* s); 替换从pos开始的n个字符为字符串s

注意:

find是从左往右查找,rfind是从右往左查找

find找到字符串后返回查找的第一个字符位置,找不到就返回-1

replace在替换时,要指定从哪个位置起,替换多少个字符,替换成什么

5)字符串的比较

int compare(const string &s) const; 与字符串s比较
int compare(const char *s) const: 与字符串s比较

注意:若=则返回0,>返回1,<返回-1

<code>int main(){

string s1="hello";code>

string s2="hhllo";code>

int ret = s1.compare(s2);

……

return 0;

}

6)字符串存取

char& operator[](int n); 通过[]方式取字符
char& at(int n); 通过at方式取字符

<code>int main(){

string str = "hello world"

for (int i = 0;i < str.size();i++){

cout << str[i] << " ";

cout << str.at(i) << " ";

}

cout<<endl;

}

//字符修改:

str[0] = "x";

str.at(1) = "x";

return 0;

}

7)子串

string substr(int pos=0,int n = npos) const; 返回由pos开始的n个字符组成的字符串

<code>void teste1(){

string str ="abcdefg";

string substr = str.substr(1,3)

cout<<"substr ="<< substr << endl;

string email="hello@sina.com";code>

int pos = email.find("@");

string username =email.substr(0, pos);

cout<<"username:"<<username<< endl

}

int main(){

teste1();

system("pause");

return0;

}

6、Set

基本概念:以有序的方式存储一组唯一的元素。具体来说,std::set使用红黑树(Red-Black Tree)实现,这使得元素在插入时就会按照特定的顺序进行排序,并且保证了查找、插入和删除操作的高效性能。

注意:set不允许容器出现重复元素,multiset允许容器出现重复元素

头文件:#include<set>

遍历:

#include <set>

void printSet(set<int> &s){

for(set<int>::iterator it=s.begin();it!=s.end;it++){

cout<<*it<<" ";

}

cout<<endl;

}

1)构造和赋值

set<T> st; 默认构造函数
set(sonst set &st); 拷贝构造函数
set& operator=(const set &st); 重载等号操作符

<code>set<int> s1;

s1.insert(10);

s1.insert(10);

set<int>s2(s1); //拷贝构造

set<int> s3;

s3=s2; //赋值

2)大小和交换

size();

返回容器中元素数目
empty(); 判断容器是否为空
swap(st); 交换两个集合容器

<code>set<int> s1;

s1.insert(10);

s1.insert(20);

s1.insert(30);

set<int> s2;

s1.insert(40);

s1.insert(50);

s1.insert(60);

s1.swap(s2);

3)插入和删除

insert(elem); 在容器中插入元素
clear(); 清除所有元素
erase(pos); 删除pos迭代器所指的元素,返回下一个元素的选代器
erase(beg,end); 删除区间[beg,end)的所有元素,返回下一个元素的迭代器
erase(elem); 删除容器中值为elem的元素。

<code>set<int> s1;

s1.insert(10);

s1.insert(20);

s1.insert(30);

s1.erase(s1.begin()); //删除

s1.erase(10);

s1.clear(); //清空

4)查找和统计

find(key); 查找是否存在key,若存在返回该键的元素的迭代器,若不存在,返回set.end()
count(key); 统计key的元素的个数

7、Queue

先进先出的数据结果,有两个出口,只有队头和队尾能被外界访问,因此不存在遍历的行为

1)构造函数

queue<T> que; queue对象默认构造形式
queue(const queue &que); 拷贝构造函数

2)赋值

queue& operator=(const queue &que); 重载等号操作符

3)数据存取

push(elem); 往队尾添加元素
pop(); 从队头移除一个元素
back(); 返回最后一个元素
front(); 返回第一个元素

4)大小

empty(); 判断堆栈是否为空
size(); 返回栈的大小

三、字符串

1、简介

C语言风格:

<code>char a[5] = {'1','2','3','4','5'}; //字符数组

char b[5] = {'1','2','3','4','\0'}; //字符串

char greeting['h','e','l','l','o','\0'}; //字符串

char greeting[]="hello";

//输出结果为 hello

C++引入的string类类型(函数及其目的)

Strcpy(s1,s2)

复制字符串s2到字符串s1

Strcat(s1,s2)

连接字符串s2到s1的末尾

Strlen(s1) 返回字符串s1的长度
Strcmp(s1,s2)

若s1=s2,返回0

若s1<s2,返回值小于0

若s1>s2,返回值大于0

Strchr(s1,s2) 返回一个指针,指向s1中字符ch第一次出现的位置
Strstr(s1,s2) 返回一个指针,指向s1中s2第一次出现的位置

2、字符串的读入

1)对字符数组得输入方法

1.1cin使用空白字符作为一次输入的结尾,并忽略该空字

<code>char word[10];

cin >> word;

cout<<word;

//若输入123 456,只会输出123

该情况下只能输入一个单词,若输入了多个单词,只会取第一个单词,其余单词被忽略掉

1.2使用getline()/get()函数完成面向行的输入

区别:主要区别在于它们处理输入流的方式:getline() 用于读取整行并丢弃定界符,而 get() 则用于逐字符读取,并保留定界符在输入流中。

#cin.getline()

cin.getline(line,nums,(optional)delim)

nums:代表从该队列中获取nums-1个字符到line中(最后一个字符为\0)若超出nums-1,后面的都无法取到。

delim:指定分界符,表示遇到分界符后当前字符串的输入将停止,其后的会保留在输入队列中作为下一个字符串的开始。

int main(){

char line1[10];

char line2[10];

cin.getline(line1,10,'s');

cin.getline(line2,10);

cout<<line1<<endl;

cout<<line2<<endl;

return 0;

}

//测试:123s456

//结果:

line1:123

line2:456

#cin.get()

cin.get(line,nums,(optional)delim)

get会在输入队列中保留最后的换行符,若不做处理可能出现问题,以下方式可以避免:

cin.get(line2,10).get();

cin.get(line2,10);

get();

1.3数字与字符串混合输入

int a,b;

char s[7];

cin>>a;

(cin>>b).get();

cin.getline(s,7);

cout<<a<<" "<<b<<" "<<s;

//测试:123 456 hello

结果:

123

456

hello

123 456 hello

2)对string对象的输入方法

string a

getline(cin,a);

cout<<a<<endl;

3、常见操作

1)常用函数

2)读写string

<code>string s1,s2,s3;

cin>>s1;

cin>>s2>>s3;

//结果:

nice to meet

nice

to

meet

若要保留输入时的空格,可以使用getline

string s1;

getline(cin,s1);

//结果:

nice to meet

nice to meet

3)cctype头文件

4)用for循环完成cctype各项

<code>#include<iostream>

#include<string>

#include<cctype>

using namespace std;

int main(void){

string s1 = "hello world";

for(auto &c : s1)

c=toupper(c);

cout<<s1<<endl;

return 0;

}

//结果

HELLO WORLD

四、排序

1、冒泡排序

原理:比较前后两个数字的大小,大的放在后面,依次遍历所有数字

#include <iostream>

#define N 1010

using namespace std;

int n = 6; //待排序的元素个数为6

int a[N] = {0,2,3,2,11,7,6}; //待排序元素

int main(){

for(int i = 1;i<n;i++){ //连续交换过程

//一共n-1个阶段,在第i个阶段,未排序序列长度从n-i+1到n-i

for (int j = 1;j<=n-i;++j) //将序列从1到n-i+1的最大值移到n-i+1的位置

if (a[j] > a[j+1]) // 将序列从1到n-i+1的最大值,移到n-i+1的位置

swap(a[j],a[j+1]); // 其中j枚举的是前后交换元素的前一个元素序号

}

//输出

for (int i=1;i<=n;++i)

cout<<a[i]<<' ';

cout<<endl;

return 0;

}

2、选择排序

原理:

遍历数组,找到最小(或最大)的元素。将找到的最小(或最大)元素与数组的第一个元素交换位置。排除第一个元素,对剩余的元素进行相同的操作,即在剩余的未排序部分中找到最小(或最大)的元素,并与该部分的第一个元素交换位置。重复以上步骤,直到整个数组排序完成。

缺点:平均时间复杂度为O(n^2),空间复杂度为O(1),性能通常比较差。

#include <iostream>

#include <vector>

using namespace std;

// 选择排序函数

void selectionSort(vector<int>& arr) {

int n = arr.size();

for (int i = 0; i < n - 1; ++i) { // 外层循环遍历数组

int minIndex = i; // 假设当前元素为最小值的索引

// 内层循环寻找最小值的索引

for (int j = i + 1; j < n; ++j) {

if (arr[j] < arr[minIndex]) { // 如果找到更小的元素,则更新最小值的索引

minIndex = j;

}

}

swap(arr[i], arr[minIndex]); // 将最小值与当前位置的元素交换位置

}

}

int main() {

// 测试选择排序函数

vector<int> arr = {64, 25, 12, 22, 11};

cout << "Original array: ";

for (int num : arr) {

cout << num << " ";

}

cout << endl;

selectionSort(arr); // 调用选择排序函数

cout << "Sorted array: ";

for (int num : arr) {

cout << num << " ";

}

cout << endl;

return 0;

}

3、插入排序

原理:

将数组视为两部分,一部分是已排序的部分,一部分是未排序的部分。从未排序部分取出第一个元素,在已排序部分中从后往前逐个比较,找到合适的位置插入该元素,使得插入后的部分仍然保持有序。重复上述过程,直到未排序部分为空,整个数组就排好序了。

优点:适合小型数据集或部分有序的数据。

#include<iostream>

using namespace std;

int main() {

int a[6] = { 2, 6, 5, 3, 4, 1}; // 待排序序列

int temp, i, j;

int n = 6; // 待排序元素个数

// 开始插入排序

for (i = 1; i < 6; i++) {

// 假定第一个数是有序的,从第二个数开始枚举

temp = a[i]; // 临时储存每一次需要排序的数

j = i; // j用于记录当前待排序元素的位置

// 在有序部分从后往前比较,将比当前元素大的元素往后移动

while (j >= 1 && temp < a[j - 1]) {

a[j] = a[j - 1]; // 元素往后移动

j--; // 继续向前搜索

}

a[j] = temp; // 将待排序元素插入到合适的位置

}

// 输出排序后的结果

for (i = 0; i < 6; i++) {

cout << a[i] << " ";

}

cout << endl;

return 0;

}



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。