入门算法
方法
判断闰年
1 | bool isLeapYear(int year) { |
【易错:ASCII码】s[i]-‘0’;和(int)s[i];为什么结果不一样
在C++中,s[i] - '0'
和 (int)s[i]
表达式虽然都涉及到将字符转换为整数,但它们的目的和结果通常是不同的。
s[i] - '0'
这个表达式通常用于将字符(假设它是一个数字字符,即
'0'
到'9'
之间的某个字符)转换为对应的整数值。在ASCII编码中,数字字符'0'
到'9'
是连续排列的,且'0'
的ASCII码值是48。因此,当你从一个数字字符中减去'0'
时,你实际上是在计算该字符与'0'
在ASCII表中的距离,这个距离恰好等于该字符所代表的数字值。例如,如果
s[i]
是'5'
,那么s[i] - '0'
的结果将是5 - 48 + 48
(这里的48
是'0'
的ASCII码值,但加48再减48是为了说明原理,实际上直接计算53 - 48
)等于5
。(int)s[i]
这个表达式将字符
s[i]
强制转换为整数类型。但是,这里转换得到的是字符的ASCII码值,而不是字符所代表的数字值(如果它是一个数字字符的话)。例如,如果
s[i]
是'5'
,那么(int)s[i]
的结果将是53
,因为'5'
在ASCII表中的值是53。
因此,这两个表达式在用途和结果上是不同的。s[i] - '0'
用于将数字字符转换为对应的整数值,而 (int)s[i]
则用于获取字符的ASCII码值。在实际编程中,你应该根据具体需求选择使用哪个表达式。
输入字符串
在C++中,字符串的输入方法有多种,以下是几种常见的方法:
使用
cin
直接输入:cin >> str;
:这种方法从标准输入读取单个单词,存储在变量str
中。它会在遇到空格或换行符时停止读取,因此只能读取到第一个空格之前的部分。
使用
cin.get()
输入:cin.get(str, size);
:从标准输入读取指定大小的字符串(包括空字符),存储在字符数组str
中。这种方法可以读取包含空格的字符串,但需要注意数组的大小,以避免溢出。
使用
getline()
函数输入:getline(cin, str);
:从标准输入读取整行,包括空格和换行符(换行符会被丢弃),存储在字符串str
中。这种方法常用于需要读取包含空格的整行输入的情况。
使用
gets()
函数输入(注意:gets()
函数是不安全的,已被C++标准弃用,推荐使用gets_s()
或其他安全的字符串输入方法):gets(str);
:从标准输入读取一行字符串,包括空格,直到遇到换行符为止。换行符会被存储在字符串中,但通常会被后续的输入操作覆盖或丢弃。由于gets()
函数存在缓冲区溢出的风险,因此不推荐使用。
使用
scanf()
输入:scanf("%s", str);
:这种方法只能读取不包含空格的字符串。当输入字符串中包含空格时,scanf()
会在遇到第一个空格时停止读取。此外,使用scanf()
时需要注意缓冲区的大小,以避免溢出。同时,scanf()
会在输入缓冲区中留下换行符,这可能会影响后续的输入操作。
使用
getchar()
逐个字符输入:char ch; while((ch = getchar()) != '\n') { /* 处理字符 */ }
:这种方法通常用于逐个字符地读取输入,直到遇到换行符为止。它可以用于读取包含空格的字符串,但需要手动处理字符和构建字符串。
使用文件输入流:
- 如果需要从文件中读取字符串,可以使用文件输入流
ifstream
。例如,ifstream infile("filename.txt"); string line; while(getline(infile, line)) { /* 处理每行 */ }
。
- 如果需要从文件中读取字符串,可以使用文件输入流
需要注意的是,以上方法中有些是不安全的或已被弃用的(如gets()
),在实际编程中应尽量避免使用。同时,对于不同的应用场景和需求,可以选择最适合的字符串输入方法。例如,对于需要读取包含空格的整行输入的情况,通常推荐使用getline()
函数。
for循环遍历字符串
在C++中,你可以使用for
循环来遍历一个string
字符串。string
提供了多种访问其字符的方法,包括使用下标运算符[]
和迭代器。以下是一些使用for
循环遍历字符串的示例:
使用下标运算符
1 |
|
在这个例子中,str.size()
返回字符串的长度,str[i]
访问字符串中位置为i
的字符。注意,size_t
是一个无符号整数类型,通常用于表示大小和索引。
使用范围for循环(C++11及以上)
1 |
|
范围for
循环(也称为基于范围的for
循环)简化了遍历容器的语法。在这个例子中,c
将依次被赋值为字符串str
中的每个字符。
使用迭代器
虽然在这个特定的情况下使用下标运算符或范围for
循环可能更常见,但了解如何使用迭代器来遍历字符串也是很有用的,因为迭代器是STL中更通用的概念。
1 |
|
在这个例子中,str.begin()
返回一个指向字符串第一个字符的迭代器,str.end()
返回一个指向字符串末尾之后位置的迭代器(不是最后一个字符,而是最后一个字符之后的位置,用作循环的结束条件)。*it
解引用迭代器以获取它所指向的字符。
注意,从C++11开始,你还可以使用auto
关键字来自动推导迭代器的类型,从而简化代码:
1 |
|
在这个修改后的例子中,auto
使得代码更加简洁,并且减少了因类型错误而导致的问题。
取数字里的每一位数
1 | // b用来保存当前的数字,c用来保存当前的位置 |
函数
【函数】isalpha、isspace、isdigit判断字母空格和数字
1 | int main() { |
【函数】toupper和tolower大小写转换
toupper
函数
toupper
函数用于将小写字符转换为对应的大写字符。如果传入的字符不是小写字母,则函数返回该字符本身。
tolower
函数
tolower
函数用于将大写字符转换为对应的小写字符。如果传入的字符不是大写字母,则函数返回该字符本身。
1 | //1.a.begin()和a.end()定义了要进行转换的范围,即容器a的开始和结束迭代器。 |
【函数】sscanf和ssprintf的用法
sscanf是C语言中的一个函数,用于从字符串中读进与指定格式相符的数据。它是scanf函数的字符串版本,允许从一个字符串而不是标准输入中读取数据。
sscanf
一、sscanf函数原型
1 | int sscanf(const char *str, const char *format, ...); |
str
:待解析的字符串。format
:字符串格式描述,用于指定如何从字符串中读取数据。...
:一序列数目不定的指针参数,用于存储解析后的数据。
二、基本用法
sscanf函数支持多种数据类型的读取,包括字符串(%s)、整型(%d, %ld等)、浮点型(%f, %lf等)。使用时,需要在format字符串中指定数据类型,并提供相应的指针参数来存储读取的数据。
例如:
1 | char str[] = "123 456.78"; |
输出结果为:
1 | a = 123, b = 456.78 |
三、高级用法
取指定长度的字符串:
使用
%[width]
格式说明符可以读取指定长度的字符串。例如:1
2
3
4char str[] = "123456789";
char buf[10];
sscanf(str, "%4s", buf);
printf("%s\n", buf);输出结果为:
1234
取到指定字符为止的字符串:
使用
%[^chars]
格式说明符可以读取直到遇到指定字符集为止的字符串。例如:1
2
3
4char str[] = "123456abcdedf";
char buf[50];
sscanf(str, "%[^A-Z]", buf);
printf("%s\n", buf);输出结果为:
123456abcdedf
忽略指定字符:
使用
%*
格式说明符可以忽略指定数量的字符或满足特定格式的字符串。例如:1
2
3
4char str[] = "iios/12DDWDFF@122";
char buf[50];
sscanf(str, "%*[^/]/%[^@]", buf);
printf("%s\n", buf);输出结果为:
12DDWDFF
读取多个数据类型:
sscanf函数可以一次读取多个数据类型,只需在format字符串中依次指定数据类型,并提供相应的指针参数即可。例如:
1
2
3
4
5char str[] = "AT+COM=123456,789.012";
int a;
float b;
sscanf(str, "AT+COM=%d,%f", &a, &b);
printf("a = %d, b = %.2f\n", a, b);输出结果为:
a = 123456, b = 789.01
四、注意事项
使用sscanf函数时,要确保提供的缓冲区足够大,以避免缓冲区溢出问题。
sscanf函数的返回值表示成功读取的数据项数量,可以通过检查返回值来判断读取是否成功。
在处理复杂格式的字符串时,要仔细设计format字符串,以确保正确读取数据。
sprintf是C语言中的一个标准库函数,全称是“string print”,意为“字符串打印”。这个函数的主要功能是将格式化的数据写入某个字符串中,即发送格式化输出到一个字符串所指向的内存区域。
sprintf
一、sprintf函数原型
sprintf函数的声明通常如下:
1 | c复制代码 |
str
:这是一个指向字符数组的指针,该数组用于存储格式化后的字符串。format
:这是一个格式控制字符串,用于指定输出的格式。它可以包含嵌入的格式标签,这些标签会被随后附加参数中指定的值替换,并按需求进行格式化。...
:这是一个可变参数列表,用于指定要格式化的数据。这些数据的类型和数量应与格式控制字符串中的格式标签相匹配。
二、格式标签
格式控制字符串中的格式标签以“%”开头,后跟一个或多个字符来指定数据类型、宽度、精度等。常见的格式标签包括:
%d
:表示一个整数。%f
:表示一个浮点数。%c
:表示一个字符。%s
:表示一个字符串。%%
:表示一个百分号字符。
此外,还可以指定输出的宽度和精度。例如,%5d
表示输出的整数宽度至少为5个字符,不足部分用空格填充;%.2f
表示输出的浮点数保留两位小数。
三、使用示例
以下是一个使用sprintf函数的示例:
1 |
|
输出结果为:
1 | 复制代码 |
四、注意事项
- 缓冲区大小:使用sprintf函数时,需要确保提供的缓冲区足够大,以存储格式化后的字符串。如果缓冲区太小,可能会导致缓冲区溢出,进而引发程序崩溃或安全问题。
- 参数匹配:可变参数列表中的参数应与格式控制字符串中的格式标签一一对应,且类型相匹配。否则,可能会导致未定义的行为或程序崩溃。
- 返回值:sprintf函数返回成功写入字符串中的字符数(不包括终止符’\0’)。如果发生错误,则返回负值。可以通过检查返回值来判断写入是否成功。
【函数】n的阶乘和累加
阶乘
1 | //递归方法 |
累加
1 | /*在C++中,计算一个数从1加到它本身(即计算`1 + 2 + ... + n`),最直接的方法是使用循环或数学公式。对于这种方法,效率主要取决于算法的时间复杂度。*/ |
【函数】sort排序
1 | //sort默认升序(从小到大) |
【函数】reverse翻转数组
1 | // 翻转函数 |
【函数】向上/下取整(ceil/floor)
1 | //向上取整 |