数组string

news2024/11/17 17:34:01

数组

目录:

  • 数组
    • 一维数组
      • 一维数组的定义和初始化
      • 一维数组数据元素的访问
      • 练习1 找小猪
      • 练习2 算平均值
      • 比较两个数组是否相等
      • 一维数组冒泡法排序
    • 一维数组操作
      • 一维数组查找元素
        • **普通查找**:
        • 二分查找:
          • 二分查找 最小下标
          • 最大下标
        • 查找元素个数
      • 一维数组修改元素
        • 通过下标直接修改
        • 先查找,再修改
      • 一维数组添加元素
      • 一维数组删除元素
      • 一维数组的合并
        • 无需合并
        • 有序合并
        • 练习
    • 字符数组
      • 字符数组的操作
      • 字符串到数值类型的转换
      • 字符检查
      • 练习
  • 字符串string
    • c++中的string类
    • string类几种常见的构造函数
      • 构造函数
    • string的常用操作
      • 获取string对象的长度
      • 复制string对象
      • string 对象的拼接和附加
        • 使用 + 操作符拼接两个字符
        • 使用 += 操作符在字符串后面附加内容
        • 使用 string.append() 函数
        • 使用 string.push_back() 函数
      • string对象的比较
      • 使用string.substr()函数来获取子串
      • 访问 string字符串的元素
      • string 对象的查找操作
        • 使用string.find()方法查找字符
        • string.rfind()
        • string.find_first_of()
        • string.find_last_of()
        • string.find_first_not_of()
        • string.find_last_not_of()
      • string对象的插入操作
      • string对象的删除操作
      • 判断字符串是否为空
      • 使用 swap 函数交换两个字符
      • 字符串替换
      • 字符串反转
      • 练习
  • 综合案例 自动点餐系统

一维数组

一维数组的定义和初始化

定义数组

  • 数据类型 数组名[数组长度]

int arr_num[5]

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

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

数组名

  1. 只能由字母、数字和下划线组合,但数字不能开头
  2. 系统关键字不能作为数组名
  3. 同一作用域下不能重名
  4. 见其名知其意

数组初始化

int ar2[5] = {10,20};

int ar3[5] = {};

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

编译器根据元素个数计算出长度

数组长度

  1. 整形常量
  2. 整形常变量
    • #define #define N 100
    • const const int N = 100; int N=100;

一维数组数据元素的访问

访问数组的元素,使用中括号,即 [] 加上数组索引即可。 但是需要注意的是,C++ 数组的索引是从 0 开始的

语法 : 数组名[索引];

循环遍历

int arr[5] = {1,2,3,4,5};
for(int i: arr){
cout << i << “ “;
}

循环赋值

int arr[5] = {1,2,3,4,5};
for(int i=0; i<5; i++){
cin >> arr[i] ;
}

练习1 找小猪

现有五只小猪,体重分别为764,942,613,476,940。定义一个一维数组,存放五只小猪的体重,找出其中最重的小猪,并打印输出

const int N = 5;
int arr[N];
for (int i = 0; i < N; i++)
{
cin >> arr[i];
}
int max_weight = arr[0];
for (int i = 0; i < N; i++)
{
if (arr[i] > max_weight) {
max_weight = arr[i];
}
}
cout << max_weight << endl

练习2 算平均值

输入n(n<=100)个数保存到数组中,求n个数的和以及平均值

int arr[100], n;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
int sum = 0;
for (int i = 0; i < n; i++)
{
sum += arr[i];
}
cout << sum << endl <<

比较两个数组是否相等

不能直接使用==运算符与两个数组名称来确定数组是否相等

int arr1[5] = { 11, 13, 50, 72, 91 };
int arr2[5] = { 11, 13, 50, 72, 91 };
int arr1Count = sizeof(arr1) / sizeof(arr1[0]);
int arr2Count = sizeof(arr2) / sizeof(arr2[0]); 
if (arr1Count != arr2Count)
{ 
	cout << "arr1 != arr2" << endl;
	return 0; 
}
else if(arr1Count==arr2Count)
{
        for (int i = 0; i < arr1Count; i++) 
    { 
        if (arr1[i] != arr2[i]) 
        { 
            cout << "arr1 != arr2" << endl;
            return 0;
        } 
    }
}
else
{
	cout << "arr1== arr2" << endl;    
}

一维数组冒泡法排序

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。

  2. 对每一对相邻元素做同样的工作,执行完毕后,找到第一个最大值。

  3. 重复以上的步骤,每次比较次数-1,直到不需要比较。

int arr[N]={8,7,6,5,3};
// 趟数
for(int i=0;i<N-1;i++)
{
	//比较次数
	for(int j=0;j<N-i-1;j++)
	{
		if(arr[j]>arr[j+1])
		{
			swap(arr[j],arr[j+1]);
		}
	}
}
for(int i=0;i<N;i++)
{
	cout<<arr[i]<<" ";
}

优化版 : 增加标记变量

int arr[N]={8,7,6,5,3};
bool flag = ture;
// 趟数
for(int i=0;i<N-1;i++)
{
    //比较次数
    flag=ture;
 	for (int j = 0; j < N - i - 1; j++) 
    {
		if (arr[j] > arr[j + 1])
        {
			swap(arr[j], arr[j + 1]);
			flag = false;
        }
	}
    if(falg)break;
}

一维数组操作

一维数组查找元素

普通查找

根据值顺序查找

比如在给定数组中查找固定的某个值,就可以从下标为0的元素开始顺序对比查找

案例:

在长度为N(N<=100)的数组中,输入m个元素,查找k元素第一次 出现的位置(位置从1开始),如果找不到k,输出-1

输入案例:

5

1 3 5 6 3

3

输出案例:

2

const int N = 100;//数组长度
int arr[N],m,k,index = -1;
cin >> m;
for(int i=0; i<m; i++){
	cin >> arr[i];
}
cin >> k;
for(int i=0; i<m;i++){ //顺序查找
	if(k == arr[i]){
	index = i + 1;
	break;
	}
}
cout << index << endl

二分查找:

​ 二分查找也称折半查找(Binary Search),是一种效率较高的查找方 法。

注意点:

  1. 用于查找的内容逻辑上来说是需要有序的
  2. 查找的数量只能是一个,而不是多个
  3. image-20221222153854865
int const N = 100; //数组长度
int arr[N]; //声明数组
int m, k; //m元素个数,k查找的元素
cin >> m;
for (int i = 0; i < m; i++) {
	cin >> arr[i];
}
	cin >> k;
//left起始下标,right最大下标,mid保存中间下标
int left = 0, right = m - 1, mid = 0;
while (left <= right) { //当left小于等于right时查找
    mid = (left + right) / 2; //计算中间值mid
    if (k == arr[mid]) //查找到k
    {
        cout << mid + 1 << endl;
        break;
    }
    else if (k < arr[mid]) { //小于的情况,right挪到mid-1
        right = mid - 1;
    }
    else if (k > arr[mid]) { //大于的情况,left挪到mid+1
        left = mid + 1;
        }
}
if (left > right) //当left <right ,k元素不在数组中
{
	cout << -1 << endl;
}

如果需要查找的元素不止一个,怎么办?

二分查找 最小下标

在数组长度为N(N<=100)的数组中,输入m个元素(有序),查找 k元素的最小位置(位置从1开始),如果找不到k,输出-1.

案例输入:

10

11 22 22 22 22 22 22 33 44 55

22

案例输出:

2

if (k == arr[mid]) //查找到k
{
	int index = mid;
	//使用while往左查找最小下标
	while (index >= 0 && arr[index] == k) {
		index--;
		}
	cout << index + 1 << endl;
	break;
}

最大下标
if (k == arr[mid]) //查找到k
{
    int index = mid;
    //使用while往右查找最大下标
    while (index <= m -1 && arr[index] == k) {
        index++;
        }
    cout << index + 1 << endl;
    break;
}

查找元素个数

在一个有序数组中,相同元素一定是挨着的,所以,只要找到这个元素,在左右寻找,记录个数即可

mid = (left + right) / 2; //计算中间值mid
if (k == arr[mid]) //查找到k
{
    int index1 = mid-1,index2 = mid+1;
    count = 1;
while (index1 >= 0 && arr[index1] == k) {//扫描左边
    index1--;
    count++;
}
while (index2 <= m-1 && arr[index2] == k){//扫描右边
    index2++;
    count++;
    }break;

一维数组修改元素

通过下标直接修改

找到对应下标修改

先查找,再修改

根据要求找到对应下标,在进行修改

在一次100百米跑比赛中,有n(5<= n <= 10)个同学进行比赛,输入这n个同学的比赛成绩,把第一名和最后一名的同学的位置进行交换,在输出比赛成绩。

输入用例:

5

10.3 9.8 10.6 9.9 11

输出用例:

10.3 11 10.6 9.9 9.8

double arrScore[20];
int n;
cin >> n;
for (int i = 0; i < n; i++) {
	cin >> arrScore[i];
}
double first = arrScore[0], last = arrScore[0];
int first_index = 0, last_index = 0;
for (int i = 0; i < n; i++) {
    if (arrScore[i] < first) {
        first = arrScore[i];
        first_index = i;
    }
    if (arrScore[i] > last) {
        last = arrScore[i];
        last_index = i;
    }
}
swap(arrScore[first_index], arrScore[last_index]);
for (int i = 0; i < n; i++) {
	cout << arrScore[i] << " ";
}

一维数组添加元素

image-20221222205505162

int arr[100];
int n, k, p, m;
cin >> n;
for (int i = 0; i < n; i++)
{
	cin >> arr[i];
}
cin >> k;
cin >> p >> m;
int index = n - 1;
if (p) {
    while (index >= m - 1)
    {
        arr[index + 1] = arr[index];
        index--;
    }
    arr[m-1] = k;
}
else {
    while (index > m -1)
    {
        arr[index + 1] = arr[index];
        index--;
    }
    arr[m] = k;
}
for (int i = 0; i < (n + 1); i++) {
	cout << arr[i] << " ";
}

一维数组删除元素

image-20221223093701845

int n;
int arr[100];
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
int index = -1;
for (int i = 0; i < n; i++)
{
if (arr[i] < 0) {
index = i;
break;
}
}
while (index < n -1)
{
arr[index] = arr[index + 1];
index++;
}
for (int i = 0; i < n -1; i++)
{
cout << arr[i] << " ";
}

一维数组的合并

无需合并

给定两个数组arr1和arr2,数组长度不超过100,合并成arr3.

image-20221224103802298

int n1,n2, arr1[100], arr2[100], arr3[200];
cin >> n1;
for (int i = 0; i < n1; i++) {
	cin >> arr1[i];
}
cin >> n2;
for (int i = 0; i < n2; i++) {
	cin >> arr2[i];
}
for (int i = 0; i < n1; i++) {
	arr3[i] = arr1[i];
}
int index = 0;
for (int i = n1; i < n1 + n2; i++) {
	arr3[i] = arr2[index ++];
}
for (int i = 0; i < n1 + n2; i++) {
	cout << arr3[i] << " ";
}

有序合并

一般合并之后的数组是有序的

image-20221225155428767

int n1, n2, arr1[100], arr2[100], arr3[200];
cin >> n1; 
for (int i = 0; i < n1; i++)
{ 
	cin >> arr1[i]; 
}
cin >> n2; 
for (int i = 0; i < n2; i++) 
{ 
	cin >> arr2[i];
}
int index = 0,i=0,j=0;
for (; i < n1 && j < n2;) 
{
	if (arr1[i] < arr2[j]) 
	{
    	arr3[index++] = arr1[i++]; 
    }
    else if (arr1[i] > arr2[j]) 
    { 
    	arr3[index++] = arr2[j++];
    }
    else 
    { 
    arr3[index++] = arr2[j++];
  	  	i++; 
    }
}
while (i < n1) 
{ 
	arr3[index++] = arr1[i++]; 
}
while (j < n2) 
{ 
	arr3[index++] = arr2[j++];
}
for (int i = 0; i < index; i++) 
{
	cout << arr3[i] << " "; 
}

练习

定义一个int型的一维数组,包含10个元素,分别赋值为1~10, .然后 将数组中的元素都向前移一个位置, 即a[0]=a[1],a[1]=a[2]…最后一 个元素的值是原来第一个元素的值,然后输出这个数组。

int arr[10];
for (int i = 0; i < 10; i++)
{
	cin >> arr[i];
}
int temp = arr[0];
for (int i = 0; i < 9; i++)
{
	arr[i] = arr[i + 1];
}
arr[9] = temp;
for (int i = 0; i < 10; i++)
{
	cout << arr[i] << " ";
}

字符数组

C++ 中的字符数组,是用来存放一连串 字符 的 数组,C++ 的字符数组使用与其他数组基本相同,但初始化时,可以直接使用字符串进行初始化。其实就是C语言风格的字符串

字符和字符串的区别

char 是字符,也是 0~127 的无符号整数。通常能用一个 char 表示 的被称为 ASCII 编码。

字符串是以 NULL 结尾的连续地址。日常生活中常用转义字符 ‘\0’ 表示

字符数组的地址

cout在遇到char数组时,会输出整个字符串,直到遇到‘\0’ ,所以就算是普通的char单个字符地址,我们也需要(void*)来强转他的类型

void 被翻译为"无类型";void * 为"无类型指针" 一般被称为通用指针或叫泛指针

字符数组的输入输出

字符数组输入时最好不要用cin,因为cin默认遇到空格和回车会结束

所以字符数组的输入用:

char arrc[100];

gets(arrc); 到\n截止

puts(arrc); 到‘\0’结束

字符数组的操作

添加头文件#include<csrting>

strlen(p)) 取字符串长度

strcpy(p,p1)复制字符串

strncpy(p,p1,n)复制指定长度字符串

strcat(p,p1)附加字符串

strncat(p,p1,n)附加指定长度字符串

  • strlen(字符数组名)

    返回字符数组的元素个数;终止‘\0’不算在内

  • strcpy(字符串1,字符串2)

    将字符串2复制到字符串1,返回字符串1的值。

  • strncpy(字符串1,字符串2,长度n);

    将字符串2前n个字符复制到字符串1,返回字符串1的值。

  • strcmp(字符串1,字符串2);

    以ASCII码来比较字符串1和字符串2的大小。

    字符串1 大于字符串2 返回1

    字符串1 等于字符串2 返回0

    字符串1 小于字符串2 返回-1

  • strncmp(字符串名1,字符串名2,长度n);

    对字符串1和字符串2的前n个字符进行比较

  • stricmp(字符串名1,字符串名2); windows

  • strcasecmp(字符串名1,字符串名2); macos/linu

    不区分大小写比较字符串1和字符串2的大小,比较的结果由函数返 回值带回。

  • strcat(字符串名1,字符串名2);

    将字符串2拼接到字符串1后(返回字符串1的值)

  • strncat(字符串名1,字符串名2,n);

    将字符串2前n个字符连接到字符串1后边(返回字符串1的值)

  • strchr(字符串, c) 在字符串中查找指定字符

  • strrchr(字符串, c) 在字符串中反向查找

返回一个指向该字符串中第一次出现的字符的指针,如果字符串中 不包含该字符则返回NULL空指针。

  • strlwr(字符串名) 将字符串中大写字母换成小写字母

  • strupr(字符串名) 将字符串中小写字母换成大写字母

  • memset(字符串名,初始化值,初始化字节数);

    将某一块内存中的内容全部设置为指定的值

字符串到数值类型的转换

  • atoi§ 字符串转换到 int 整型
  • atof§ 字符串转换到 double 符点数
  • atol§ 字符串转换到 long 整型

字符检查

#include

isalpha() 检查是否为字母字符

isupper() 检查是否为大写字母字符

islower() 检查是否为小写字母字符

isdigit() 检查是否为数字

isxdigit() 检查是否为十六进制数字表示的有效字符

isspace() 检查是否为空格类型字符

iscntrl() 检查是否为控制字符

ispunct() 检查是否为标点符号

isalnum() 检查是否为字母和数字

isprint() 检查是否是可打印字符

isgraph() 检查是否是图形字符,等效于 isalnum() | ispunct(

练习

统计数字字符个数

描述输入一行字符,统计出其中数字字符的个数。

输入格式:一行字符串,总长度小于255。

输出格式:输出为1行,输出字符串里面数字字符的个数。

样例输入: dream abc jlje 2022.

样例输出: 4

gets(str);
int n=strlen(str),cnt=0;
for(int i=0;i<n;i++)
{
    /**/
	if(isdigit(str[i]))
	{
		cnt++;
	}
    /**/
    if(str[i]>='0'&&str[i]<='9')
    {
        cnt++;
    }
}
cout<<cnt;

字符串string

c++中的string类

C++ 标准库提供了 string 类类型,支持上述所有的操作,另外还增加了其他更多的功能。我们将学习 C++ 标准库中的这个类,现在让 我们先来看看下面这个实例:

#include <iostream> 
#include <string> 
using namespace std; 
int main () 
{ 
    string str1 = "Hello"; 
    string str2 = "World"; 
    string str3; 
    int len ;
    
    // 复制 str1 到 str3 
    str3 = str1;
    cout << "str3 : " << str3 << endl; 

    // 连接 str1 和 str2 
    str3 = str1 + str2; 
    cout << "str1 + str2 : " << str3 << endl; 

    // 连接后,str3 的总长度 
    len = str3.size(); 
    cout << "str3.size() : " << len << endl; 
    return 0;
}

str3 : Hello

str1 + str2 : HelloWorld

str3.size() : 1

现在您可能还无法透彻地理解这个实例,因为到目前为止我们还没 有讨论类和对象。所以现在您可以只是粗略地看下这个实例,等理解了面向对象的概念之后再回头来理解这个实例。

C++ 中提供了专门的头文件 string(注意不是 string.h,这个是 C 风 格字符串相关函数的头文件),来支持 string 类型。string 类定义 隐藏了字符串的数组性质,让我们可以像处理普通变量那样处理字 符串。string 对象和字符数组之间的主要区别是:可以将 string 对 象声明为简单变量,而不是数组。

string类几种常见的构造函数

构造函数

  1. string(const char *s) :将 string 对象初始化为 s 指向的字符串

string str(“Hello!”);

  1. string(size_type n,char c) :创建一个包含 n 个元素的 string 对象,其中每个元素都被初始化为字符 c

string str(10,‘a’)

  1. string(const string &str) :将一个 string 对象初始化为 string 对象 str(复制构造函数

string str1(“hello!”);

string str2(str1);

  1. string() :创建一个默认的 string 对象,长度为 0(默认构造函数)

string str; // 创建一个空的 string 对象

string 类的设计允许程序自动处理 string 的大小,因此,上述代码创建了一个长度为 0 的string 对象,但是向 str 中写入数据时,程序会自动调整 str 的长度。因此,与使用数组相比,使用 string 对象更方便,也更安全

string的常用操作

获取string对象的长度

在 C 语言中,使用 strlen 函数获取字符串的长度。在 C++ 中,可以使用 string.size() 函数或 string.length() 函数来获得 string 对象的长度。

string str(“Hello,World!”);

  • str.length();
  • str.size();

这两个方法是完全一样的,并没有区别。length() 方法是 C 语言习惯保留的,size() 方法则是为了兼容 STL 容器而引入的。

复制string对象

在 C 语言中,使用 strcpy、strncpy 函数来实现字符串的复制。在 C++ 中则方便很多,可以直接将一个string 对象赋值给另一个 string 对象,即

string str1(“Hello,World!”);

string str2;

str2 = str1;

由于 string 类会自动调整对象的大小,因此不需要担心目标数组不够大的问题。

string 对象的拼接和附加

在 C 语言中,使用 strcat、strncat 函数来进行字符串拼接操作。在 C++ 中也有多种方法来实现字符串拼接和附加操作:

使用 + 操作符拼接两个字符

string str1("hello ");
string str2("world!");
string str3 = str1 + str2;

使用 += 操作符在字符串后面附加内容

可以使用 += 来在一个 string 对象后面附加一个 string 对象、字符以及 C 风格的字符串:

string str1("hello ");
string str2("world!\n");
str1 += str2;
str1 += "nice job\n";
str1 += 'a';

使用 string.append() 函数

可以使用 string.append() 函数来在一个 string 对象后面附加一个 string 对象或 C风格的字符串:

string str1 ="hello,world!";
string str2 ="HELLO,WORLD!";

str1.append(str2);
str1.append("C string")

使用 string.push_back() 函数

可以使用 string.push_back() 函数来在一个 string 对象后面附加一个字符串:

string str("Hello");
str.push_back(“abc”);

string对象的比较

在 C 语言中,使用 strcmp、strncmp 函数来进行字符串的比较。在 C++ 中,由于将 string 对象声明为了 简单变量,故而对字符串的比较操作十分简单了,直接使用关系运算符(==、!=、<、<=、>、>=)即可:

string str1("hello");
string str2("hello");
if (str1 == str2)
	cout << "str1 = str2" << endl;
else if (str1 < str2)
	cout << "str1 < str2" << endl;
else
	cout << "str1 > str2" <<endl;

image-20221231211553609

使用类似 strcmp 的函数来进行 string 对象的比较,string 类提供的是 string.compare() 方法,函数原型如下

int compare(const string&str) const;
int compare(size_t pos,size_t len,const string&str)const;
int compare(size_t pos,size_t len,const string&str, size_t subpos,size_t sublen)const;
int compare(const char * s)const;
int compare(size_t pos,size_t len,const char * s)const;
int compare(size_t pos,size_t len,const char * s,size_t n)const;

compare 方法的返回值如下
1)返回 0,表示相等;
2)返回结果小于 0,表示比较字符串中第一个不匹配的字符比源字符串小,或者所有字符都匹配但是比较字符串比源字符串短;
3)返回结果大于 0,表示比较字符串中第一个不匹配的字符比源字符串大,或者所有字符都匹配但是比较字符串比源字符串长。
string str1 ("aBcdef");
string str2 ("AbcdEf");
string str3 ("123456");
string str4 ("123dfg");
//下面是各种比较方法
int m=str1.compare (str2); //完整的A和B的比较
int n=str1.compare(1,5,str2); //"Bcdef"和"AbcdEf"比较
int p=str1.compare(1,5,str2,4,2); //"Bcdef"和"Ef"比较
int q=str3.compare(0,3,str4,0,3); //"123"和"123"比较

使用string.substr()函数来获取子串

可以使用 string.substr() 函数来获取子串,string.substr() 函数的定义如下:

string substr(size_t pos = 0,size_t len = npos)const;

其中,pos 是子字符串的起始位置(索引,第一个字符的索引为 0),len 是子串的长度。这个函数的功能是: 复制一个 string 对象中从 pos 处开始的 len 个字符到 string 对象 substr 中去,并返回 substr。

string str("Hello,World!");
string subStr = str.substr(3,5);//从第三个字符开始,截取5个字符
cout << subStr << endl;

这段代码的输出结果为:“lo,Wo”。

访问 string字符串的元素

可以像 C 语言中一样,将 string 对象当做一个数组,然后使用数组下标的方式来访问字符串中的元素; 也可以使用 string.at(index) 的方式来访问元素(索引号从 0 开始):

string str("Hello,World!");
cout << str[1] << endl; // 使用数组下标的方式访问 string 字符串的元素
cout << str.at(1) << endl; // 使用 at 索引访问 string

image-20221231213135937

string 对象的查找操作

使用string.find()方法查找字符

npos==-1

find方法的函数原形如下:

  1. 从字符串的pos位置开始(若不指定pos的值,则默认从索引0处开始),查找字符串str。如果找到,则返该字符串首次出现时其首字符的索引;否则,返回string::npos:

size_type find (const string& str, size_type pos

  1. 从字符串的 pos 位置开始(若不指定 pos 的值,则默认从索引 0 处开始),查找子字符串 s。如果找到,则返回 该子字符串首次出现时其首字符的索引;否则,返回 string::npos:

size_type find (const char *s, size_type pos = 0) const;

  1. 3)从字符串的 pos 位置开始(若不指定 pos 的值,则默认从索引 0 处开始),查找 s 的前 n 个字符组成的子字符串。 如果找到,则返回该子字符串首次出现时其首字符的索引;否则,返回 string::npos:

size_type find (const char *s, size_type pos, size_type n);

  1. 从字符串的 pos 位置开始(若不指定 pos 的值,则默认从索引 0 处开始),查找字符 ch 。如果找到,则返回该 字符首次出现的位置;否则,返回 string::npos:

size_type find (char ch, size_type pos = 0) const;

string.rfind()

string.rfind() 与 string.find() 方法类似,只是查找顺序不一样, string.rfind() 是从指定位置 pos (默认为字符串末尾)开始向前查找,直到字符串的首部,并返回第一次查找到匹配项时匹 配项首字符的索引。换句话说,就是查找子字符串或字符最后一次出现的位置。

string.find_first_of()

string.find_first_of() 方法在字符串中从指定位置开始向后(默认为索引 0 处)查找参数中任何一个字符 首次出现的位置。

string str("catjldkjfellmlm");
int pos = str.find_first_of("gat");
if (pos == string::npos) {
    printf("没有匹配到\n");
    return 0;
}
else
	cout << "在索引 " << pos << " 处匹配到"

程序输出结果是:在索引 1 处匹配到。所查找的字符串 gat 中,第一次出现在字符串 str 中的字符是 ‘a’ , 该字符在 str 中的索引是 1.

string.find_last_of()

string.find_last_of() 方法在字符串中查找参数中任何一个字符最后一次出现的位置(也就 是从指定位置开始往前查找,第一个出现的位置)。

string.find_first_not_of()

string.find_first_not_of() 方法在字符串中查找第一个不包含在参数中的字符

string.find_last_not_of()

string.find_last_not_of() 方法在字符串中查找最后一个不包含在参数中的字符(从指定位 置开始往前查找,第一个不包含在参数中的字符)。

string对象的插入操作

使用string.insert()进行插入操作,函数原型如下:

string&insert(size_t pos,const string&str); // 在位置 pos 处插入字符串 str
string&insert(size_t pos,const string&str,size_t subpos,size_t sublen); // 在位置 pos 处插入字符
串 str 的从位置 subpos 处开始的 sublen 个字符
string&insert(size_t pos,const char * s); // 在位置 pos 处插入字符串 s
string&insert(size_t pos,const char * s,size_t n); // 在位置 pos 处插入字符串 s 的前 n 个字符
string&insert(size_t pos,size_t n,char c); // 在位置 pos 处插入 n 个字符 c
iterator insert (const_iterator p, size_t n, char c); // 在 p 处插入 n 个字符 c,并返回插入后迭代器的位置
iterator insert (const_iterator p, char c); // 在 p 处插入字符 c,并返回插入后迭代器的位置
案例
string str("abcdefgh");
str.insert(1,
"test"); // 在位置 1 处插入字符串 "test"
cout << str << endl;
str.insert(10, 5,
'H'); // 在位置 10 处插入 5 个字符 'H'
cout << str << endl;

string对象的删除操作

使用 string.erase() 进行元素删除操作

函数原型如下:

string& erase (size_t pos = 0, size_t len = npos); // 删除从 pos 处开始的 n 个字符
iterator erase (const_iterator p); // 删除 p 处的一个字符,并返回删除后迭代器的位置
iterator erase (const_iterator first, const_iterator last); // 删除从 first 到 last 之间的字符,并返回删除后迭代器的位置

判断字符串是否为空

使用 empty() 函数判断字符串是否为空

string str;
if(str.empty()){
	cout << "字符串为空" << endl;
}

使用 swap 函数交换两个字符

string str1 ="abc";
string str2 ="hjkui";
str1.swap(str2);swap(str1,str2);
cout << str1 << endl;
cout << str2 << endl;

字符串替换

string &replace(int p0, int n0,const char *s);
//删除从p0开始的n0个字符,然后在p0处插入串s

string &replace(int p0, int n0,const char *s, int n);
//删除p0开始的n0个字符,然后在p0处插入字符串s的前n个字符

string &replace(int p0, int n0,const string &s);
//删除从p0开始的n0个字符,然后在p0处插入串s

string &replace(int p0, int n0,const string &s, int pos, int n);
//删除p0开始的n0个字符,然后在p0处插入串s中从pos开始的n个字符

string &replace(int p0, int n0,int n, char c);
//删除p0开始的n0个字符,然后在p0处插入n个字符c

案例
string s1 ="abcedfghijklmn";
s1.replace(1, 3,"HK");
cout << s1 << endl; //aHKdfghijklmn

string s2 ="abcedfghijklmn";
s2.replace(2, 1,"qwerty", 5);
cout << s2 << endl; //abqwertedfghijklmn

string s3 ="hjkbnm";
s3.replace(1,2,3,'a');
cout << s3 << endl; //haaabnm

字符串反转

使用algorithm 头文件里面的reverse函数

#include <iostream>
#include <algorithm>
using namespace std;
int main() {
    string s1;
    cin >> s1;
    reverse(s1.begin(), s1.end());
    cout << s1 << endl;
    return 0;
}

输入:abc

输出:cba

练习

从键字输入一个字符串(由英文字母组成),将该字符串中所有的字母改成 该字母的下一个字母,如b改成c,字母z改为a要求,大小写不变。

#include <iostream>
using namespace std;
int main() {
    string s1,s2;
    cin >> s1;
    int n=s1.length();
    for(int i=0;i<n;i++)
    {
        if(s1.at(i)=='z')
        {
            s2+='a';
        }
        else
        {
            s2+=s1.at(i)+1;
        }
    }
    cout<<s2<<endl;
    return 0;
}

给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果 不存在,则返回 -1

输入用例:abccga

输出用例:1

#include <iostream>
using namespace std;
int main() {
    string s1;
    cin>>s1;

    int n=s1.length();
    int cnt[26]={0};

    for(int i=0;i<n;i++)
    {
        cnt[s1[i]-'a']++;
    }
    for(int i=0;i<n;i++)
    {
        if(cnt[s1[i]-'a']==1)
        {
            cout<<i<<endl;
            return 0;
        }
    }

    return -1;
}

综合案例 自动点餐系统

image-20221231231701990

  1. 打印菜单
  2. 单点
  3. 套餐
  4. 结账

打印菜单

打印出来的显示界面

image-20221231231201588

单点

进入系统后,会提示用户,选择单点,套餐,还是结账

image-20230103122412799

套餐

套餐有两种,套餐A和套餐B,进入每种套餐,在点选

image-20230103122502907

结账

进入结账,如果消费超过100元,提示用户是否参与换购

image-20230103122526206


#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int main() {

	cout << "欢迎光临本店" << endl;
	cout << "请收好您的优惠券,面值20元" << endl;
	int yhq = 20;

	cout << "-------------------自助点餐系统-------------------" << endl;
	cout << "菜单:" << endl;
	cout << "1火锅 2回锅肉 3宫保鸡丁 4夫妻肺片 5毛血旺 6麻婆豆腐 7东坡肘子 8水煮牛肉" << endl;
	cout << "9龙抄手 10钟水饺 11串串香 12肥肠粉 13担担面" << endl;
	cout << "14可乐 15雪碧 16脉动 17果缤纷 18果粒橙 19营养快线" << endl;
	cout << "套餐A(优惠10):火锅 回锅肉 东坡肘子,任选其一" << endl;
	cout << "龙抄手 钟水饺 串串香,任选其一" << endl;
	cout << "可乐 雪碧,任选其一" << endl;
	cout << "套餐B(优惠12):火锅 回锅肉 东坡肘子 水煮牛肉,任选其一" << endl;
	cout << "肥肠粉 担担面,任选其一" << endl;
	cout << "脉动 果缤纷 果粒橙,任选其一" << endl;
	cout << "本店消费满100元,可加1元,换购一种饮料" << endl;

	//选择单点 套餐 结账菜单变量
	char c;
	//接收菜的编号
	int input;

	//菜名数组
	string name[19] = {"火锅","回锅肉","宫保鸡丁","夫妻肺片","毛血旺","麻婆豆腐","东坡肘子","水煮牛肉","龙抄手","钟水饺",
						"串串香","肥肠粉","担担面","可乐","雪碧","脉动","果缤纷","果粒橙","营养快线"};
	//价格数组
	int price[19] = { 30,20,15,45,21,34,22,23,31,16,18,19,11,9,13,10,9,8,6 };
	//数量数组
	int cnt[19] = { 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0 };
	int cnt2[19] = { 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0 };
	//总价格  总优惠
	int total = 0, fp = 0;

	while (true)
	{
		cout << "A单点  B套餐  C结账" << endl;
		cin >> c;
		if (c == 'A')
		{
			//单点
			cout << "输入编号点餐,输入0结束点餐" << endl;
			while (true)
			{
				cin >> input;
				if (input == 0) {
					break;
				}
				switch (input) {
				case 1:
					cnt[0]++;
					break;
				case 2:
					cnt[1]++;
					break;
				case 3:
					cnt[2]++;
					break;
				case 4:
					cnt[3]++;
					break;
				case 5:
					cnt[4]++;
					break;
				case 6:
					cnt[5]++;
					break;
				case 7:
					cnt[6]++;
					break;
				case 8:
					cnt[7]++;
					break;
				case 9:
					cnt[8]++;
					break;
				case 10:
					cnt[9]++;
					break;
				case 11:
					cnt[10]++;
					break;
				case 12:
					cnt[11]++;
					break;
				case 13:
					cnt[12]++;
					break;
				case 14:
					cnt[13]++;
					break;
				case 15:
					cnt[14]++;
					break;
				case 16:
					cnt[15]++;
					break;
				case 17:
					cnt[16]++;
					break;
				case 18:
					cnt[17]++;
					break;
				case 19:
					cnt[18]++;
					break;
				}
			}

			//每种菜名字,数量和小计
			total = 0;
			for (int i = 0; i < 19; i++)
			{
				if (cnt[i] != 0) {
					cout << name[i] << price[i] << "元,数量:" << cnt[i] << " 小计:" << price[i] * cnt[i] << "元" << endl;
					total += price[i] * cnt[i];
				}
			}
			cout << "单点总计:" << total << "元,优惠:" << fp << "元" << endl;
		}
		else if (c == 'B') {
			//套餐
			while(1){
				cout << "套餐A    套餐B  (输入字母确定)" << endl;
				cin >> c;
				if (c == 'A') {
					//套餐A
					fp += 10;
					cout << "1火锅 2回锅肉 7东坡肘子" << endl;
					cin >> input;
					switch (input) {
					case 1:
						cnt2[0] ++;
						break;
					case 2:
						cnt2[1] ++;
						break;
					case 7:
						cnt2[6] ++;
						break;
					}

					cout << "9龙抄手 10钟水饺 11串串香" << endl;
					cin >> input;
					switch (input) {
					case 9:
						cnt2[8] ++;
						break;
					case 10:
						cnt2[9] ++;
						break;
					case 11:
						cnt2[10] ++;
						break;
					}
					cout << "14可乐 15雪碧" << endl;
					cin >> input;
					switch (input) {
					case 14:
						cnt2[13] ++;
						break;
					case 15:
						cnt2[14] ++;
						break;
					}

					break;
				}
				else if (c == 'B') {
					//套餐B
					fp += 12;
					cout << "1火锅 2回锅肉 7东坡肘子 8水煮牛肉" << endl;
					cin >> input;
					switch (input) {
					case 1:
						cnt2[0] ++;
						break;
					case 2:
						cnt2[1] ++;
						break;
					case 7:
						cnt2[6] ++;
						break;
					case 8:
						cnt2[7]++;
					}

					cout << "12肥肠粉 13担担面" << endl;
					cin >> input;
					switch (input) {
					case 12:
						cnt2[11] ++;
						break;
					case 13:
						cnt2[12] ++;
						break;
					
					}
					cout << "16脉动 17果缤纷 18果粒橙" << endl;
					cin >> input;
					switch (input) {
					case 16:
						cnt2[15] ++;
						break;
					case 17:
						cnt2[16] ++;
						break;
					case 18:
						cnt2[17]++;
						break;
					}

					break;
				}
				else {
					cout << "请输入正确的大写字母进行套餐选择!!" << endl;
				}
			}
			total = 0;  //数量累加的,所以total需要清零
			for (int i = 0; i < 19; i++) {
				if (cnt2[i] != 0) {
					total += price[i] * cnt2[i];
					cout << name[i] << price[i] << "元,数量:" << cnt2[i] << " 小计:" << price[i] * cnt2[i] << "元" << endl;
				}
			}
			total -= fp;
			cout << "套餐总计:" << total << "元,优惠:" << fp << "元" << endl;
		}
		else if (c == 'C') {
			//结账

			total = 0;
			cout  << "单点消费:" << endl;
			for (int i = 0; i < 19; i++) {
				if (cnt[i] != 0) {
					cout << name[i] << price[i] << "元,数量:" << cnt[i] << " 小计:" << price[i] * cnt[i] << "元" << endl;
					total += price[i] * cnt[i];
				}
			}

			cout << "套餐消费:" << endl;
			for (int i = 0; i < 19; i++) {
				if (cnt2[i] != 0) {
					cout << name[i] << price[i] << "元,数量:" << cnt2[i] << " 小计:" << price[i] * cnt2[i] << "元" << endl;
					total += price[i] * cnt2[i];
				}
			}
			total -= fp;
			cout << "总费用:" << total << "元,优惠" << fp << "元" << endl;

			if (total >= 100)
			{
				cout << "总消费超过了100元,请问是否加1元换购饮料(Y/N)" << endl;
				cin >> c;
				if (c == 'Y') {
					total += 1;
					cout << "14可乐 15雪碧 16脉动 17果缤纷 18果粒橙" << endl;
					cin >> input;
					switch (input)
					{
					case 14:
						fp += price[13] - 1;
						break;
					case 15:
						fp += price[14] - 1;
						break;
					case 16:
						fp += price[15] - 1;
						break;
					case 17:
						fp += price[16] - 1;
						break;
					case 18:
						fp += price[17] - 1;
						break;
					
					}
				}
			}

			cout << "您总共消费:" << total << "元,优惠了" << fp << "元" << endl;
			cout << "是否使用优惠券(Y/N)" << endl;
			cin >> c;
			if (c == 'Y') {
				total -= yhq;
				fp += yhq;
			}


			cout << "您支付了:" << total << "元,优惠了" << fp << "元" << endl;
			break;

		}
		else {
			cout << "请输入正确的大写字母!!" << endl;
		}

	}
	cout << "-----------------------欢迎下次光临!-------------------------" << endl;

	return 0;
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/136343.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何优化 MySQL

为什么要对 SQL 进行优化 有时候数据库会出现性能低、执行时间太长、等待时间太长、SQL 语句欠佳&#xff08;连接查询&#xff09;、索引失效等问题&#xff0c;这些问题会严重拖慢一个系统的速度&#xff0c;因此需要对 SQL 进行优化。 SQL 的编写过程和解析过程并非是一致…

Qt样式表语法

样式规则每个样式规则由选择器和声明组成。选择器&#xff1a;指定受该规则影响的部件。声明&#xff1a;指定这个部件上要设置的熟悉如&#xff1a;QPushButton{color:red} QPushButton是选择器&#xff1b;{color:red}是声明&#xff1b;color是属性&#xff1b;red是值。选择…

使用prometheus监控ES

下载elasticsearch_exporter wget 下载二进制包并解压、运行&#xff1a; wget https://github.com/prometheus-community/elasticsearch_exporter/releases/download/v1.3.0/elasticsearch_exporter-1.3.0.linux-amd64.tar.gz tar -xvf elasticsearch_exporter-1.3.0.linux-a…

ARM6818开发板画任意矩形,圆形,三角形,五角星,6818开发板画太极,画五星红旗(含码源与思路)

本文利用6818开发板完成LCD屏上绘制任意的矩形&#xff0c;圆形&#xff0c;三角形或五角星形图案&#xff0c;还有绘制太极&#xff0c;五星红旗的方案。 目录 映射 绘制矩形 代码思路 代码实现 实践出真知 绘制圆形 代码思路 代码实现 绘制三角形 代码思路 代码实现…

【回答问题】ChatGPT上线了!用给写出可执行的实体链接模型

如何实现一个实体链接模型/代码 在实现实体链接模型之前&#xff0c;您需要确定所要链接的实体类型&#xff08;例如人名、地名、组织机构等&#xff09;。然后&#xff0c;您需要准备一份包含大量实体及其相应识别码的实体百科数据集。接着&#xff0c;您可以使用深度学习模型…

乾元通多卡聚合通信系统在应急通信领域的解决方案

后疫情时代&#xff0c;日益增多的大型集会类事件给现有通信系统带来极大的压力。目前&#xff0c;我国已经认识到应急通信系统的重要性&#xff0c;因此我国各个部门已经配置了不少应急通信系统和设备&#xff0c;并且积累了相当的使用经验。 在不同情况下&#xff0c;对应急…

基础数据结构——数组

目录 一、前言 二、一维数组 1、定义和初始化 2、一维变长数组 3、一维正向遍历 4、一维反向遍历 5、一维数组区间操作、一维数组从 a[1] 开始&#xff0c;读入一维数组 6、一维数组例题1 7、一维数组例题2 三、二维数组 1、二维数组初始化 2、三维数组初始化 3…

HTTP_day02

掘金地址 结合 小林 coding 当键入网址后&#xff0c;到网页显示&#xff0c;其间发生了什么 DNS 服务器 专门保存了 Web 服务器域名与 IP 的对应关系 域名用“.”分隔成多个单词&#xff0c;级别从左到右逐级升高&#xff0c;最右边的被称为“顶级域名” DNS 服务器是一个分…

聊聊Spring中最常用的11个扩展点

前言 我们一说到spring&#xff0c;可能第一个想到的是 IOC&#xff08;控制反转&#xff09; 和 AOP&#xff08;面向切面编程&#xff09;。 没错&#xff0c;它们是spring的基石&#xff0c;得益于它们的优秀设计&#xff0c;使得spring能够从众多优秀框架中脱颖而出。 除…

第三十六讲:神州无线AP胖AP模式配置与管理

胖AP(Fat AP)配置一个开放式WLAN非常方便&#xff0c;需要完成的操作包括有线和无线两部分的配置。有线部分即ethernet接口的配置&#xff0c;保证AP能够接入Internet,无线部分的配置包括关联WLAN与VLAN&#xff0c;广播SSID,启用VAP&#xff0c;若无其他DHCP服务器的话&#x…

业务状态实时监控预警,「告警配置」来帮您

腾讯云数据连接器iPaaS团队服务了各行各业的数百家客户后&#xff0c;发现许多企业有大量的自建应用/SaaS应用&#xff0c;却缺乏一套可靠灵活的告警系统。当相关的IT系统/资源调配出现故障后&#xff0c;往往是影响到业务系统被用户投诉后&#xff0c;技术人员才发现故障并展开…

【超详细】LightGBM介绍与应用

目录 1. LightGBM简介 2. LightGBM详细介绍 2.1 单边梯度抽样算法 2.2 直方图算法 2.3 互斥特征捆绑算法 2.4 基于最大深度的 Leaf-wise 的垂直生长算法&#xff08;带深度限制的 Leaf-wise 算法&#xff09; 2.5 类别特征最优分割 &#xff08;直接支持类别特征&#xf…

【自学Python】Windows安装Python

Windows安装Python Python下载 Python下载地址 https://www.python.org/Python下载 打开上面的链接&#xff0c;打开 Python 的下载页面&#xff0c;如下图所示&#xff1a; 我们把鼠标放到 Downloads 上&#xff0c;然后点击 Windows&#xff0c;此时界面如下图所示&#…

Docker简介

Docker官网链接&#xff1a; http://docker.p2hp.com/问题&#xff1a;我们开发的嵌入式项目基本是基于虚拟机下的ubuntu的&#xff0c;如果每一个项目要求的系统版本、库版本、交叉编译工具链等不一样&#xff0c;我们就需要为每一个项目安装一个对应的ubuntu&#xff0c;这既…

【Leetcode】111. 二叉树的最小深度

一、题目 1、题目描述 给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明&#xff1a;叶子节点是指没有子节点的节点。 示例1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;2…

4.0、Linux-文件属性查看和修改学习

4.0、Linux-文件属性查看和修改学习 基本属性 Linux 系统是一种典型的多用户系统&#xff0c;不同的用户处于不同的地位&#xff0c;拥有不同的权限&#xff1b;为了保护系统的安全性&#xff0c;Linux 系统对不同的用户访问同一文件&#xff08;包括目录文件&#xff09;的权限…

Linux0基础入门,教你如何在Shell中使用正则表达式

正则表达式 在 shell 脚本中成功运用 sed 编辑器和 gawk 程序的关键在于熟练使用正则表达式。这可不是件简单的事&#xff0c;从大量数据中过滤出特定数据可能会&#xff08;而且经常会&#xff09;很复杂。本章将介绍如何在 sed 编辑器和 gawk 程序中创建正则表达式来过滤出需…

聚观早报 | 元旦机票预订量增长145%;小米集团副总裁崔宝秋离职

今日要闻&#xff1a;元旦跨境机票预订量增长145%&#xff1b;小米集团副总裁崔宝秋离职&#xff1b;抖音推出桌面端聊天软件&#xff1b;《阿凡达2》全球票房破14亿美元&#xff1b;苹果 A17 芯片要用 3nm 工艺元旦跨境机票预订量增长145% 1 月 2 日&#xff0c;各旅游平台发布…

小工具集锦,5款好用的良心软件

今天来给大家推荐5款良心软件,每款都是经过时间检验的精品,用起来让你的工作效率提升飞快&#xff0c;各个都让你觉得相见恨晚&#xff01; 1.高效截图——Snipaste 我曾经尝试过 FastStone Capture、ShareX 等多款截图软件&#xff0c;直到遇见 Snipaste 才画上句点。除了基…

“当不存在跨域问题,也解决了数据验证时,还出现:No ‘Access-Control-Allow-Origin‘,说存在跨域问题 ”的解决办法

不存在跨域问题&#xff0c;数据验证也弄好了&#xff0c;还出现下面的问题&#xff1a;Access to XMLHttpRequest at https://m.maizuo.com/gateway?cityId440100&pageNum1&pageSize10&type1&k7325551 from origin http://localhost:8080 has been blocked b…