欢迎来到第一文库网! | 帮助中心 第一文库网-每个人都是第一
第一文库网
全部分类
  • 研究报告>
  • 学术论文>
  • 全科教育>
  • 应用文档>
  • 行业资料>
  • 企业管理>
  • 技术资料>
  • 生活休闲>
  • ImageVerifierCode 换一换
    首页 第一文库网 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

    交换不连续的两个内存块.docx

    • 资源ID:1121437       资源大小:21.17KB        全文页数:6页
    • 资源格式: DOCX        下载积分:10金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: QQ登录 微博登录
    二维码
    扫码关注公众号登录
    下载资源需要10金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    交换不连续的两个内存块.docx

    交换不连续的两个内存块Io假设有两段连续的内存块a和b;2首先对内存块a进行反转:a,=reverse(a);3o接着对内存块b进行反转:b,=reverse(b);3o最后对内存块ab进行反转:(aby=ba;是不是很神奇?当我第一次看到这个算法的时候,我就惊叹为什么这三步简单的操作就能解决看似很复杂的问题?如果你还不相信的话(我一开始和你一样也是不相信),请看下面的例子:Io假如有两段连续的内存块,a内存块的内容是匕bed”,b内存块的内容是“efgh”;2o首先对内存块a进行反转:a,=reverse(nabcd")=',dcba,'3o接着对内存块b进行反转:b,=reverse(',efgh")=",hgfe"4o最后对内存块a'b'进行反转:(a,b,),=reverse(1,dcbahgfen)=efghabcd;那”reversa1a1gorithm”和本文中需要解决的问题有什么联系呢?在看到这个问题的时候,我就立即联想到了“reversa1a1gorithm",我试图通过已有的方法去解决类似的问题。幸运的是经过简单的分析和推论,我就找到了一个简单的方法,这个方法只要对“reversa1a1gorithm”进行简单的修改就可以解决本文的问题:1假设有三段连续的内存a,b和c,这样a和C是不连续的;2首先对内存块a进行反转:a,=reverse(a);3接着对内存块b进行反转:b'=reverse(b);4接着对内存块c进行反转:c,=reverse(c);5最后对内存块a'bc进行反转:reverse(a'b'c')=cba;是不是超简单?这里使用了和"reversa1a1gorithm”一样的思路。最后一次反转,不仅分别将内存块a和c中的数据调整为初始状态,而且还交换它们的位置。由于内存块b处于中间的位置,最后一次反转只将它的内容调整到初始状态。实现篇有了上面的分析,编写代码实现这个算法就显得相对比较简单了:Io首先我们需要一个反转内存块的函数。这个函数应该说比较简单:/*/IIIIIII/swaponeadjacentmemoryb1ock/Thememory1ayout1ikethis:/11/memTota1Size/RETURNVA1UE:Theaddressofthememoryjustbeingswappedvoid*swapMemory(void*pMemoryzsize_tmemTota1Size).if(NU11=pMemory)returnpMemory;if(memTota1Size<2)returnpMemory;unsignedchar*pByteMemory=reinterpret_cast<unsignedchar*>(pMemory);for(size_ti=O;i<memTota1Size2;i+).unsignedchartempByte=*(pByteMemory+i);*(pByteMemory+i)=*(pByteMemory+memTota1Size-1-i);*(pByteMemory+memTota1Size-1-i)=tempByte;returnpMemory;)就这个函数的实现,有以下几点需要说明:I0在函数的开始,我对函数的参数进行了一定的约束,这个在"DesignByCOntraCt”中被称作前项约束"Precondition”。相应的,在函数的最后还有一个后项约束"PoStConditiorT;在函数中间的部分,应该还有一个被称为不变式(InVariant)的东西。这些约束的目的就是保证函数在开始/中间/结束过程中处于一个正确的状态。2如果要对内存进行逐字节的访问,我们可以通过一个字符指针来完成。一个字符所占的内存空间是一个字节,它在内存块中的索引值就等于它相对于内存块首地址的偏移量。2有了上面的函数,按照本文前面的分析,我们就可以很容易实现本文的算法了:SW叩twononadjacentmemoryb1ock/Thememory1ayout1ikethis:/I111/memHeadSizememTota1Size-memHeadSize-memEndSizememEndSize/Thestart/endindexforthethreememoryb1ocksare:/Theheadb1ock:Oz(memHeadSize-1);/Themidd1eb1ock:memHeadSize,(memTota1Size-memEndSize-1);/Theendb1ock:(memTota1Size-memEndSize)z(memEndSize-1);/RETURNVA1UE:Theaddressofthememoryjustbeingswappedvoid*swapNonadjacentMemory(void*PMemOry,sizememTota1Size,size_tmemHeadSize,size_tmemEndSize).if(NU11=pMemory)returnpMemory;if(memTota1Size<3)returnpMemory;if(memTota1Size<memEndSize)returnpMemory;if(memTota1Size<(memHeadSize+memEndSize)returnpMemory;unsignedchar*pByteMemory=reinterpret_cast<unsignedchar*>(pMemory);/step1:reversetheheadb1ockswapMemory(pByteMemor½memHeadSize);/step2:reversethemidd1eb1ockswapMemory(pByteMemory+memHeadSize)1(memTota1Size-memHeadSize-memEndSize);/step3:reversetheendb1ockswapMemory(pByteMemory+memTota1Size-memEndSize)zmemEndSize);/step4:reversethewho1eb1ockswapMemory(pByteMemoryzmemTota1Size);returnpMemory;)在这个函数的前项约束中,第一个和第二个约束很好理解,第三个和第四个约束是如何得到的?一开始我也就写了前两个约束,当我写完了所有的代码后进行复查的时候,我看到了这样的函数调用:swapMemory(pByteMemory+memTota1Size-memEndSize)zmemHeadSize);如果(memTota1Size-memEndSize)小于0,那就有可能访问到不属于它的内存,这个操作是非常危险的,是绝对要禁止的,所在我们需要添加约束来避免这样的参数进入到函数的内部。接着我又在随后的代码中找到需要约束的地方:swapMemory(pByteMemory+memHeadSize)z(memTota1Size-memHeadSize-memEndSize);这里需要约束(memTota1Size-memHeadSize-memEndSize)不小于Oo经过以上的代码复查过程,我就添加了第三个和第四个前项约束。测试篇我写了一个函数用来测试本文实现的算法:voidTest_swapNonadjacentMemory()./tab1e-driventestcasestaticconstchar*testString=.I1/",ab"zabc,zabcdefghn);void*pMemory=ma11oc(MAXMEMBFFERSIZE);if(NU11=pMemory)return;for(inti=0;i<sizeof(testString)sizeof(costchar*);i+).size_tiString1ength=str1en(testStringi);/c1earthememoryb1ockmemset(pMemoryzOzMAXMEMBUFFERSIZE);/copyfromthestringmemcpy(pMemoryztestStringiziString1ength);/reversethememoryb1ockSWaPNOnadjaCemMemory(PMemory,iString1ength,3,3);)free(pMemory);)值得注意的是,这里我把所有的测试字符串都放在一个“表”中,然后用一个简单的循环语句就可以对所有的测试字符串进行测试,同时如果想修改测试字符串或者添加新的测试用例,只需要对表进行操作就可以了。后记在随后的文章中,我将使用本文的算法去解决更复杂的问题:反转一个字符串中所有单词。有兴趣的朋友也可以思考一下这个问题,据说这个问题是微软的一个面试题。参考资料Io编程珠矶,第二版本人强烈推荐此书!此书博大精深,是修炼内功的好资料。看看大家是怎么评价这本书的吧:这里还有此书的配套网站:转载:httpbenny5609archive200804252327022.aspx

    注意事项

    本文(交换不连续的两个内存块.docx)为本站会员(lao****ou)主动上传,第一文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知第一文库网(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2022 001doc.com网站版权所有   

    经营许可证编号:宁ICP备2022001085号

    本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有,必要时第一文库网拥有上传用户文档的转载和下载权。第一文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知第一文库网,我们立即给予删除!



    收起
    展开