请用C++编这个程序 谢谢

求高手帮忙写一下 这个程序,,,,,谢谢了
[问题点数:40分,结帖人u]
求高手帮忙写一下 这个程序,,,,,谢谢了
[问题点数:40分,结帖人u]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
本帖子已过去太久远了,不再提供回复功能。大家好,我想用纯C编写一个代码编辑器,可是目前我只会写控制台,不会做界面,请问高手能不能给我一个思路,谢谢!
回复讨论(解决方案)
Linux下C没有问题,可以看看VIM的源码,
Windows下必须是C++,像MFC自带的编辑控件,实现起来比较容易。
cmd的编辑器比gui麻烦多了,上个纯c的简单例子
#include&&stdlib.h&
#include&&iup.h&
int&main(int&argc,&char&**argv)
&&Ihandle&*dlg,&*multitext,&*
&&IupOpen(&argc,&&argv);
&&multitext&=&IupText(NULL);
&&vbox&=&IupVbox(
&&&&multitext,
&&&&NULL);
&&IupSetAttribute(multitext,&&MULTILINE&,&&YES&);
&&IupSetAttribute(multitext,&&EXPAND&,&&YES&);
&&dlg&=&IupDialog(vbox);
&&IupSetAttribute(dlg,&&TITLE&,&&Simple&Notepad&);
&&IupSetAttribute(dlg,&&SIZE&,&&QUARTERxQUARTER&);
&&IupShowXY(dlg,&IUP_CENTER,&IUP_CENTER);
&&IupSetAttribute(dlg,&&USERSIZE&,&NULL);
&&IupMainLoop();
&&IupClose();
&&return&EXIT_SUCCESS;
用的也是纯c的gui库iup
c做界面的话去看看gtk
Windows&下的&Raw&控制台代码,需要调用&控制台API
DOS下的&Raw&控制台代码&可以调用&Bios&中断(0x10),DOS&中断(0x21)
总之,Raw&控制台,需要依赖&系统服务,API&
C,C++标准库,不能提供很好的支持。
你需要先考虑清楚,是用系统的图形库,还是第三方图形库,或者自己写图形库。
参考Notepad++源代码&?
你需要先考虑清楚,是用系统的图形库,还是第三方图形库,或者自己写图形库。
第三方图形库吧
cmd的编辑器比gui麻烦多了,上个纯c的简单例子
#include&&stdlib.h&
#include&&iup.h&
int&main(int&argc,&char&**argv)
&&Ihandle&*dlg,&*multitext,&*
&&IupOpen(&argc,&&argv);
&&multitext&=&IupText(NULL);
&&vbox&=&IupVbox(
&&&&multitext,
&&&&NULL);
&&IupSetAttribute(multitext,&&MULTILINE&,&&YES&);
&&IupSetAttribute(multitext,&&EXPAND&,&&YES&);
&&dlg&=&IupDialog(vbox);
&&IupSetAttribute(dlg,&&TITLE&,&&Simple&Notepad&);
&&IupSetAttribute(dlg,&&SIZE&,&&QUARTERxQUARTER&);
&&IupShowXY(dlg,&IUP_CENTER,&IUP_CENTER);
&&IupSetAttribute(dlg,&&USERSIZE&,&NULL);
&&IupMainLoop();
&&IupClose();
&&return&EXIT_SUCCESS;
用的也是纯c的gui库iup
这是系统API吗?
Windows&下的&Raw&控制台代码,需要调用&控制台API
DOS下的&Raw&控制台代码&可以调用&Bios&中断(0x10),DOS&中断(0x21)
总之,Raw&控制台,需要依赖&系统服务,API&
C,C++标准库,不能提供很好的支持。
我可以用DirectX来做图形库吗?
控制台做这个啊,应该可以吧,不过和控制台的初衷,相违背了啊
还是要先得到控制台窗口的DC
然后就和普通窗口一样了吧,没玩过
控制台做这个啊,应该可以吧,不过和控制台的初衷,相违背了啊
还是要先得到控制台窗口的DC
然后就和普通窗口一样了吧,没玩过
不好意思,我没表达清楚,我不是要在控制台下,只是做一个普通的GUI程序就行了,在Windows下的
C可以用&API&
C++可以用&MFC
C可以用&API&
C++可以用&MFC
请问Windows下C用API实现会很复杂吗?
有了MFC不是很想深入学习API的,
都去用MFC了。毕竟爱偷懒是人的天性
用API写代码编辑器,或者文本编辑器,要用到一些控件
建立窗口的代码,可以让VC自动生成,其他要靠自己编写了
Windows&Win32&程序,就是&窗口程序,完全可以用&C写
用API写代码编辑器,或者文本编辑器,要用到一些控件
建立窗口的代码,可以让VC自动生成,其他要靠自己编写了
Windows&Win32&程序,就是&窗口程序,完全可以用&C写
刚看了下Windows程序设计(第5版),给跪了,请问要用MFC是不是要先学C++呢?
《C语言课程设计案例精编》有个编辑器实例,不过DOS的已经不推荐了。
Windows界面,还是C++&Builder、QT或者C#吧。
用API写代码编辑器,或者文本编辑器,要用到一些控件
建立窗口的代码,可以让VC自动生成,其他要靠自己编写了
Windows&Win32&程序,就是&窗口程序,完全可以用&C写
刚看了下Windows程序设计(第5版),给跪了,请问要用MFC是不是要先学C++呢?
C++&Builder的VCL、Visual&C++的MFC、QT都是一种类库,是基于C++的,是面向对象的。C语言没有类。
《C语言课程设计案例精编》有个编辑器实例,不过DOS的已经不推荐了。
Windows界面,还是C++&Builder、QT或者C#吧。
纯C可以用QT吗?
用API写代码编辑器,或者文本编辑器,要用到一些控件
建立窗口的代码,可以让VC自动生成,其他要靠自己编写了
Windows&Win32&程序,就是&窗口程序,完全可以用&C写
刚看了下Windows程序设计(第5版),给跪了,请问要用MFC是不是要先学C++呢?
C++&Builder的VCL、Visual&C++的MFC、QT都是一种类库,是基于C++的,是面向对象的。C语言没有类。
好吧,那也就是说要想用QT,前提也要会C++?
刚看了下Windows程序设计(第5版),给跪了,请问要用MFC是不是要先学C++呢?
C++&Builder的VCL、Visual&C++的MFC、QT都是一种类库,是基于C++的,是面向对象的。C语言没有类。
好吧,那也就是说要想用QT,前提也要会C++?
对的,C++是一个必攻的中途岛,然后可以分支。
刚看了下Windows程序设计(第5版),给跪了,请问要用MFC是不是要先学C++呢?
C++&Builder的VCL、Visual&C++的MFC、QT都是一种类库,是基于C++的,是面向对象的。C语言没有类。
好吧,那也就是说要想用QT,前提也要会C++?
对的,C++是一个必攻的中途岛,然后可以分支。
我大学的时候一个NB师兄用纯C写了一个DOS下的编辑器,类似于TC那样,非常漂亮,支持自定义的汇编代码格式整理。非常N&B。那时还是win98的时代。
我大学的时候一个NB师兄用纯C写了一个DOS下的编辑器,类似于TC那样,非常漂亮,支持自定义的汇编代码格式整理。非常N&B。那时还是win98的时代。
DOS下写个下拉菜单界面都很不容易。
我大学的时候一个NB师兄用纯C写了一个DOS下的编辑器,类似于TC那样,非常漂亮,支持自定义的汇编代码格式整理。非常N&B。那时还是win98的时代。
DOS下写个下拉菜单界面都很不容易。
转眼就到Windows时代了,我是Windows时代的时候出生了,不了解DOS,但是磁盘操作系统应该很强大吧?
只会写控制台,不会做界面,
我大学的时候一个NB师兄用纯C写了一个DOS下的编辑器,类似于TC那样,非常漂亮,支持自定义的汇编代码格式整理。非常N&B。那时还是win98的时代。
DOS下写个下拉菜单界面都很不容易。
转眼就到Windows时代了,我是Windows时代的时候出生了,不了解DOS,但是磁盘操作系统应该很强大吧?
DOS现在看来很简陋了。
楼主可以MFC或者Win32程序,基本上都是拖拽控件,需要你写的部分很少涉及到C++的知识。如果楼主完全用C实现例如楼主距离的Directx,写起来比较费时而已。
会不会C++啊,会的话用Qt写界面很简单的。
楼主可以MFC或者Win32程序,基本上都是拖拽控件,需要你写的部分很少涉及到C++的知识。如果楼主完全用C实现例如楼主距离的Directx,写起来比较费时而已。
会不会C++啊,会的话用Qt写界面很简单的。
我觉得楼主听#6楼说的就够了。
我觉得楼主听#6楼说的就够了。
是吗?我觉得还是34楼的好...
好像源代码是java的吧?
我觉得楼主听#6楼说的就够了。
是吗?我觉得还是34楼的好...
好像源代码是java的吧?
睁眼说瞎话!
我觉得楼主听#6楼说的就够了。
是吗?我觉得还是34楼的好...
好像源代码是java的吧?
睁眼说瞎话!
不好意思,从没下载过源码,我在你给的官网地址上下载了一隔压缩包,源代码在哪额。。
师傅领进门,以后修行得咋样,就得看徒弟的主观能动性了。
推荐使用Source&Insight软件查看大型项目的源代码。
老赵的蹭分计划完败于楼主
老赵的蹭分计划完败于楼主
你知道得太多了!啪——!啊——!查看: 919|回复: 13
【提问】我需要一个简单的C++程序,谢谢大大们
阅读权限10
本帖最后由 奋斗丶小Z 于
18:44 编辑
就一个简单的C++,输入任意10个数求出最大值最小值和平均值,我没学这个不会,看了一天的书也没看懂
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限80
[C++] 纯文本查看 复制代码
#include &iostream&
int main(void)
//别问我问啥循环变量用n,dz的代码太坑爹,都是泪
int n, max, min, sum,
int num[10];
//输入过程,输入10个int,这个可以根据你自己的需要定义数据类型
for(n = 0; n & 10; n++)
cin && num[n];
//给几个变量赋初值
max = num[0];
min = num[0];
//对每一个数字做处理,比max大的记为max,比min小的记为min,并做累加
for(n = 0; n & 10; n++){
if(num[n] & max)
max = num[n];
if(num[n] & min)
min = num[n];
sum += num[n];
//最后根据sum计算平均值,额,忘记可能是小数了,结果取整吧,反正是个例程
avg = sum / 10;
//输出结果
cout && &max = & && max &&
cout && &min = & && min &&
cout && &sum = & && sum &&
cout && &avg = & && avg &&
目测应该能正常跑,人肉编译器编译通过,以及楼上说要排序的,貌似只要输出最大最小值就好了吧?
热心加上~~
虽然简单 但没几个像您这么认真答的
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
int max_value, min_
for (int i = 0; i & 10; i++) {
& & if (0 == i || *p & max_value) {
& && &&&max_value = *p;
& & if (0 == i || *p & min_value) {
& && &&&min_value = *p;
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限25
这么简单都不会,看来你还得继续看书
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
这么简单都不会,看来你还得继续看书
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
冒泡排序,继续看书
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
其实你百度更快
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限20
这个排序都不用
for(int i=1;i&10;i++)
& & if(a[i] & min)
& && && &min = a[i];
& & if(a[i] & max)
& && &&&max = a[i];
最大值最小值已经有了,其他就简单了
你的【i】居然没有变成斜体,可啪,吓得我循环变量都用了n
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
以解决呢& & 不懂C+&&路过
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
免责声明:吾爱破解所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
( 京ICP备号 | 京公网安备 87号 )
Powered by Discuz! X3.2
Comsenz Inc.程序写累了,就来玩玩酷跑小游戏吧,嘿嘿。
雨松MOMO送你一首歌曲,嘿嘿。
Unity3D研究院之Android加密DLL与破解DLL .SO(八十一)
Unity3D研究院之Android加密DLL与破解DLL .SO(八十一)
围观29491次
编辑日期: 字体:
首先要非常感谢大神提供了这么好的一篇文章,帮助我解决了1年我都没能解决的问题。其次感谢这两天微博好友给我的留言与评论。
阅读本文之前请先阅读大神的这篇。
我做的时候有些细节不太一样。一样的地方我就不写了,我把不一样的地方写出来。
加密DLL首先要找准unity版本对应的mono,地址在这里
这里有个很恶心的事情,unity的mono版本并不是按小版本分的,比如我想找unity4.6.1 对应的mono那么它就没有,unity只提供4.3x 或者 4.6x 或者5.1x 这种大版本的mono .从提交时间上来看更新的很随意啊。我感觉要想找到对应的unity版本,可以根据unity这个版本发布的时候,然后在github上找对应时间的mono版本。。
如下图所示,打开网页后,找到对应的branches版本, 这里选择unity-4.6 或者 unity-5.1 这两个版本我已经测试通过。别的版本希望大家都能来参与测试。
在说说说恶心的地方,我下载4.6以后,把mono编译出来。放在unity4.6.1的打出来的包里 死活会报错, 但是4.6.6就没问题了。。 不过还好我这里两个项目 一个是用unity4.6.6还有一个是unity5.1.1目前都没出现问题。
下面我都用unity4.6举例,其他版本原理都一样我就不赘述了。
1.github下载下来对应的mono解压放在本地,在终端里先cd到这个目录下。
2.把打包脚本拖入终端中(注意脚本的路径),然后就开始耐心等待吧。估计5分钟左右就OK了。
3.打包脚本分两种, 一个是 arm的,还有一个是x86,执行build_runtime_android.sh 就可以了, 它会自动调用
build_runtime_android_x86.sh。
打包脚本我们需要改一下,因为下载下来的脚本直接运行打的是debug版本,效果就是打出来的.so比unity自带的大很多。我们要改成release版本。
如下图所示,左边是x86,右边是arm。把CFLAGS里的-g改成-O2 (O0 ,O1,O2,OS,O3分了好几个压缩档次,我觉得O2就可以了)然后在LDFLAGS里加上-Wl,–gc-sections \ 就行了。
注意:今天同事说x86下有些手机进游戏卡死。后来经过一番分析,原来是x86的编译选项和arm不一样。如下图所示,在X86.sh 这里只把-g去掉就行。。别的什么都别改。切记切记!!!
然后在下面把这两句代码注释掉,不然编译的时间就要增加了。
#clean_build “$CCFLAGS_ARMv5_CPU” “$LDFLAGS_ARMv5” “$OUTDIR/armv5”
#clean_build “$CCFLAGS_ARMv6_VFP” “$LDFLAGS_ARMv5” “$OUTDIR/armv6_vfp”
在打mono.so前记得改一下解密算法。因为在测试所以解密和加密算法我们就写简单一点。如下图所示,mono/metadata/image.c里面找到 mono_image_open_from_data_width_name 。 因为我只会对自己写的c#编译后的dll加密,所以这里判断一下是否是我们自己的dll,解密算法很简单就是让字节下标为1的字节-1。
如果你要热更DLL时一定要注意!!这里一定要先判断一下name是否为NULL 不然使用System.Reflection.Assembly.Load
在Android平台反射调用DLL的时候unity 会挂的。
if(name != NULL) {
if(strstr(name,"Assembly-CSharp.dll")){&&&&&&&&&&&&&&&&&&&&&& data[0]-=1
还有如果想在 mono里打印Log的话可以使用
#include &glib.h&
g_message(“momo: %s”,str);
OK 然后开始编译mono吧。arm 和x86 两个大概 5 分钟左右就能编译完成。对应会会放在mono根目录build的文件夹里。然后回到生成的adnroid工程中,把libmono.so 分别放在x86和armeabi-v7a文件夹下。因为我项目用了slua所以这里也会有一些第三方的.so
再说说自动化的问题,DLL每次代码变更都会重新生成一个新的,那么我总不能每次都手动加密DLL然后在手动的拷贝到assets下面吧。。
再说一句,我的项目在处理自动化打包时用的是adnroid的ant打包。也就是先把unity导出成一个android 工程。然后在打包。所以我的自动化就可以是当android工程生成后,然后把dll读取到内存里,加密后在重新写到原来工程的位置上。如果有朋友不太懂自动化,可以在我博客里搜索一下,以前我有写过。
环境变量如果你不会加的话,也可以看我这篇文章。
这段代码的意思就是当eclipse的android工程生成后,紧接着就给dll加密。。字节一变那么Dll其实就变成了一个普通的二进制文件。这样用各种反编译Dll的工具就都打不开了。
1234567891011121314151617181920212223
//shell脚本来自动调用unity中的这个c#方法 static void ExportAndroidProject()?
List&string& args = GetArgs("ExportAndroidProject");? ?
if (string.IsNullOrEmpty (BuildPipeline.BuildPlayer (GetBuildScenes (), args [0], BuildTarget.Android, BuildOptions.AcceptExternalModificationsToPlayer)))
encryptDll (args [0]);?
static private void encryptDll(string path)?
//DLL在android工程中对应的位置?
string inpath = path +"/"+ PlayerSettings.productName +"/assets/bin/Data/Managed/Assembly-CSharp.dll";?
if(File.Exists(inpath)){&&&&&&
//先读取没有加密的dll?
byte[] bytes = File.ReadAllBytes (inpath); ?
//字节偏移 DLL就加密了。
bytes [0] += 1;
//在写到原本的位置上?
File.WriteAllBytes (inpath, bytes);?
然后还有前面我们编译出来的两个 mono.so 也要在这里自动化一并拷贝到这个工程对应的目录下面(可以在shell里拷贝,也可以在C#里拷贝)。 接下来就调用自动打包apk就行了。。总之最后的效果就是Dll不能被解开了。如下图所示。
但是,高兴的别太早。DLL是解不开了,但是你的解密算法是写在.so里面的,那么对方反编译你的.so取出解密算法,随便写个小工具就可以把你的DLL逆向回来。。
在windows上下载ida pro 神器(真是道高一尺魔高一丈啊)。
然后打开我们编译的libmono.so
找到mono_image_open_from_data_width_name 方法,然后点击F5 解密算法就破解了。(下面我找到了一个避免破解的方法,在本文的最后)
怎样才能避免别人这么容易破解你的DLL呢?请看我的下一篇文章
本文固定链接:
转载请注明:
雨松MOMO提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
如果您愿意花10块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。
您可能还会对这些文章感兴趣!在日常工作中,经常需要使用随机算法。比如面对大量的数据, 需要从其中随机选取一些数据来做分析。 又如在得到某个分数后, 为了增加随机性, 需要在该分数的基础上, 添加一个扰动, 并使该扰动服从特定的概率分布。本文主要从这两个方面出发, 介绍一些算法, 供大家参考。
首先假设我们有一个使用的随机函数float frand(), 返回值在(0, 1)上均匀分布。大多数的程序语言库提供这样的函数。 在其他的语言如C/C++中, 可以通过间接方法得到。如 frand()= ((float)rand() ) / RAND_MAX;
1, 随机选取数据
假设我们有一个集合A(a_1,…,a_n), 对于数m,0≤m≤n, 如何从集合A中等概率地选取m个元素呢?
通过计算古典概率公式可以得到, 每个元素被选取的概率为m/n。 如果集合A里面的元素本来就具有随机性, 每个元素在各个位置上出现的概率相等, 并且只在A上选取一次数据,那么直接返回A的前面m个元素就可以了, 或者可以采取每隔k个元素取一个等类似的方法。这样的算法局限很大, 对集合A的要求很高, 因此下面介绍两种其他的算法。
1.1 假设集合A中的元素在各个位置上不具有随机性, 比如已经按某种方式排序了,那么我们可以遍历集合A中的每一个元素a_i, 0&=n 根据一定的概率选取ai。如何选择这个概率呢?
设m’为还需要从A中选取的元素个数, n’为元素a_i及其右边的元素个数, 也即n’=(n-i+1)。那么选取元素a_i的概率为 m’/n’。
由于该算法的证明比较繁琐, 这里就不再证明。
我们简单计算一下前面两个元素(2&=m&=n)各被选中的概率。
1) 设p(a_i=1)表示a_i被选中的概率。显而易见, p(a_1=1)=m/n, p(a_1=0)为(n-m)/n;
2)第二个元素被选中的概率为
p(a_2=1)= p(a_2=1,a_1=1)+p(a_2=1,a_1=0)
= p(a_1=1)*p(a_2=1│a_1=1)+ p(a_1=0)* p(a_2=1│a_1=0)
m/n * (m-1)/(n-1) + (n-m)/n*m/(n-1)
我们用c++语言, 实现了上述算法
template&class T&
bool getRand(const vector&T& vecData, int m, vector&T&& vecRand)
int32_t nSize = vecData.size();
& m || m & 0)
vecRand.clear();
vecRand.reserve(m);
for(int32_t i = 0, isize = nS i & i++){
float fRand = frand();
if(fRand &=(float)(m)/nSize){
vecRand.push_back(vecData[i]);
利用上述算法, 在m=4, n=10, 选取100w次的情况下, 统计了每个位置的数被选取的概率
还有很多其他算法可以实现这个功能。比如对第i个数, 随机的从a_i, …, a_n中, 取一个数和a_i交换。这样就不单独介绍了。
1.2 在有些情况下,我们不能直接得到A的元素个数。比如我们需要从一个很大的数据文件中随机选取几条数据出来。在内存不充足的情况下,为了知道我们文件中数据的个数, 我们需要先遍历整个文件,然后再遍历一次文件利用上述的算法随机的选取m个元素。
又或者在类似hadoop的reduce方法中, 我们只能得到数据的迭代器。我们不能多次遍历集合, 只能将元素存放在内存中。 在这些情况下, 如果数据文件很大, 那么算法的速度会受到很大的影响, 而且对reduce机器的配置也有依赖。
这个时候,我们可以尝试一种只遍历一次集合的算法。
取前m个元素放在集合A’中。
对于第i个元素(i&m), 使i在 m/i的概率下, 等概率随机替换A’中的任意一个元素。直到遍历完集合。
下面证明在该算法中,每一个元素被选择的概率为m/n.
当遍历到到m+1个元素时, 该元素被保存在A’中的概率为 m/(m+1), 前面m个元素被保存在A’中的概率为 1- (m/m+1 * 1/m) = m/m+1
当遍历到第i个元素时,设前面i-1个元素被保存在A’中的概率为 m/(i-1)。根据算法, 第i个元素被保存在A’中的概率为m/i , 前面i-1各个元素留在A’中的概率为 m/(i-1) * (1-(m/i* 1/m) = m/i;
通过归纳,即可得到每个元素留在A’中的概率为 m/n;
我们在类似 hadoop的reduce函数中, 用java实现该算法。
public void reduce(TextPair key, Iterator value, OutputCollector collector, int m)
Text[] vecData = new Text[m];
int nCurrentIndex = 0;
while(value.hasNext()){
Text tValue = value.next();
if(nCurrentIndex & m){
vecData[nCurrentIndex] = tV
else if(frand() & (float)m / (nCurrentIndex+1)) {
int nReplaceIndex = (int)(frand() * m);
vecData[nReplaceIndex] = tV
nCurrentIndex ++;
//collect data
利用上述算法,在m=4, n=10, 经过100w次选取之后, 计算了每个位置被选择的选择的概率
2. 随机数的计算
在搜索排序中,有些时候我们需要给每个搜索文档的得分添加一个随机扰动, 并且让该扰动符合某种概率分布。假设我们有一个概率密度函数f(x), min&=x&=max, 并且有
那么可以利用f(x)和frand设计一个随机计算器r(frand()), 使得r(frand())返回的数据分布, 符合概率密度函数f(x)。
符合密度函数为f(x)的分布。
下面对这个以上的公式进行简单的证明:
由于g(x)是单调函数, 并且x在[0,1]上均匀分布,那么
由于上述公式太复杂, 计算运算量大, 在线上实时计算的时候通常采用线性差值的方法。
1)在offline计算的时候, 设有数组double A[N+1];对于所有的i, 0&=i&=N, 令
2)在线上实时计算的时候,
令f = frand(),
lindex = (int) (f* N);
rindex = lindex +1;
那么线性插值的结果为 A[lindex]*(A[rindex]-f) + A[rindex] * (f – A[lindex])
我们做了一组实验,令f(x)服从标准正太分布N(0,1), N=10000, 并利用该算法取得了200*N个数。对这些数做了个简单的统计, 得到x轴上每个小区间的概率分布图。
在日常工作中, 还有其他一些有趣的算法。比如对于top 100w的query, 每个query出现的频率不一样, 需要从这100w个query, 按照频率越高, 概率越高的方式随机选择query。限于篇幅, 就不一一介绍了。
ps: 谢谢大家在评论中指出了程序上的一些错误。今天一并改正了。
这个看起来都有点难度呵。
A quality product by}

我要回帖

更多关于 如何编程序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信