演算法怎麼搞
① 該怎麼提高自己的演算法能力
先好好讀書,這里我推薦the
art
of
unix
programming,我自己便是看完這書後技術能力才有質的變化。
然後,減少看微博、博客、知乎等的時間,最好是徹底不看,這些資訊的網站是非常浮躁的,很難學到真正的東西。
學門新語言,比方說go,
python,
ruby,
haskell等等,然後用這門語言去做一個開源項目,比方說,一個orm。然後,再去看這門語言的成功項目的源碼。看看自己寫的跟別人的不足是什麼,然後,再把自己的項目重新實現一遍。自覺略有所得之後換個方向,比方說模板,再搞個開源項目。伺服器後端的mvc各搞一次,還可以再去搞前端的。
最後,心態要好,不要急於求成,欲速則不達。修煉一年能有小成就不錯的了~
② 怎樣研究演算法
演算法是一個體系。為什麼說研究演算法的都是高學歷高智商的人呢,就是因為搞演算法不是一蹴而就的。
首先你不要心急,這東西真沒有捷徑。
我給你說說大概的步驟吧。
首先要學習數學,初等數學啦,高等數學啦,甚至說是概率,幾何,代數,離散數學,數學分析,數學建模,這些都要多多少少的涉及。
這時候很多人就煩了,說搞演算法,你讓我學什麼數學啊。
確實,你學完這些課,你還不能編自己的演算法,但是這裡面很多演算法的思想非常重要,你沒見過你就不會用,你就不會分析,所以這些課學好了都不行,還要學精。
再者就是做項目,結合項目來不斷見識演算法和思想。
我說說我用了幾年吧,我大三開始好好學習的,兩年時間完成了數學課程的學習,之後讀研,三年時間主要是用本科學的數學課程來進行演算法分析,編寫演算法。
研究生一畢業就去工作,直接找的演算法工程師的工作,工作剛開始比較難,強度稍微大一點,不過好在有基礎,所以大概一個月就上手了。
總之怎麼研究演算法,這東西不能一蹴而就,你要耐下心來學基礎課程。
如果你還沒考大學,你去考數學專業或者計算機專業或者金融專業。
如果你已經畢業了,可以考這幾個方向的研究生。
③ 怎樣學習演算法
c++要比c語言難的多,每個人學習新的東西時都會感覺到亂的,等你感覺不到亂的時候,可以說你已經入門了或者說已經掌握了,一下接觸許多陌生的名詞就會感覺亂的,一定的沉得住氣努力的學下去,有許多人在中途放棄c++就是輔助課程就把人給搞煩了,高數里要用到傅里葉級數,微分積分等,你兩本高等數學都的學,c語言的知識就不多了,了解就行了,數據結構和演算法你可以看看清華大學編的數據結構(c語言版的),這本書上數據結構和演算法都有。
高等數學和c語言你一起看,看完了你在學c語言和數據結構和演算法,最後學c++,c語言里的函數一定要學會,數據結構和演算法都要用到這些。
雖然不好學,努力堅持學習下去,你一定會成功。
④ 演算法怎麼學
貪心演算法的定義:
貪心演算法是指在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,只做出在某種意義上的局部最優解。貪心演算法不是對所有問題都能得到整體最優解,關鍵是貪心策略的選擇,選擇的貪心策略必須具備無後效性,即某個狀態以前的過程不會影響以後的狀態,只與當前狀態有關。
解題的一般步驟是:
1.建立數學模型來描述問題;
2.把求解的問題分成若干個子問題;
3.對每一子問題求解,得到子問題的局部最優解;
4.把子問題的局部最優解合成原來問題的一個解。
如果大家比較了解動態規劃,就會發現它們之間的相似之處。最優解問題大部分都可以拆分成一個個的子問題,把解空間的遍歷視作對子問題樹的遍歷,則以某種形式對樹整個的遍歷一遍就可以求出最優解,大部分情況下這是不可行的。貪心演算法和動態規劃本質上是對子問題樹的一種修剪,兩種演算法要求問題都具有的一個性質就是子問題最優性(組成最優解的每一個子問題的解,對於這個子問題本身肯定也是最優的)。動態規劃方法代表了這一類問題的一般解法,我們自底向上構造子問題的解,對每一個子樹的根,求出下面每一個葉子的值,並且以其中的最優值作為自身的值,其它的值舍棄。而貪心演算法是動態規劃方法的一個特例,可以證明每一個子樹的根的值不取決於下面葉子的值,而只取決於當前問題的狀況。換句話說,不需要知道一個節點所有子樹的情況,就可以求出這個節點的值。由於貪心演算法的這個特性,它對解空間樹的遍歷不需要自底向上,而只需要自根開始,選擇最優的路,一直走到底就可以了。
話不多說,我們來看幾個具體的例子慢慢理解它:
1.活動選擇問題
這是《演算法導論》上的例子,也是一個非常經典的問題。有n個需要在同一天使用同一個教室的活動a1,a2,…,an,教室同一時刻只能由一個活動使用。每個活動ai都有一個開始時間si和結束時間fi 。一旦被選擇後,活動ai就占據半開時間區間[si,fi)。如果[si,fi]和[sj,fj]互不重疊,ai和aj兩個活動就可以被安排在這一天。該問題就是要安排這些活動使得盡量多的活動能不沖突的舉行。例如下圖所示的活動集合S,其中各項活動按照結束時間單調遞增排序。
關於貪心演算法的基礎知識就簡要介紹到這里,希望能作為大家繼續深入學習的基礎。
⑤ 求高手看數據結構這幾個演算法怎麼弄。是c++,不是c語言!!!做好,馬上給80分!
你這題目不全吧,我以前做的一個課程設計,其中的幾個要求和你的一樣,不過比你的多一些要求,已經通過了,你看看吧:
要求:
1. 創建二叉樹的鏈表存儲結構;
2. 實現二叉鏈表的初始化演算法、二叉樹空的判斷演算法;
3. 實現二叉樹的先序遍歷演算法、中序遍歷演算法和後序遍歷演算法;
4. 利用某遍歷演算法實現計算二叉樹中葉子結點、度為2的結點和度為1的結點的個數。
5. 求二叉樹中結點個數。
6. 求二叉樹的深度。
7. 設計一個演算法,求二叉樹中指定結點x的層數。
8. 設計一演算法,求先序遍歷序列中第k個結點的左右孩子。
9. 求結點x的所有祖先。
10.輸出所有葉子結點到根結點的路徑。
11.如果將二叉樹中左分支標為0,右分支標為1,從葉子結點到根結點的路徑由所經過的左、右分支組成。取左右分支的上0和1就構成了葉子結點的二進制編碼。請輸出二叉樹中所有葉子結點的編碼。
代碼實現
#include <iostream>
using namespace std;
#define Elemtype char
struct TreeNode
{
Elemtype data;
struct TreeNode *lchrild,*rchrild,*preNode;
int record;
};
void IsEmptyTree(struct TreeNode *Node)
{
if(Node!=NULL) cout<<"樹不為空!"<<endl;
else cout<<"樹是空的。"<<endl;
}
struct TreeNode *CreateTree(struct TreeNode *preNode)
{ struct TreeNode *Node;
Elemtype data;
cin>>data;
if(data=='#') return 0;
else
{ Node=new struct TreeNode;
Node->data=data;
Node->preNode=preNode;
Node->lchrild=CreateTree(Node);
Node->rchrild=CreateTree(Node);
}
return Node;
}
void PreOrderTraverse(struct TreeNode *Node)
{
if(Node!=NULL)
{
cout<<Node->data<<" ";
PreOrderTraverse(Node->lchrild);
PreOrderTraverse(Node->rchrild);
}
}
void InOrderTraverse(struct TreeNode *Node)
{
if(Node!=NULL)
{
InOrderTraverse(Node->lchrild);
cout<<Node->data<<" ";
InOrderTraverse(Node->rchrild);
}
}
void LaterOrderTraverse(struct TreeNode *Node)
{
if(Node!=NULL)
{
LaterOrderTraverse(Node->lchrild);
LaterOrderTraverse(Node->rchrild);
cout<<Node->data<<" ";
}
}
void GetData(struct TreeNode *Node,int &i,Elemtype *Data)
{
if(Node!=NULL)
{
GetData(Node->lchrild,i,Data);
Data[i]=Node->data;
i++;
GetData(Node->rchrild,i,Data);
}
}
void CaculateTreeNode(struct TreeNode *Node,int &tNode,int &One,int &Two)
{
if(Node!=NULL)
{
if(Node->lchrild==NULL&&Node->rchrild==NULL) tNode++;
else if(Node->lchrild!=NULL&&Node->rchrild!=NULL) Two++;
else One++;
CaculateTreeNode(Node->lchrild,tNode,One,Two);
CaculateTreeNode(Node->rchrild,tNode,One,Two);
}
}
int TreeHight(struct TreeNode *Node)
{
int i,j;
if(Node==NULL) return 0;
else
{
i=TreeHight(Node->lchrild);
j=TreeHight(Node->rchrild);
}
return ((i>j)?i:j)+1;
}
struct TreeNode *FindNode(struct TreeNode *Node,Elemtype x)
{
struct TreeNode * result = 0;
if(Node==NULL)return 0;
else
{
if(Node->data==x) return Node;
result = FindNode(Node->lchrild,x);
if(result > 0)
return result;
return FindNode(Node->rchrild,x);
}
}
void PreTraverseFind(struct TreeNode *Node,int &i,int k,Elemtype &ch)
{
if(Node!=NULL)
{
i++;
if(i==k) ch=Node->data;
PreTraverseFind(Node->lchrild,i,k,ch);
PreTraverseFind(Node->rchrild,i,k,ch);
}
}
/*void PreTraverseFind(struct TreeNode *Node,int &i,int k,struct TreeNode *p)
{
if(Node!=NULL)
{
i++;
if(i==k) p=Node;
PreTraverseFind(Node->lchrild,i,k,p);
PreTraverseFind(Node->rchrild,i,k,p);
}
}*/
void TreeNodeLocate(struct TreeNode *xNode,struct TreeNode * Root,int &i)
{
if(xNode!=NULL)
{
i++;
if(xNode==Root) return;
TreeNodeLocate(xNode->preNode,Root,i);
}
}
void SearchChildren(struct TreeNode *Node)
{
if(Node->lchrild!=NULL) cout<<"左孩子:"<<Node->lchrild->data<<",";
else cout<<"沒有左孩子,";
if(Node->rchrild!=NULL) cout<<"右孩子:"<<Node->rchrild->data<<"."<<endl;
else cout<<"沒有右孩子."<<endl;
}
void SearchAllParents(struct TreeNode *xNode,struct TreeNode *Root,Elemtype ch)
{
if(xNode!=NULL)
{
if (xNode->data!=ch) cout<<xNode->data<<" ";
if(xNode==Root) return;
SearchAllParents(xNode->preNode,Root,ch);
}
}
//找所有葉子結點的路徑
void FindAllWay(struct TreeNode *xNode,struct TreeNode *Root,Elemtype ch)
{
if(xNode!=NULL)
{
if (xNode!=Root) cout<<xNode->data<<"->";
else{ cout<<xNode->data<<endl; return;}
FindAllWay(xNode->preNode,Root,ch);
}
}
void FindNodeWay(struct TreeNode *Node,struct TreeNode *Root)
{
if(Node!=NULL)
{
if(Node->lchrild==NULL&&Node->rchrild==NULL)
{
FindAllWay(Node,Root,Node->data);//找到一個葉子結點就調用FindAllWay
}
FindNodeWay(Node->lchrild,Root);
FindNodeWay(Node->rchrild,Root);
}
}
void SetNodeRecord(struct TreeNode *Node,struct TreeNode *Root )
{
if(Node!=NULL)
{
if(Node!=Root)
{
if(Node==Node->preNode->lchrild) Node->record=0;
if(Node==Node->preNode->rchrild) Node->record=1;
}
SetNodeRecord(Node->lchrild,Root);
SetNodeRecord(Node->rchrild,Root);
}
}
void FindNodeBinary(struct TreeNode *xNode,struct TreeNode *Root,Elemtype ch)
{
if(xNode!=NULL)
{
if (xNode!=Root) cout<<xNode->record;
else{cout<<endl; return; }
FindNodeBinary(xNode->preNode,Root,ch);
}
}
void FindAllNodeBinary(struct TreeNode *Node,struct TreeNode *Root)
{
if(Node!=NULL)
{
if(Node->lchrild==NULL&&Node->rchrild==NULL) //找到葉子結點
{
FindNodeBinary(Node,Root,Node->data);
}
FindAllNodeBinary(Node->lchrild,Root);
FindAllNodeBinary(Node->rchrild,Root);
}
}
void main()
{
struct TreeNode *Node,*Root,*p;
int tNode=0,One=0,Two=0;
Elemtype ch;
int i=0,k,n;
cout<<"\n提示:以#表示一棵樹有左葉子或者有右子,以##表示既無左葉子也沒有右葉子,請輸入該樹的先序遍歷方式,";
cout<<"(輸入:A B C # # D E # G # # F # # #):"<<endl;
Root=Node=CreateTree(Node);
IsEmptyTree(Node);
cout<<"樹的遞歸先序遍歷結果:";
PreOrderTraverse(Node);
cout<<endl;
cout<<"樹的遞歸中序遍歷結果:";
InOrderTraverse(Node);
cout<<endl;
cout<<"樹的遞歸後序遍歷結果:";
LaterOrderTraverse(Node);
cout<<endl;
CaculateTreeNode(Node,tNode,One,Two);
cout<<"二叉樹中葉子結點"<<tNode<<" "<<"度為2的結點"<<One<<" "<<"度為1的結點的個數"<<Two<<endl;
k=tNode+One+Two;
cout<<"總結點數為:"<<k<<endl;
cout<<"樹的深度為:"<<TreeHight(Node)<<endl;
cout<<"你要判斷哪個字元所在層次:";
Elemtype *Data=new Elemtype[k];
GetData(Node,i,Data);
cin>>ch;
i=0;
p=FindNode(Node,ch);
TreeNodeLocate(p,Root,i);
cout<<"你要查找的字元所在層次為:"<<i<<endl;
cout<<"請輸入你要查找(線序遍歷中)第幾個結點的左右孩子:";
cin>>n;
/* 方法2:PreTraverseFind(Node,i,k,ch);//返回元素
Node=FindNode(Node,ch);//找到元素地址*/
while(1)
{
if(n<=k) break;
cout<<"你輸入的結點樹大於了該樹的總結點樹,請重新輸入:";
cin>>n;
}
if(n<=k)
{
cout<<"結果:";
i=0;
//PreTraverseFind(Node,i,n,p);
PreTraverseFind(Node,i,n,ch);//返回元素
p=FindNode(Node,ch);//找到元素地址*/
SearchChildren(p);
}
cout<<"輸入你要查找哪個結點的所有祖先:";
cin>>ch;
cout<<"你查詢的所有祖先如下:";
p=FindNode(Root,ch);//找到ch的結點地址
SearchAllParents(p,Root,ch);
cout<<"\n所有葉子結點到跟結點的路徑如下:"<<endl;
FindNodeWay(Root,Root);
cout<<"所有葉子結點的二進制編碼如下:"<<endl;
SetNodeRecord(Root,Root );
FindAllNodeBinary(Root,Root);
}
⑥ 想學習演算法,如何入門
入門的話推薦兩本書:《演算法圖解》和《大話數據結構》,
另外推薦一門視頻課程《300分鍾搞定數據結構與演算法》,不想花時間看書的同學,建議看這個視頻課程,是關於數據結構和演算法很好的一個課程。
⑦ 平方哈希演算法怎麼弄題目見下
Hash,一般翻譯做「散列」,也有直接音譯為」哈希「的,就是把任意長度的輸入(又叫做預映射, pre-image),通過散列演算法,變換成固定長度的輸出,該輸出就是散列值。這種轉換是一種壓縮映射,也就是,散列值的空間通常遠小於輸入的空間,不同的輸入可能會散列成相同的輸出,而不可能從散列值來唯一的確定輸入值。簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數。 HASH主要用於信息安全領域中加密演算法,他把一些不同長度的信息轉化成雜亂的128位的編碼里,叫做HASH值. 也可以說,hash就是找到一種數據內容和數據存放地址之間的映射關系
⑧ 如何做好「推薦演算法」有哪些常見的錯誤需要避免
在這里share一下。
1、推薦演算法的構成
一套標準的推薦演算法,需要四個組成部分
第一:數據源,行為基礎數據的篩選;通常,推薦演算法來源於用戶行為的採集,簡單說就是行為數據越豐富,樣本覆蓋率越全面,結果越准確;如果采樣有偏差,那麼結果就會有偏差。
舉例1:游戲推薦演算法,我們之前限於采樣技術水平和處理能力,用的是登陸用戶玩過的游戲歷史,那麼推薦結果就會偏重於需要登陸的游戲。而隨著技術提升用全部用戶玩過的游戲歷史,就更全面了。
舉例2:在搜索引擎中,對關鍵詞做推薦,有兩種方案,一種是基於廣告主的競價記錄;另一種是基於網民的搜索行為;前一種專業性更強,噪音小;後一種覆蓋面廣,噪音大,各有利弊,根據業務訴求選擇。
推薦演算法,通常來源於用戶的行為記錄,比如關鍵詞推薦用用戶搜索歷史,電商推薦用用戶購物歷史,游戲推薦用玩家玩游戲的歷史,然後基於演算法給出相關度,再排序展示 ;但這不絕對,也有並非基於用戶行為記錄的推薦原理,比如基於用戶身份特徵或其他地區、網路環境等特徵,限於篇幅和常見的業務訴求,這里就不展開說明了。
行為基礎數據必要時要做一些去除噪音的工作,比如你通過日誌分析玩家游戲歷史,或用戶購物歷史,至少知道把各搜索引擎和工具的抓取痕跡過濾出去,否則結果是很難看的。
演算法很多種,網上可以搜到很多,就算搜不到,或者搜到了看不懂,自己編也不難的(我就編過,效果自以為還不錯,但是的確不如人家專業的演算法效果好,所以適合練手,不適合出去吹牛)
不同演算法差異還是蠻大的,需要理解一下業務訴求和目標特徵來選擇。這個我真心不是高手,我們同事講的演算法我都沒能理解,就不多說了。微博上的「張棟_機器學習"和"梁斌penny"都是演算法高手,大家可以多關心他們的微博。
第三:參數!
絕對不要認為用到了好的演算法就可以了!演算法往往會基於一些參數來調優,這些參數哪裡來?很不好意思的告訴你,大部分是拍腦袋出來的。但是你拍腦袋出來後,要知道去分析結果,去看哪裡對,哪裡錯,哪裡可以改,好的演算法可以自動調優,機器學習,不斷自動調整參數達到最優,但是通常可能需要你不斷手工去看,去看badcase,想想是什麼參數因素導致的,改一下是否變好?是否引入新的bad case?
第四:校驗!
校驗一種是人工做盲測,A演算法,B演算法的結果混淆,選案例集,看哪個效果好;或A參數、B參數混淆,同理測試。通過盲測選擇認為更合理的演算法、更適宜的參數.
以上是個人認為,做好推薦演算法的步驟
下面說一下常見問題
1、以為有了演算法就ok了,不對參數優化,不做後續的校驗和數據跟蹤,效果不好就說演算法有問題,這種基本屬於工作態度的問題了。
2、對樣本數據的篩選有問題,或缺乏必要的噪音篩查,導致結果噪音多。比如你有個推廣位天天擺著,導致用戶點擊多,然後導致後台行為數據里它和誰的關聯都高,然後不管用戶到哪裡都推薦這個玩意,這就是沒有足夠篩查。
3、熱度影響
我說一下最簡單的推薦演算法
同時選擇了A和B的人數作為A與B的關聯度。
這個實現最簡單,也最容易理解,但是很容易受熱度影響
我曾經注意過某個熱門圖書電商網站,推薦的關聯書籍一水的熱門書籍,就是這個問題。
這些是非常簡單但是又非常容易出現的,關聯誤區。
4、過於求全
現在也遇到一些朋友,一提到推薦演算法或者推薦系統,就說我這個要考慮,那個要考慮,不管是行為記錄,還是用戶特徵,以至於各種節日效應,等等等等,想通過一個推薦系統完全搞定,目標很大,所以動作就極慢,構思洋洋灑灑做了很多,實現起來無從下手,或者難以寸進;我覺得,還是量力而行,從最容易下手的地方開始,先做到比沒有強,然後根據不斷地數據校驗跟蹤,逐漸加入其他考慮因素,步步前進,而不要一上來就定一個宏偉的龐大的目標;此外要考慮實現成本和開發周期,對於大部分技術實力沒有網路,騰訊,淘寶那麼強的公司而言,先把簡單的東西搞好,已經足夠有效了,然後在運營數據的基礎上逐次推進,會越來越好;有些公司是被自己宏大的目標搞的焦頭爛額,最後說,哎,沒牛人搞不定啊。嗯,反正他們的目標,我顯著是搞不定的。就這些,希望有所幫助