在《程式設計珠璣,第二版》和《程式設計之美》中都有關於交換兩段連續的記憶體塊的題目,而且非常經典,交換兩段連續記憶體塊的問題又可以延伸到交換兩段不連續記憶體塊的問題,無論是哪種情況都需要乙個基本操作:
反轉記憶體塊。
反轉記憶體時,比較簡單,可以兩個指標同時走,也可以乙個指標,隨意,實現如下: 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中能看到...