算法怎么搞
① 该怎么提高自己的算法能力
先好好读书,这里我推荐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、过于求全
现在也遇到一些朋友,一提到推荐算法或者推荐系统,就说我这个要考虑,那个要考虑,不管是行为记录,还是用户特征,以至于各种节日效应,等等等等,想通过一个推荐系统完全搞定,目标很大,所以动作就极慢,构思洋洋洒洒做了很多,实现起来无从下手,或者难以寸进;我觉得,还是量力而行,从最容易下手的地方开始,先做到比没有强,然后根据不断地数据校验跟踪,逐渐加入其他考虑因素,步步前进,而不要一上来就定一个宏伟的庞大的目标;此外要考虑实现成本和开发周期,对于大部分技术实力没有网络,腾讯,淘宝那么强的公司而言,先把简单的东西搞好,已经足够有效了,然后在运营数据的基础上逐次推进,会越来越好;有些公司是被自己宏大的目标搞的焦头烂额,最后说,哎,没牛人搞不定啊。嗯,反正他们的目标,我显着是搞不定的。就这些,希望有所帮助