C++的输入输出,以及STL使用问题
输入不定长度的数组,用字符串变量S存储
- 某些算法题的输入没有要求输入长度,而是直接输入长度未知的数组
1.输入一个长度最多为 30 位数字的十进制非负整数
我们可以使用while循环输入,并存入一个vector整型变量中,以回车结束输入。
string s;
while (cin >> s){
vector<int> A;
for (int i = 0; i < s.size(); i ++){
A.push_back(s[s.size() - 1 - i] - '0');//高精度采用大端存储方法
}//由于输入数据存放在字符串s中,所以我们要存放在vector中时需要 -'0'
}
2.输入包含多组数据
每组第一行为该组数据个数n,接下来n行每行代表一个数据当输入一行0时,代表输入结束.
while(cin >> n);
输入结束的时候能够返回一个bool
类型false
,停止循环.
++ 当输入一行为0时代表输入结束,故:
while(cin >> n && n != 0)
格式化输出
-
要求:每行按
yyyy-mm-dd
的格式输出。printf("%04d-%02d-%02d", year, month, day);
- %4d,指定输出的这个整数占4个宽度。输出的数字不够4位就会补足四个空格
- %04d,最低4个宽度,不足4个补0。
- %-4d,最低4个宽度,居左。
- %+4d,最低4个宽度,显示±。
- %6.4f,最低6个宽度,保留4位小数。
- % d,正数前面有个空格,负数显示负号。
- %#o,#作用是显示八进制/十六进制符号,如果是浮点数如%#8.0f,#会阻止保留小数。
输入输出字符串
0.需要知道的ASCii码知识
'0'~'9' = 48 ~ 57
数字0到9的编码'A'~'Z' = 65 ~ 90
大写字母A到Z'a'~'z' = 97 ~ 122
小写字母a到z
小写字母x变大写字母X:x -= 32;
字符类型数字x变int型数字 :x -= '0';
1.puts()
函数定义与使用
int puts(const char *s);
其中s可以是字符串常量,字符数组名。
puts(name) == printf("%s\n", name)
即puts()会在字符串输出后自动换行。
puts("") == cout << endl
通常用来当做换行使用。
2.读入一整行(包括空格、制表符)的字符串(getline)
当 cin
读取数据时,它会传递并忽略任何前导白色空格字符(空格、制表符或换行符)
getline(cin, s);
其中s
是string
类型,能够读入一整行字符- 使用
getline(cin, s)
输入时,我们要自行在while
里面判断什么时候结束输入
while (getline(cin, s)) {
if (s.size() == 0) break;//当遇到空白行时,结束输入
logs[n ++] = s;
}
3.读入以不定长度空格分隔开的字符串(sstring)
#include <sstream>
:使用其中的stringstream sa(str)
,将str
字符串以空格或制表符分开,并储存在sa
输入流中,等待输入给string
变量
#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main()
{
string str = "I am coding ABC";//初始化一行字符串,其中含多个空格
stringstream in_stream(str);//创建一个stringstream对象,可以看成一个含多段字符的cin
do{
string substr;
in_stream >> substr;//将sa中的字符按序输出到substr中
cout << substr << endl;
} while (in_stream);//sa中存有字符时,while循环继续进行
return 0;
}
4.sscanf(str,...)
与c_str()
来读入字符串中不同类型的变量值
##输入:hs_10000_p 2007-01-17 19:22:53,315 253.035(s)
## name yy-mm-dd hh:min:ss,mmm cost (s)
int main(){
int n = 0;
string s;
while (getline(cin, s)) {
if (s.size() == 0) break;
char name[20] = {0};//
int yy, mm, dd, hh, min, ss, mmm;//
double cost;
sscanf(s.c_str(), "%s %04d-%02d-%02d %02d:%02d:%02d,%d %lf", name, &yy, &mm, &dd, &hh, &min, &ss, &mmm, &cost);
}//sscanf函数操作的对象必须是字符串,所以我们要使用s.c_str()将string变量变为字符串
5.sscanf()
函数的用法
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int day, year;
char w[20], m[20], d[100];//char类型的数组,对应%s的输入形式
strcpy( d, "Saturday March 25 1989" );
sscanf( d, "%s %s %d %d", w, m, &day, &year );
printf("%s %d, %d = %s\n", m, day, year, w );
return(0);
}
string
转为 char*
变量
const char *ch1 = str.c_str();
- 通过将
string
转换成char*
来使用sscanf()
- 用
char*
类的参数来保存%s
对应的值。
sscanf函数原型:
int sscanf (char *str, "%d, %s, ..." , [argument, ...]);
【参数】参数str为要读取数据的字符串;format为用户指定的格式;argument为变量,用来保存读取到的数据。
c++STL
函数的使用方法
1.<algorithm>
库函数
-
count
函数
定义与使用:count(起始地址, 结束地址, 查找元素)
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s = "abcdefgaabbccd";//vector,
int num = count (s.begin(), s.end(), 'a');//在字符串s中查找'a'出现次数
cout << num << endl;
}
-
sort函数
sort(first, last, cmp);
对[first,last)(一定要注意这里的区间是左闭又开)区间内数据根据
cmp
的方式进行排序。其中,first是元素的起始地址,last是结束地址,cmp
是排序的方式。也可以不写第三个参数,此时按默认排序,从小到大进行排序。 -
memset初始化数组
设有int 型数组A[N],现将数组元素全部初始化为 -1.
memset(A, -1, sizeof A);
当我们在func()函数下对传入的数组进行初始化时,sizeof需要使用原数组名,若使用传入参数名,长度会变成指针长度。
-
reverse函数
reverse(a.begin(),a.end());
将a中的元素倒置,操作区间同样是[first,last)。
-
copy函数
copy(a.begin(),a.end(),b.begin());
将a中元素复制到b,a中复制区间为[first,last),b中复制区间从begin()开始
2. <string>
函数
1.初始化
-
直接赋值
string str = "zhijiefuzhi";
-
初始化为
n
个char
字符string str (n, ' ');
2.erase()
函数
- 删除指定范围字符
[first, second)
的字符串:str.erase(first, second)
- 删除指定长度的字符串:
str.erase(pos, len)
std::string str("This is an example sentence.");
str.erase(10, 8);
str.erase(str.begin() + 9);
str.erase(str.begin() + 5, str.end() - 9);
//输出结果
this is an sentence.
this is a example sentence.
this sentence.
3. string -> int 的stoi()
函数
- 将
string
变量转换为指定进制的int
变量
//函数定义
int stoi (const string& str, size_t* idx = 0, int base = 10);
str:表示所要转化的字符串
idx:表示想要str中开始转化的位置,默认为从第一个字符开始。
base:表示要用的进制(如2进制、16进制,默认为10进制)转化为int类型十进制数字。
4.<string>的find()
s.find(str, pos)
: 从字符串的pos位置开始,查找子字符串str。如果找到,则返回该子字符串首次出现时其首字符的索引;否则,返回string::npos.
s.rfind(str):
反向查找字符串中的str子串,常与正向查找一起使用,若两次返回结果不同,则说明字符串s中含有多个字符串str.to_string(int x)
:将数字x变为string类型,即可使用string的所有内置函数,如to_string(x).find('7')
:查找数字x中是否含7
.
5. str.substr()
str.substr(int pos, int end);
//pos为要复制string串的起始位置,end为结束位置。(end为空时代表从pos一直到string结尾)
2.queue
基本操作
//基本操作
q.push(x); //入队,将元素 x 从队尾插入(尾插法)
q.pop(); //出队,删除对首元素,并返回其值
q.size(); //返回队中元素个数
q.front(); //返回对首元素
q.back(); //返回队尾元素
q.empty(); //判断是否为空(空返回 1,非空返回 0)
4.priority_queue
- 定义
priority_queue <int, vector<int>, less<int>> q === priority_queue <int> pq
:构建大根堆pq
priority_queue <int, vector<int>, greater<int>> pq
:构建小根堆pq
- 基本操作
pq.top();//返回堆顶元素
pq.pop();//堆顶元素出队
pq.size();//堆中元素个数
3. <vector>
库函数
-
初始化
- 初始化一维vector:
vector <int> a
- 初始化二维vector:
vector
:vector<vector<int>> a(N, vector<int> (M));
定义一个N
行M
列的二维数组
- 初始化一维vector:
-
添加、查找、删除元素
a.front(); //返回a的第一个元素
a.back(); //返回a最后一个元素
a.push_back(val); //在a中最后一个元素后插入val
a.clear(); //清空a中元素
//a中添加元素 vector <int> a; for (int i = 0; i < n; i ++) a.push_back(x);//不能使用下标添加元素!下标只能用于获取已存在的元素,而现在的a[i]还是空的对象 //a中访问元素 int a[6]={1,2,3,4,5,6}; vector <int> b (a, a + 4); for(int i = 0;i <= b.size() - 1; i ++) cout << b[i] << " ";
4. <unordered_map>
与< map>
详解
使用区别:
- map中存储的键值对是有序的,其key按字典序有序存放
精度问题
- 小心整除
double a = 4/3 * PI * pow(r, 3)
:运算到3/4
时进行整除运算,并向下取整
double a = 4.0/3 * PI * pow(r, 3)
:强制类型转换,不进行取整操作
- 小心
sqrt()
a != sqrt(a) * sqrt(a)
:a
是double
类型的浮点数,进行开方运算sqrt()
后结果丢失部分精度,故两式不再相等。