1.程序一秒的運行時限,所設計的算法複雜度不能超過百萬級別,即不能超過1千萬。若算法複雜度是O(n^2),則該n不該大於3000,不然會達到千萬數量級複雜度。ios
2.qsort 的使用方法:算法
1、對int類型數組排序express
int num[100];數組
int cmp ( const void *a , const void *b )函數
{ui
return *(int *)a - *(int *)b; //升序排序spa
//return *(int *)b - *(int *)a; //降序排序設計
/*可見:參數列表是兩個空指針,如今他要去指向你的數組元素。因此轉型爲你當前的類型,而後取值。指針
升序排列時,若第一個參數指針指向的「值」大於第二個參數指針指向的「值」,則返回正;若第一個參數指針指向的「值」等於第二個參數指針指向的「值」,則返回零;若第一個參數指針指向的「值」小於第二個參數指針指向的「值」,則返回負。對象
降序排列時,則恰好相反。
*/
}
qsort(s,n,sizeof(s[0]),cmp);
示例完整函數(已在 VC6.0上運行經過):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int s[10000],n,i;
int cmp(const void *a,const void *b)
{
return(*(int *)b-*(int *)a); //實現的是降序排序
}
int main()
{
// 輸入想要輸入的數的個數
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&s[i]);
qsort(s,n,sizeof(s[0]),cmp);
for(i=0;i<n;i++)
printf("%d ",s[i]);
return(0);
}
2、對char類型數組排序(同int類型)
char word[100];
int cmp( const void *a , const void *b )
{
//注意,網上不少版本是 「 return *(char *)a - *(int *)b; 」
//由於編輯者的不用心,盲目copy,以訛傳訛,傳的一直是錯的 *(int *)b
//應該是return *(char *)a - *(char *)b;
return *(char *)a - *(char *)b;
}
qsort(word,100,sizeof(word[0]),cmp);
//附,可能 getchar(); 會派上用場
3、對double類型數組排序(特別要注意)
double in[100];
int cmp( const void *a , const void *b )
{
return *(double *)a > *(double *)b ? 1 : -1;
//返回值的問題,顯然cmp返回的是一個整型,因此避免double返回小數而被丟失,用一個判斷返回值。
}
qsort(in,100,sizeof(in[0]),cmp);
//附:排序結果的輸出,通常建議用 「 %g 」 格式
/* 在這裏多嘴一句,"%g"格式輸出 雖然書上是說系統會自動選擇 " %f " 格式 和 " %e " 格式 中長度較短的格式,並去掉無心義的0,但實際上系統若是選擇了" %e ",系統會輸出比 「 %e " 格式更省一位的格式輸出。(此結論,來自VC6.0的實際操做)*/
4、對結構體一級排序
struct In
{
double data;
int other;
}s[100]
//按照data的值從小到大將結構體排序,關於結構體內的排序關鍵數據data的類型能夠不少種,參考上面的例子寫
int cmp( const void *a ,const void *b)
{
return (*(In *)a).data > (*(In *)b).data ? 1 : -1;
//注意,這條語句在VC6.0環境下運行可能會出錯,可是並非語句錯了,而是你要先 Build ,或者所有重建。總之語句是對的。
//或者你能夠將這上面1條語句改爲下面這3條語句
//struct In *aa = (In *)a;
//struct In *bb = (In *)b;
//return aa->data > bb->data ? 1 : -1;
}
qsort(s,100,sizeof(s[0]),cmp);
5、對結構體二級排序
struct In
{
int x; //你能夠比喻成:失敗次數
int y; //你能夠比喻成:成功次數
}s[100];
//按照x從小到大排序,當x相等時按照y從大到小排序。 你能夠想象成:失敗是主要因素的一個問題,先比較 失敗次數少,失敗次數相同 再看 成功次數多。
int cmp( const void *a , const void *b )
{
struct In *c = (In *)a;
struct In *d = (In *)b;
if(c->x != d->x) return c->x - d->x;
else return d->y - c->y;
}
qsort(s,100,sizeof(s[0]),cmp);
6、對字符串進行排序
struct In
{
int data;
char str[100];
}s[100];
//按照結構體中字符串str的字典順序排序
int cmp ( const void *a , const void *b )
{
return strcmp( (*(In *)a)->str , (*(In *)b)->str );
}
qsort(s,100,sizeof(s[0]),cmp);
注意!qsort 中的 cmp 得本身寫 。
C++sort()的用法:
默認sort排序後是升序,若是想讓他降序排列,可使用本身編的cmp函數
#include<iostream>
#include<algorithm>
using namespace std;
int cmp(int a,int b)
{
if(a<b)
return 1; //升序排列,若是改成 a >b,則爲降序,要注意sort()中cmp()的返值只有1和0,不像qsort中存在-1!!!!
else
return 0;
}
int main(){
int i;
int a[20];
for(int i=0;i<5;++i)
cin>>a[i];
sort(a,a+5,cmp); //範圍,很明顯這裏是a+5 注意,這是必要的,若是是a+4最後一個值a[4]就不會參與排序。
for(i=0;i<5;i++)
cout<<a[i]<<endl;
system("pause");
return 0;
}
對二維數組的排序:
#include <iostream>
#include <algorithm>
#include <ctime>
using namespace std;
bool cmp(int *p,int *q)
{
if(p[0]==q[0])
{
if(p[1]==q[1])
{
return p[2]<q[2];
}
else return p[1]<q[1];
}
else return p[0]<q[0];
}
int main()
{
srand(time(0));
int i;
int **a=new int*[1000];
for(i=0;i<1000;++i)
{
a[i]=new int[3];
a[i][0]=rand()%1000;
a[i][1]=rand()%1000;
a[i][2]=rand()%1000;
//printf("%d\t%d\t%d\n",a[i][0],a[i][1],a[i][2]);
}
sort(a,a+1000,cmp);
/*cout<<"After sort"<<endl;
for(i=0;i<1000;++i)
{
printf("%d\t%d\t%d\n",a[i][0],a[i][1],a[i][2]);
}*/
return 0;
}
推薦sort用法
3. int strcmp(const * char, const * char );
<string.h>是C版本的頭文件,包含好比strcpy、strcat之類的字符串處理函數。
<cstring>
在C++標準化(1998年)過程當中,爲了兼容之前,標準化組織將全部這些文件都進行了新的定義,加入到了標準庫中,加入後的文件名就新增了一個"c"前綴而且去掉了.h的後綴名,因此string.h頭文件成了cstring頭文件。可是其實現倒是相同的或是兼容之前的,這就是<cstring>的來源,不要以爲又多了一個東西。至關於標準庫組織給它蓋了個章,說「你也是個人標準程序庫的一份子了」。
<string>
<string>是C++標準定義的頭文件,它定義了一個string的字符串類,裏面包含了string類的各類操做,如s.size(), s.erase(), s.insert()等。但<string>又包含了老的C版本的字符串操做如strcpy、strcat等,這就至關於,在<string>的文件中除了定義本身的string類以外,還加了一個#include<string.h>一句包含了C版本的字符串操做。
5.const的使用
二、指針使用CONST
(1)指針自己是常量不可變
char* const pContent;
(2)指針所指向的內容是常量不可變
const char *pContent;
(3)二者都不可變
const char* const pContent;
四、類相關CONST
(1)const修飾成員變量
const修飾類的成員函數,表示成員常量,不能被修改,同時它只能在初始化列表中賦值。
class A
{
…
const int nValue; //成員常量不能被修改
…
A(int x): nValue(x) { } ; //只能在初始化列表中賦值
}
(2)const修飾成員函數
const修飾類的成員函數,則該成員函數不能修改類中任何非const成員函數。通常寫在函數的最後來修飾。
class A
{
…
void function()const; //常成員函數, 它不改變對象的成員變量.
//也不能調用類中任何非const成員函數。
}
對於const類對象/指針/引用,只能調用類的const成員函數,所以,const修飾成員函數的最重要做用就是限制對於const對象的使用。
a. const成員函數不被容許修改它所在對象的任何一個數據成員。
b. const成員函數可以訪問對象的const成員,而其餘成員函數不能夠。
(3)const修飾類對象/對象指針/對象引用
· const修飾類對象表示該對象爲常量對象,其中的任何成員都不能被修改。對於對象指針和對象引用也是同樣。
· const修飾的對象,該對象的任何非const成員函數都不能被調用,由於任何非const成員函數會有修改爲員變量的企圖。
例如:
class AAA
{
void func1();
void func2() const;
}
const AAA aObj;
aObj.func1(); ×
aObj.func2(); 正確
const AAA* aObj = new AAA();
aObj-> func1(); ×
aObj-> func2(); 正確
3、將Const類型轉化爲非Const類型的方法
採用const_cast 進行轉換。
用法:const_cast <type_id> (expression)
該運算符用來修改類型的const或volatile屬性。除了const 或volatile修飾以外, type_id和expression的類型是同樣的。
· 常量指針被轉化成很是量指針,而且仍然指向原來的對象;
· 常量引用被轉換成很是量引用,而且仍然指向原來的對象;
· 常量對象被轉換成很是量對象。
5.直接在struct中寫operator<操做,比從新寫一個cmp函數,在調用sort函數時,耗時少