最近在学react还有go。
在我的不懈坚持之下,终于让前后端通信了,可喜可贺。
:wink:
puts函数换行作用
puts("")
的作用是换行。
puts
函数是 C 标准库中的一个函数,用于将字符串输出到标准输出设备(通常是控制台),并在输出结束后自动换行。
其函数原型如下:
int puts(const char *str);
主要功能:
- 输出字符串:
puts
函数会将传入的字符串参数str
输出到标准输出(通常是终端或控制台)。 - 自动换行:与
printf
不同的是,puts
函数在输出完字符串后会自动添加一个换行符(\n
),因此你不需要手动加上换行。 - 返回值:如果输出成功,
puts
返回一个非负值。如果发生错误,返回EOF
(表示 End of File 或错误)。
示例:
puts("Hello, World!");
输出为:
Hello, World!
(并且会自动换行)
区别:
- 与
printf
不同,puts
只适用于输出 字符串,而不能像printf
那样支持格式化输出(例如整型、浮点型等)。 puts
函数在输出完毕后 自动换行,而printf
需要你手动添加换行符\n
。
所以puts("")
实际上是输出一个空字符串,然后自动换行。
阶乘末尾零优化
在计算 (b!) 的末尾有多少个连续的0时,可以通过模拟阶乘的乘法来计算整个大数阶乘,再统计结果中末尾的0的数量。然而,当 (b) 很大时,这种直接模拟阶乘的方法会导致运行时间和空间效率较低,容易超时。
实际上,计算一个数的阶乘末尾有多少个0并不需要真的计算出整个阶乘。阶乘末尾0的数量实际上取决于阶乘中因子5的数量(因为2的数量总是比5多)。因此,可以采用数学方法来计算。
优化方法
计算 (b!) 末尾0的数量的核心在于统计从1到(b)中,能够被5整除的数的个数,以及更高次方(如25, 125, …)的个数。具体的公式为:
一直计算到
优化后的代码
#include<iostream>
using namespace std;
int main()
{
int b;
cin >> b;
int count = 0;
for (int i = 5; i <= b; i *= 5)
{
count += b / i;
}
cout << count << "\n";
return 0;
}
解释
i
从5开始,每次乘以5,直到 ( i > b ) 为止。b / i
表示当前阶乘数范围内包含多少个可以被当前的5次方整除的数。- 将每一步的结果累加即可得到 (b!) 中因子5的总数,这就是末尾0的数量。
这种方法的时间复杂度是 (O(\log b)),相比原算法效率极高,能轻松处理非常大的 (b) 值,从而避免超时问题。
int类型的变量size()方法返回值进行比较。
从截图中,可以看到程序虽然被正确接受(Accepted),但编译时出现了一些警告。主要问题如下:
警告信息
警告内容显示在以下位置:
warning: comparison of integer expressions of different signedness: 'int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
原因
这些警告是因为在您的 for
循环中,使用了 int
类型的变量 i
与 std::string
的 size()
方法返回值进行比较。而 size()
方法的返回值是一个无符号整数类型 (std::string::size_type
),通常是 size_t
,在很多系统中定义为 long unsigned int
。因此,当您用 int
类型的 i
和无符号的 size_t
进行比较时,编译器会提示这种有符号与无符号类型的比较可能导致潜在的问题。
解决方案
您可以将循环变量 i
的类型从 int
改为 std::string::size_type
或者 size_t
,以确保类型一致。例如:
for (std::string::size_type i = 0; i < s1.size(); ++i) {
// Your code
}
或者:
for (size_t i = 0; i < s1.size(); ++i) {
// Your code
}
总结
虽然这些警告不会影响程序的运行,但为了代码的健壮性和可维护性,建议按照上述方法修改代码,消除这些警告。
C++ 字典实现方法
在C++中没有像Python那样的内置“字典”(即dict
)这种直接的数据类型,但可以使用std::map
或者std::unordered_map
来实现类似字典的功能。这些容器位于C++标准库的<map>
或<unordered_map>
头文件中。
这两者都允许将“键-值对”进行存储和查找,像Python的字典一样,不过它们有一些区别:
std::map
:- 是一个有序的关联容器,底层实现通常为红黑树。
- 存储的键值对是有序的,按照键的顺序自动排序。
- 查找、插入、删除的时间复杂度为O(log n)。
例子:
#include <iostream> #include <map> int main() { std::map<std::string, int> myMap; myMap["apple"] = 1; myMap["banana"] = 2; std::cout << "apple: " << myMap["apple"] << std::endl; // 遍历 for (const auto& pair : myMap) { std::cout << pair.first << ": " << pair.second << std::endl; } return 0; }
std::unordered_map
:- 是一个无序的关联容器,底层实现通常为哈希表。
- 键值对是无序的,插入顺序与存储顺序无关。
- 查找、插入、删除的平均时间复杂度为O(1),但最坏情况下可能为O(n)。
例子:
#include <iostream> #include <unordered_map> int main() { std::unordered_map<std::string, int> myUnorderedMap; myUnorderedMap["apple"] = 1; myUnorderedMap["banana"] = 2; std::cout << "apple: " << myUnorderedMap["apple"] << std::endl; // 遍历 for (const auto& pair : myUnorderedMap) { std::cout << pair.first << ": " << pair.second << std::endl; } return 0; }
总结
- C++中的
std::map
和std::unordered_map
可以实现类似Python字典的功能。 std::map
是有序的,而std::unordered_map
是无序的。- 使用哪种容器取决于你的使用场景:如果你需要按键有序存储,选择
std::map
;如果你不关心顺序,且希望更快的查找速度,选择std::unordered_map
。