C++常见问题

生成随机数

加头函数

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

在main函数下第一行加

 srand((unsigned)time(NULL));
 // 生成[a,b]
 p = rand()%(b - a + 1) + a;

产生一定范围随机数的通用表示公式
要取得[a,b)的随机整数,使用(rand() % (b-a))+ a;
要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a;
要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1;
通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。
要取得a到b之间的随机整数,另一种表示:a + (int)b * rand() / (RAND_MAX + 1)。
要取得0~1之间的浮点数,可以使用rand() / double(RAND_MAX)。

字符串

string 操作加

#include <string>

字符数组操作加

#include <cstring>

string 转字符数组 s.c_str();
string 输入输出只能使用 cin,cout
输入一行字符串getline(cin, s);
遇到空格符,换行等停止读入 cin >> s
数字转换成字符串注意2位数以上要多次取余转换
char 数组可以 直接赋值给string
基本类型转string 使用 to_string(int/double);
字符串相加只能一对一对加,不能2个以上一次性相加。

string s;
s += "a"; // 正确
s = s + "a" + "b"; // 错误

s.erase(index, len); 去掉的是从下标为index开始的len长度的字符,是对原字符串上操作。

编译器设置

有些编译器不支持C++11需要设置,dev设置
选择工具->编译选项->勾选在这里插入图片描述
空白处添加 -std=c++11

编译器报错问题

  1. C++ 遇到reference to ’ *** ’ is ambiguous 错误
    定义的变量名与库函数重名,更换一下名字就好了,例如next

  2. 在函数区定义过大数组会导致运行直接出错。将大数组定义为全局变量即可。或者在main使用vector。vector申请空间是动态申请的,在堆中,空间较大。vector<int> v(6)初始化为vector分配空间,可以使用&v[i] 赋值

位运算

if (x & 1)

使用&操作进行余2操作不能x & 1 == 0 因为==的优先级大于& 会先计算1 == 0,为false 导致x&false 始终为false了。

stl

可以使用auto遍历容器的元素,类似于java的增强for循环。
vector添加结构体可以使用{x,y}来表示。

#include <bits/stdc++.h>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
struct Node{
	int x, y;
};
int main(int argc, char** argv) {
	vector<Node> v;
	v.push_back({1,2});
	for (auto it: v) {
		printf("%d %d", it.x, it.y);
	}
	return 0;
}

c++11的auto遍历map

for(auto it: mp) {
	cout << it.first << it.second;
}

优先队列排序priority_queue需要重载结构体的<号

    struct Node{
        int x, y;
        friend bool operator < (Node n1, Node n2) {
            return n1.y < n2.y;
        }
    };

这样使得大的在顶部
list的内置sort对结构体排序也需要重载结构体的<号

    struct Node{
        int x, y;
        friend bool operator < (Node n1, Node n2) {
            return n1.y < n2.y;
        }
    };

跟优先队列的相反,这样表示从小到大排列

bitset

常用于判断数组哪一位取不取。集合合并,统计N个数组成的不同数的个数。

bitset<n> bs; // 如集合bs 存放 10110110
bs = bs | bs << n;  //表示原集合bs和集合bs内所有1左移n位, 原来位置上的1就到了1+n位上
// 如左移2位 bs << 2, bs就变成 00101101,i位置上为1左移n位相当于i+n位置变成1
// 在和bs进行或操作, bs = 10111111
int x = bs.count(); // 统计bs集合中1的个数

进制转换

负进制转换
若余数为负,商 = 商+1,余数= 余数 - 除数
-15 = -2 * 7 …-1
余数 = -1 - (-2) = 1
商等于 7 + 1 = 8
8 = -2 * 4 … 0

-15 = 110001(-2) = =1×(−2)^5 +1×(−2)^4 +0×(−2)^3 +0×(−2)^2 +0×(−2)^1+1×(−2)^0

库函数使用

lower_bound

非递减数组二分查找,即升序,存在重复的元素
lower_bound 查找第一个大于等于x的数,返回的是数组对应的下标地址指针。需要减去数组初始地址得到整数坐标,下面同理。
upper_bound 查找第一个大于x的数,返回的是数组对应的下标地址指针。

int v[20];
int p = lower_bound(v, v + n, x) - v
int p = upper_bound(v, v + n, x) - v

非递增数组二分查找,即降序,存在重复的元素
重载lower_bound 查找第一个小于等于x的数,返回的是数组对应的下标地址指针。
重载upper_bound 查找第一个小于x的数,返回的是数组对应的下标地址指针。

int p = lower_bound(v, v + n, x, greater<int>()) - v;
int p = upper_bound(v, v + n, x, greater<int>()) - v;

代码实现二分查找


__builtin_popcount(x)

统计x的二进制中1的个数,O(M)的时间复杂度,M为1的个数。
实现:
利用n&(n-1)使得n的二进制末尾最后一个1变0.
n = 01010100
n-1 = 01010011
所以每次的与操作将n的末尾1变0,其他位不变,直到n变为0结束。

    int hammingWeight(uint32_t n) {
        int cnt = 0;
        while (n) {
            cnt++;
            n &= (n - 1);
        }
        return cnt;
    }

取余

一个数的前i位对n取余之后的结果在连接上第i+1位在对n取余等于前i+1位为n取余的结果。
如:314
31 % 3 = 1—连接上4----> 14 % 3 = 2
314 % 3 = 2
即如果判断一个很长的整数是否能被n整除,可以从高位一位一位取余在连接后一位判断。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值