暑假oj練習
C++基礎
變量
1)整型 int 4Byte 32bit, long long 8byte 4bit
以上,
long long bignum; long long bignum=123456789012345LL;
%d:int型輸出格式
2)浮點型 float 1符號位 8 指數位 23尾數位(存在有效精度6~7位)
double 1符號位 11指數位 52尾數位(15~16位精度)
double a=20.0;
“%f":float 和double的輸出格式
3)字符型 char “%c"
字符串常量:字符串由若干字符組成的串。“%s"
4)符號常量和const常量
符號常量通俗的意思是“替換”,即用一個標識符來替代常量,又稱為“宏定義”,“宏替換”,于是在程序中凡是使用pi的地方將會在程序執行前全部自動替換為3.14.
#define pi 3.14
const double pi=3.14;
這兩種寫法都被稱為常量,值一旦確定后就無法改變。
define除了定義常量外,還可以定義任何語句或片段
#define ADD(a,b) ((a)+(b))//必須加這么多括號
5)位運算符
<<左移 >>右移
使用scanf和printf輸入輸出
scanf()函數執行成功后的返回值是成功讀取的變量數,也就是說,這個scanf()函數有n個變量,如果scanf()函數全部正常讀取,它就返回n。scanf()函數執行成功意味著:用戶輸入的數據類型與scanf()函數的變量類型匹配,且個數一致,如scanf(“%d”, &a);用戶輸入的是整數6,則scanf()函數執行成功,返回值為1 。
#include <stdio.h>
scanf("%d",&n);scanf("%lld",&lon);
scanf("%f",&f);scanf("%lf",&db);
scanf("%c",&c);scanf("%s",str);//str為char數組類型
printf("%d",n);printf("%lld",n);
printf("%f",fl);printf("%f",db);//這個和scanf不一樣
printf("%c",c);printf("%s",str);
沒有寫&可能會導致數據異常退出。
“%0md",m表示位數。”%.mf“表示幾位小數
使用getchar和putchar輸入、輸出字符
getchar 用來輸入單個字符,putchar用來輸出單個字符,在某些scanf函數使用不便的場合可以用getchar來輸入字符。
getchar可以識別換行符、空格,同時可以用putchar輸出。
#include<stdio.h>
int main(){
char c1,c2,c3;
c1=getchar();//內容存在c1里。
getchar();
c2=getchar();
c3=getchar();
putchar(c1);
putchar(c2);
putchar(c3);
return 0;
}
字符數組的輸入輸出
char str[10];
scanf("%s",str);printf("%s",str);//不能讀入空格
//使用getchar(),putchar();
char str2[5][5];
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
str[i][j]=getchar();//可以輸入空格
}
getchar();//可以吸收換行符
}
輸入格式:
^ ^
-
^
- -
使用gets,puts
gets識別換行符\n作為輸入結束。因此scanf完一個整數后,如果要使用gets,需要先用getchar接收整數后的換行符。puts,輸出,并緊跟一個換行符。
#include<stdio.h>
int main(){
char str1[20];
char str2[5][10];
gets(str1);
for(int i=0;i<3;i++){
gets(str2[i]);
}
}
- 結束符\0 ASCII碼為0,即空字符NULL,占用一個字符位,因此開char數組時千萬要記得字符數組的長度一定要比實際存儲字符串長度至少多1
- 使用getchar輸入在字符串后加結束符“\0";
string.h[char數組的相關函數]
1 | strcpy(s1, s2); 復制字符串 s2 到字符串 s1。 |
---|---|
2 | strcat(s1, s2); 連接字符串 s2 到字符串 s1 的末尾。 |
3 | strlen(s1); 返回字符串 s1 的長度。 |
4 | strcmp(s1, s2); 如果 s1 和 s2 是相同的,則返回 0;如果 s1<s2 則返回值小于 0;如果 s1>s2 則返回值大于 0。 |
sscanf和sprintf
sscanf:string+scanf; sprintf:string+printf
把各種類型的數據放到數組中
scanf("%d",&m)->scanf(screen,"%d",&m);
sscanf(str,"%d",&n);
sprintf(str,"%d",n);
把數字等輸入數組中去,這個時候,str相當于屏幕,如:
char str[100]="2048:3.14,hello",str2[100];
sscanf(str,"%d:%lf,%s",&n,&db,str2);
cin與cout
使用條件:1.#include<iostream> 2.using namespace std;
讀入一整行的方法:
char str[100];cin.getline(str,100);
string str; getline(cin,str);
cin cout 可能會引起超時。
typedef 給復雜的數據類型起一個別名,這樣在使用中就可以用別名來代替原來的寫法。
math 函數
fabs(double x):對double變量取絕對值
floor(double x) :double型變量向下取整
ceil(double x):double型變量向上取整
pow(double r ,double p)
sqrt(double x) 開方
log(double x)(以e為底)sin cos tan
round(double x) 四舍五入
數組
如果數組一開始沒有賦初值,數組中的每個元素都可能會是一個隨機數,并不一定默認為0
把數組賦為0.memset,fill
int a[10]={0}; int a[10]={};
scanf("%d",&b[i][j]);//二維數組
如果數組大小較大(>),則需要將其定義在主函數外面,否則會使程序異常退出。
int a[1000000];
- 主要函數 memset
memset() 函數常用于內存空間初始化
memset可以方便的清空一個結構類型的變量或數組。
#include<string.h>
···
memset(數組名,值,sizeof(數組名))
memset(a,-1,sizeof(a));
使用memset需要在程序開頭添加string.h頭文件,且只建議初學者使用賦0或-1,因為memset按字節賦值,對每個字節賦同樣的值。如果對數組賦其他數字(如1),請使用fill函數
- 相似作用 fill函數
fill函數可以把數組或容器中某一區間段賦為某個相同的值。
#include<algorithm>
···
int a[5] = {1,2,3,4,5};
fill(a,a+5,233);//
C++ STL介紹
vector
- 常見用途
1)存儲數據,作為數組使用。2)用鄰接鏈表存儲圖【可以避開指針】
#include <stdio.h>
#include <vector>
using namespace std;
int main(){
vector<int> vi;
for(int i=1;i<=5;i++){
vi.pushback(i);
}
vector<int>::iterator it=vi.begin();
for(int i=0;i<5;i++){
printf("%d",*(it+i));
//等于輸出vi[i]
}
/**另一種寫法
for(vector<int>::iterator it=vi.begin();it!=vi.end();it++){
printf("%d",*it);//這里不支持it<vi.end();
}
**/
}
vector<int> vec;
vector():創建一個空vector
vector(int nSize):創建一個vector,元素個數為nSize
vector(int nSize,const t& t):創建一個vector,元素個數為nSize,且值均為t
vector(const vector&):復制構造函數
vector(begin,end):復制[begin,end)區間內另一個數組的元素到vector中
vec.size();vec.empty();
末尾添加元素: vec.push_back(const T& x);
末尾刪除元素: vec.pop_back();
任意位置插入元素:
任意位置刪除元素: vec.erase();
交換兩個向量的元素: vec.swap();
下標訪問: vec[1]; //并不會檢查是否越界
at方法訪問: vec.at(1); //以上兩者的區別就是at會檢查是否越界,是則拋出out of range異常
訪問第一個元素: vec.front();
訪問最后一個元素: vec.back();
(3)a.back();//返回a的最后一個元素
(4)a.front();//返回a的第一個元素
(5)a[i]; //返回a的第i個元素,當且僅當a[i]存在2013-12-07
(6)a.clear();//清空a中的元素
(7)a.empty();//判斷a是否為空,空則返回ture,不空則返回false
(8)a.pop_back();//刪除a向量的最后一個元素
(9)a.erase(a.begin()+1,a.begin()+3);//刪除a中第1個(從第0個算起)到第2個元素,也就是說刪除的元素從a.begin()+1算起(包括它)一直到a.begin()+3(不包括它)
(10)a.push_back(5);//在a的最后一個向量后插入一個元素,其值為5
(11)a.insert(a.begin()+1,5);//在a的第1個元素(從第0個算起)的位置插入數值5,如a為1,2,3,4,插入元素后為1,5,2,3,4
(12)a.insert(a.begin()+1,3,5);//在a的第1個元素(從第0個算起)的位置插入3個數,其值都為5
(13)a.insert(a.begin()+1,b+3,b+6);//b為數組,在a的第1個元素(從第0個算起)的位置插入b的第3個元素到第5個元素(不包括b+6),如b為1,2,3,4,5,9,8,插入元素后為1,4,5,9,2,3,4,5,9,8
(14)a.size();//返回a中元素的個數;
set
set:集合,是一個內部自動有序且不含重復元素的容器。
在考試中,可能會需要去掉重復元素,且這些元素比較大,或不是int型不能用散列函數。這時可以用set保存元素。set可以自動排序。
- 常見用途
自動去重,并按升序排序。【需要不唯一 -》用multiset】
set只能通過迭代器iterator訪問
除開vector和string之外的STL容器都不支持(it+i)的訪問方式*
set<typename>::iterator it;
//實例
#include<stdio.h>
#include <set>
using namespace std;
int main(){
set<int> st;
st.insert(3);
st.insert(5);
st.insert(2);
st.insert(3);
for(set<int>::iterator it=st.begin();it!=st.end();it++){
printf("%d",*it);
}
return 0;
}
string[重要]
string str="abcd";
str.length();str[i];cin>>str;cout<<str;
str.c_str();//將str轉化成char數組。
printf("%s\n",str.c_str());
//拼接 str1+str2;
str.insert(2,str2);str.erase(str.begin()+4);
str.erase(str.begin()+2,str.end()-1);//刪除[str.begin()+2,str.end()-1)元素
str.erase(2,2);//刪除2號位開始的兩個元素,23兩個元素
str.substr(0,5);//從0開始5個元素
str.find(str2);//找到返回位置,否則返回string::npos
map
映射map將任意基本類型映射到任意基本類型。
可以用iterator訪問
map<string,int> mp; map<set<int>,string> mp;
map<char,int> mp;mp['c']=20;mp['r']=30;
printf("%d",mp['c']);//輸出20
for(map<char,int>::iterator it=mp.begin();it!=mp.end();it++){
printf("%c %d\n",it->first,it->second);
}
find erase等方法
priority queue
用堆實現,隊首元素一定是當前隊列在優先級最高的那一個。
【有序的一般是由大到小】
【好像設定需要重載操作符,需要用到的時候再詳細看QAQ】
pair
可以看做內部有兩種類型元素的結構體。
- 常見用途
用來代替二元結構體及其構造函數,節省編碼時間。
作為map鍵值進行插入
pair<string,int> p;
p.first="haha";p.second=5;
cout<<p.first<<" "<<p.second<<endl;
map<string,int> mp;
map.insert(pair<string,int>("haha",10));
比較時先比較first大小,first相等再比較second大小。
algorithm
- max(),min(),abs();
- swap();
int x=1;y=2;
swap(x,y);(x=2,y=1)
- reverse();
int a[10]={10,11,12,13,14,15};
reverse(a,a+4);
string str="sd";
reverse(str.begin+2,str.begin+6);
for(int i=0;i<str.length();i++){
printf("%c",str[i]);
}
- next_permutation生成全排列
int a[10]={1,2,3}//開始是從小到大的順序
do{
printf("%d%d%d\n",a[0],a[1],a[2]);
}while(next_permutation(a,a+3))
memset(x,-1,sizeof(x));
fill(a,a+5,233);
sort(a,a+4);//從小到大排序(char數組也可以,字典序)
- cmp
bool cmp(int a,int b)
return a>b;
sort(a,a+4,cmp);//寫比較,用方法幫助排序
bool cmp(node a,node b)
return a.x>b.x
- sort函數
sort(re,re+m,cmp);\\sort(首元素地址,尾元素下一個地址,比較函數(可不填))
int a[6]={9,4,2,5,6,-1};
sort(a,a+4);//a[0]~a[3]從小到大排序
stable_sort(a,a+4);//穩定排序 !!!!!
指針舉例
int a=2;int *p=&a;
//int*是指針變量的類型,后面的p才是變量名,用來存儲地址。因此地址&a是賦值給p而不是給*p的。
printf("%d\n",*p);//得到p中的元素
指針變量也可以進行加減法。對一個int* 型的指針變量p來說,p+1是指p所指的int型變量的下一個int型變量地址。p+i,說明是跨越到當前int型變量之后的第i個int型變量。int *p,則這里變量p不能存放double型或者char型數據的地址,必須是int型數據的地址。
- 使用指針作為函數參數
void change(int *p){
*p=233;
}