1、
char str[1001];
strlen(str);//头文件include《string.h》
Stack()
1 | boolean empty() 测试堆栈是否为空。 |
2 | Object peek( ) 查看堆栈顶部的对象,但不从堆栈中移除它。 |
3 | Object pop( ) 移除堆栈顶部的对象,并作为此函数的值返回该对象。 |
4 | Object push(Object element) 把项压入堆栈顶部。 |
5 | int search(Object element) 返回对象在堆栈中的位置,以 1 为基数。 |
还有个add方法,可以指定在指定位置放入数据stack1.add(0,tmp)
vector末尾的添加移除操作
vector.push_back(elem); //在容器尾部加入一个元素。
vector.pop_back(); //移除容器中最后一个元素
例如:
vector<int> vecInt;
vecInt.push_back(1); vecInt.push_back(3);
vecInt.push_back(5);vecInt.push_back(7);
vecInt.push_back(9);
此时容器vecInt就包含了按顺序的1,3,5,7,9元素。
如果在此基础上再运行语句vecInt.pop_back();
vecInt.pop_back();此时容器vecInt就包含了按顺序的1,3,5元素。
Arrays.sort(array);//java中对数组进行排序 小于7个元素用的插入排序,大于的话使用的是快速排序
return
array[
0
];
2、char类型的输入时候,会忽略前面的空格,in空字符(包括回车,TAB,空格)都会当成一个输入的结束。连续的空字符会被忽略
char a[1000];
cin.getline(a, 1000);
这样会将空格也算进去,不然12 3 那么3是存不进去的,遇到空格当作结束了
3、
string s = str; //char转化为string
count1 = s.find("P");//find是string类里面的,返回下标
4、system("pause")不能有
5、有的数组的大小需要根据输入的n去定
法1 int a = (int)malloc(n * sizeof(int));//动态申请数组空间
for (int i = 0; i < n; i++) { cin >> a[i];
}
法2 vector v(k);//定义一个动态数组,大小为k
vector result;//定义一个空的动态数组
for(int i=0;i<k;i++){
scanf("%d", &v[i]);
}
6、输入的方式不同
有的是直接就一个数组,cin直接连着输入即可,集中处理数组
cin >> n;
int *a = (int*)malloc(n * sizeof(int));//动态申请数组空间
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
for (int j = 0; j < n; j++)
{
int d = a[j];
..................
}
有的是输入一个,随机处理数据,在输入,在处理
vector<int> v(k);//定义一个动态数组,大小为k
vector<int> result;//定义一个空的动态数组
for(int i=0;i<k;i++){
cin>>v[i];//这个是输入一个检测一回,不是输入完才检测的
n = v[i];
while(n != 1){
if(n % 2 == 0){
n /= 2;
if(flag[n] == true){
break;
.............
}
stack<string>a; string s; int n=0; while (cin>>s)//ctrl+z 再按回车才会结束输入,正常每输入一个就要回车一次,空格也会被当成字符串 { a.push(s); n++; }
我们先来看一段输入流cin>>和getline混用的代码:
#include<iostream>
#include<string>
using namespace std;
int main()
{
int age;
string name;
cout<<"请输入年龄:"<<endl;
cin>>age;
cout<<"请输入姓名:"<<endl;
getline(cin,name);
cout<<"年龄:"<<age<<endl;
cout<<"姓名:"<<name<<endl;
return 0;
}
不难看出这段代码的初衷是通过输入流、输入流提取运算符cin>>和getline分别从命令行获取年龄age和姓名name,但是运行后的结果如下:
可以看出并没有得到我们期望的结果,输入姓名的代码没有等待用户输入就被跳过。
我们先看下cin>>与getline的工作方式,流提取运算符根据它后面的变量类型读取数据,从非空白符号开始,遇到Enter、Space、Tab键时结束。getline函数从istream中读取一行数据,当遇到“\n”时结束返回。
getline(cin,str)的读取原理是将以‘/n’为结束符做为一完整读取的一行,'/n'会读。所以当之前用cin读取一个字符的时候,你会输入一个字符然后点击回车,那么下面getline(cin,str)读的时候会读入这个回车,并判断结束了。
造成程序错误结果的原因是,用户输入完年龄后按回车结束输入,把“\n”留在了输入流里,而cin不会主动删除输入流内的换行符,这样换行符就被getline读取到,getline遇到换行符返回,因此程序不会等待用户输入。
解决的办法是手动清除换行符,在cin>>后加上
cin.ignore();
这样即可得到正确结果:
因此在使用getline函数之前要注意,输入流中是否有可能会有换行符,如果有则使用cin.ignore清除。
注意点2:
C++中vector头文件中有push_back这一函数,作用是在vector尾部加入一个数据。string中也有这个函数,作用是在字符串结尾插入一个字符。
注意点3:
length 和size后面的()不要掉(新手)
7、vectore为什么不可以强行赋值
可以这么理解
vector<int> a;
并没有开辟一段存放数据的空间,这时候 a.size() 为0,换个角度,如果一个数组大小为0,必然不能往这个数组里写数据
两种方式
一种是push_back()
vector<int> a;
a.push_back(0);
a.push_back(1);
这时候a[0] == 0, a[1] == 1
另一种是在定义vector的时候指定一个大小
vector<int> a(10, 0);
a[0] = 1;
将a[0]的值由0改为1
vector<vector<int> > array
int row = array.size();
int col = array[0].size();
int i,j;
for (i=0,j=col-1;i<row && j>=0;)
{
if (array[i][j] == target)
{
8、string和int的转换
一个非常好用的方法,使用stringstream,个人理解:可以把stringstream理解为一个容器,输入进去一种类型,可以以另一种类型形式输出,例如下代码就实现了string到int的转换,注意复用时要clear一下,另外要包含头文件<sstream>
#include<iostream>
#include<sstream>
using namespace std;
int main(){
stringstream ss;
string s="55";
string s2="666";
int x;
ss<<s;
ss>>x; //x为55
cout<<x<<endl;
ss.clear();
ss<<s2;
ss>>x; //x为666
cout<<x<<endl;
return 0;
}
找到一个大佬对stringstream较详细的讲解,附上链接供大家学习string和stringstream用法总结,本菜鸡目前掌握到这刷题就够用了。
刷oj更常用的是下面这个方法
string s="123";
int a=atoi(s.c_str());
如果string不是数字形式的则转换结果为0。
————————————————
int转为string
string aaa = to_string(result / i);
string bbb= to_string(i);
或者用
String.valueOf(i)
对于string类型变量,我们可以直接用“+”或者“+=”进行字符串的连接,操作符非常方便。
用“+”风格字符串进行字符串连接时,操作符左右两边既可以都是string字符串,也可以是一个string字符串和一个C风格的字符串,还可以是一个string字符串和一个char字符。
而用“+=”风格字符串进行字符串连接时,操作符右边既可以是一个string字符串,也可以是一个C风格字符串或一个char字符。
上述两种方法:左边必须是string字符串。
对于string类型变量,我们可以直接用“+”或者“+=”进行字符串的连接,操作符非常方便。用“+”风格字符串进行字符串连接时,操作符左右两边既可以都是string字符串,也可以是一个string字符串和一个C风格的字符串,还可以是一个string字符串和一个char字符。而用“+=”风格字符串进行字符串连接时,操作符右边既可以是一个string字符串,也可以是一个C风格字符串或一个char字符。
例1:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1, s2, s3;
s1 = "first";
s2 = "second";
s3 = s1 + s2;
cout<< s3 <<endl;
s2 += s1;
cout<< s2 <<endl;
s1 += "third";
cout<< s1 <<endl;
s1 += 'a';
cout<< s1 <<endl;
return 0;
}
str.contains("3") 检查包含
求解奇数序列中,3出现的次数
我们看到这个数值866278171,为8亿多,去掉偶数,只看奇数,也有4亿多。
问这4亿个数中3出现了多少次,这个问题有点费解。
方式一 暴力破解
所谓暴力破解,就是遍历每一个数值,统计3出现的次数。下面的各个版本仅供参考:
该方案耗时:2m 52s 139ms
// 奇数序列中,一共出现了多少次3
int number = 866278171;
int sum = 0;
for (int i = 1; i <= number; i = i + 2) {
sum += String.valueOf(i).replace("3", "_#_")
.split("#")
.length - 1;
}
// 总数: 441684627
System.out.println("总数: " + sum);
该方案耗时:1m 41s 259ms
// 奇数序列中,一共出现了多少次3
int number = 866278171;
int sum = 0;
for (int i = 1; i <= number; i = i + 2) {
String str = String.valueOf(i);
if (str.contains("3")) {
sum += str.length() - str.replace("3", "").length();
}
}
// 总数: 441684627
System.out.println("总数: " + sum);
该方案耗时:22s 942ms
// 奇数序列中,一共出现了多少次3
int number = 866278171;
int sum = 0;
for (int i = 1; i <= number; i = i + 2) {
String str = String.valueOf(i);
for (int j = 0; j < str.length(); j++) {
if (str.charAt(j) == '3') {
sum++;
}
}
}
// 总数: 441684627
System.out.println("总数: " + sum);
该方案耗时:6s 669ms
// 奇数序列中,一共出现了多少次3
int number = 866278171;
int sum = 0;
for (int i = 1; i <= number; i = i + 2) {
int k = i;
while (k > 1) {
if (k % 10 == 3) {
sum++;
}
k /= 10;
}
}
// 总数: 441684627
System.out.println("总数: " + sum);
我们看到,走了好多的弯路,String类中的replace和contains都是重量级方法。当我们使用有限次数时,并不会感觉到慢。但是当我们需要重复执行上亿次时,就很慢了。
————————————————