交換兩段連續 不連續 記憶體《轉》

2021-06-26 20:54:23 字數 2565 閱讀 9175

在《程式設計珠璣,第二版》和《程式設計之美》中都有關於交換兩段連續的記憶體塊的題目,而且非常經典,交換兩段連續記憶體塊的問題又可以延伸到交換兩段不連續記憶體塊的問題,無論是哪種情況都需要乙個基本操作:

反轉記憶體塊。

反轉記憶體時,比較簡單,可以兩個指標同時走,也可以乙個指標,隨意,實現如下: 01

// reverse the memory block

02// goal: |12345| -> |54321|

03void

*reversememory

(void

*pmemory

,const

size_t

memsize)04

16return

pmemory;17

}其中,函式的兩個形參分別為要反轉記憶體的起始位址和記憶體塊的大小。返回值型別為void*,指向反轉記憶體塊的起始位址。

實現了反轉記憶體塊這一基本操作後,我們就可以用它來交換兩段連續的記憶體,從而解決類似「陣列迴圈移位」的問題。具體演算法在程式設計珠璣和程式設計之美中都有詳細介紹,這裡簡單說一下:

假設有連續的記憶體塊m和n形如:|----m---|--------n---------|

首先反轉記憶體塊m:m』=reverse(m)

反轉記憶體塊n:n』=reverse(n)

對整個記憶體塊m』 n』進行反**(m』n』)』 = nm

舉例:m=」abc」, n=」1234」

m』=reverse(m)=」cba」

n』=reverse(n)=」4321」

(m』n』)』=(cba4321)』=」1234abc」

實現如下: 01

// swap two adjacent memory block

02// goal: |*****|######|  -> |######|*****|

03void

*swapadjacentmemory

(void

*pmemory

,const

size_t

headsize

,const

size_t

totalsize)04

函式的形參為記憶體起始位址pmemory、頭長度headsize和記憶體總長度totalsize,其中headsize就相當於「陣列迴圈移位問題」中移位大小,如右移4位等同於headsize為4。

現在我們明白了如何交換兩段連續的記憶體,那麼如何交換兩段不連續的記憶體呢?

形如:有記憶體man三塊:|----m---|----a----|-----n------|,我們要交換m,n,保持a不動。

類似於交換兩段連續記憶體,仔細地想一下並不難,演算法如下:

反轉記憶體塊m:m』=reverse(m)

反轉a:a』=reverse(a)

反轉n:n』=reverse(n)

反轉m』a』n』:(m』a』n』)』=nam

實現如下: 01

// swap two nonadjacent memory block

02// goal: |*****|$$$$|######|  -> |######|$$$$|*****|

03void

*swapnonadjacentmemory

(void

*pmemory

,const

size_t

headsize

,const

size_t

endsize

,const

size_t

totalsize)04

實現之後,我們寫乙個測試用例來驗證一下:

01#include

02using

namespace

std;

0304

#define maxbuffersize 100

0506

void

main

()07;18

19void

*resultarr

=malloc

(maxbuffersize

);// store the test result

20if

(null

==resultarr

)return;21

22size_t

arrlen

=sizeof

(stringarr)/

sizeof(*

stringarr

);23

24// test swapadjacentmemory |

25for

(size_ti=

0;i<

arrlen;++

i)2632

33// test swapnonadjacentmemory

34for

(size_ti=

0;i<

arrlen;++

i)3541

42free

(resultarr

);43

}反轉記憶體 & 交換記憶體 這一操作很重要,後面的文章我們會看到其靈活運用的效果。

注:該文參考整理而來,感謝houdy!

記憶體反轉以及交換兩段連續 不連續 記憶體

在 程式設計珠璣,第二版 和 程式設計之美 中都有關於交換兩段連續的記憶體塊的題目,而且非常經典,交換兩段連續記憶體塊的問題又可以延伸到交換兩段不連續記憶體塊的問題,無論是哪種情況都需要乙個基本操作 反轉記憶體塊。當遇到系統網路傳輸出現大小端不一致時,拼資料幀或者解資料幀的時候需要對不同的資料型別進...

求乙個陣列的兩段連續的部分的最大和

求乙個陣列的兩段連續的部分的最大和,例如1,2,2,3,4,結果就是6,第一段就是1,第二段就是2,3。而陣列 2,3,1,2,5,6,7,3,4,9,2,1,第一段是3,1,2,第二段是7,3,4,結果就是12。這個其實就是陣列最大連續和的擴充套件問題,經典dp問題。求最大連續和並不難,我們只需要...

N76E003編譯陣列記憶體不連續的問題

編譯的時候關閉外部編輯器,不然可能有記憶體共用問題。我使用keil c51編譯n76e003發現陣列記憶體不連續問題,這裡特意記錄下來。編譯情況 乙個16位的陣列,前3個元素是連續的位址,從第4個開始,出現不連續。用指標取陣列每乙個元素的位址能看出來。但是,debug直接把陣列放到watch中能看到...