🕺作者: 主页
我的专栏 C语言从0到1 探秘C++ 数据结构从0到1 探秘Linux 😘欢迎 ❤️关注 👍点赞 🙌收藏 ✍️留言
文章目录
- 前言
- 使用scanf格式化读取数据
- 输入字符串 getline
- cin.getline() 使用举例
- 两种getline函数
- getline使用举例
- 输入多行字符串(行数未知)
- 截断字符串
- 字符串转浮点数 stof函数
- PAT甲级真题1108 求平均值
- 输入格式
- 输出格式
- 数据范围
- 输入样例1:
- 输出样例1:
- 输入样例2:
- 输出样例2:
- 题解
- 对二维数组去重
前言
欢迎提供新技巧,可在评论区留言~
使用scanf格式化读取数据
eg:
scanf("%d.%d.%d %d.%d.%d",&a,&b,&c,&d,&e,&f);
//可以读取数据格式为1.2.4 2.14.15
输入字符串 getline
使用getline函数:
cin.getline()也是常用的读取整行string的方式。
getline()操作的对象是string,cin.getline()操作的对象的char数组
cin.getline()函数读取至新行结尾或直到达到最大限制的整行文本。函数定义如下:
// (buffer, stream_size, delimiter)
istream& getline(char*, int size, char='\n')// The delimiter character is considered as '\n'
istream& getline(char*, int size)
- 提取字符直到定界符。
- 将字符存储在缓冲区中。
- 提取的最大字符数为size-1。
cin.getline() 使用举例
#include <iostream>
using namespace std;
int main()
{ char str[20]; cin.getline(str, 20); cout << str; return 0;
}
两种getline函数
有两种getline函数:
库函数 string 和 iostream 均有getline函数#include<string> // 全局的函数
istream& getline (istream& is, string& str, char delim);
istream& getline (istream& is, string& str);#include <iostream> // 成员函数
istream& getline (char* s, streamsize n);
istream& getline (char* s, streamsize n, char delim);注意iostream的getline是将读取的字符串存储在char数组中而不可以将该参数声明为string类型,
因为C++编译器无法执行此默认转换。
getline使用举例
#include <iostream>
#include <string>
using namespace std;
int main() {string s;getline(cin, s);cout << s; system("pause");return 0;
}
输入多行字符串(行数未知)
string str;
vector<string> v;
while (getline(cin, str)) //读取输入的一行数据
{if (str.size() == 0) break; //如果读取的是空,则读取结束v.push_back(str);
}
截断字符串
substr:返回一个从指定位置开始的指定长度的子字符串
stringvar.substr(start, [length])
/*
参数
stringvar 必选项。要提取子字符串的字符串文字或 String 对象。
start 必选项。所需的子字符串的起始位置。字符串中的第一个字符的索引为 0。
length 可选项。在返回的子字符串中应包括的字符个数。说明
如果 length 为 0 或负数,将返回一个空字符串。如果没有指定该参数,则子字符串将延续到 stringvar 的最后。
*/
字符串转浮点数 stof函数
使用方法和stoi函数一样
stof判断"5.2abc"这类字符串时视"5.2"为合法,"abc"不合法,但实际上5.2abc不合法
举例:
PAT甲级真题1108 求平均值
基本任务非常简单:给定 N 个实数,请你计算它们的平均值。
但是令事情变得复杂的是,某些输入数字可能不合法。
合法输入数字指 [−1000,1000] 范围内的精确到不超过 2 个小数位的实数。
在计算平均值时,不得将这些非法数字计算在内。
输入格式
第一行包含整数 N。
第二行包含 N 个输入数字,数字之间用空格隔开。
输出格式
按照输入的顺序,对于每个输入的非法数字,在一行中输出 ERROR: X is not a legal number,其中 X 是非法输入。
最后一行,输出 The average of K numbers is Y,其中 K 是合法输入的数量,Y 是它们的平均值,注意保留两位小数。
如果平均值无法计算,则将 Y 替换为 Undefined。
如果 K 仅为 1,则输出 The average of 1 number is Y。
数据范围
1≤N≤1000
输入样例1:
7
5 -3.2 aaa 9999 2.3.4 7.123 2.35
输出样例1:
ERROR: aaa is not a legal number
ERROR: 9999 is not a legal number
ERROR: 2.3.4 is not a legal number
ERROR: 7.123 is not a legal number
The average of 3 numbers is 1.38
输入样例2:
2
aaa -9999
输出样例2:
ERROR: aaa is not a legal number
ERROR: -9999 is not a legal number
The average of 0 numbers is Undefined
题解
//@魔法学徒:https://www.acwing.com/user/myspace/index/162238/
#include <iostream>
using namespace std;int main()
{int n;cin >> n;int cnt = 0; // 合法数字个数double sum = 0; // 合法数字总和while (n -- ){string num;cin >> num;double x;bool success = true;/*不加try catch报错terminate called after throwing an instance of 'std::invalid_argument' what(): stof(若传入不可转化为浮点型的字符串)会抛出异常*/try{size_t idx = sizeof(num); // size type 用来记录大小的数据类型x = stof(num, &idx); // 字符串转换为float型// stof判断"5.2abc"这类字符串时视"5.2"为合法,"abc"不合法,但实际上5.2abc不合法if (idx < num.size()) success = false; // 经stof处理后变短的字符串不合法}catch(...) // 捕捉所有类型的异常 {success = false; // 所有不合法的输入数字都设为error}if (x < -1000 || x > 1000) success = false;int k = num.find('.');if (k != -1 && num.size() - k > 3) success = false;// 不超过2个小数位(最后一位是num.size()-1)if (success) cnt ++, sum += x;else printf("ERROR: %s is not a legal number\n", num.c_str());}if (cnt > 1) printf("The average of %d numbers is %.2lf\n", cnt, sum / cnt);else if (cnt == 1) printf("The average of 1 number is %.2lf\n", sum);else puts("The average of 0 numbers is Undefined");return 0;
}
对二维数组去重
std::vector<std::vector<int>> removeDuplicates(const std::vector<std::vector<int>>& arr) {std::vector<std::vector<int>> sortedArr = arr;// 对二维数组排序std::sort(sortedArr.begin(), sortedArr.end());// 去除重复项auto last = std::unique(sortedArr.begin(), sortedArr.end());sortedArr.erase(last, sortedArr.end());return sortedArr;}
在上述代码中,std::unique 函数用于去除连续的重复项,该函数位于 <algorithm> 头文件中。函数的原型如下:
template<class ForwardIt>
ForwardIt unique(ForwardIt first, ForwardIt last);
其中,first 和 last 是表示要处理的元素范围的迭代器,ForwardIt 是一个泛型类型。std::unique 函数会返回一个指向最后一个不重复元素之后位置的迭代器。这意味着,从 first 到 last 的范围内的所有连续重复元素都被移到了范围的末尾,并且返回的迭代器指向了新范围的终点。
在代码中,我们使用 std::unique 函数将数组 sortedArr 中的重复项移到了末尾,并将返回的迭代器保存在 last 变量中。然后,我们使用 erase 函数将重复项从数组中删除,其原型如下:
template<class Container, class Iterator>
Iterator erase(Container& cont, Iterator pos);
其中,cont 是容器,pos 是指向要删除元素位置的迭代器。erase 函数会从容器中删除指定位置的元素,并返回一个指向被删除元素之后位置的迭代器。
在我们的代码中,sortedArr 是一个二维向量,我们使用 erase 函数将 last 到 sortedArr.end() 范围内的元素从 sortedArr 中删除,即删除了末尾的重复项。
通过上述操作,我们使用 std::unique 函数和 erase 函数成功去除了二维数组中的连续重复项。