SOGO論壇
  登入   註冊   找回密碼
查看: 503|回覆: 0
列印 上一主題 下一主題

[技術文章] Array — 動態陣列 [複製連結]

Rank: 11Rank: 11Rank: 11Rank: 11

熱心參予論壇活動及用心回覆主題勳章 數位硬體勳章

狀態︰ 離線
跳轉到指定樓層
1
發表於 2012-7-11 00:20:14 |只看該作者 |倒序瀏覽

檔案:Array.h

#ifndef ARRAY_H
#define ARRAY_H

#include "Lib.h"

typedef struct {
  int size;    // 陣列目前的上限
  int count;   // 陣列目前的元素個數
  void **item; // 每個陣列元素的指標
} Array;       // 動態陣列的資料結構

typedef enum { KEEP_SPLITER, REMOVE_SPLITER } SplitMode;

extern void ArrayTest();

extern Array* ArrayNew(int size);// 建立新陣列
extern void ArrayFree(Array *array, FuncPtr1 freeFuncPtr); // 釋放該陣列
extern void ArrayAdd(Array *array, void *item); // 新增一個元素
extern void ArrayPush(Array *array,void *item); // (模擬堆疊) 推入一個元素
extern void* ArrayPop(Array *array);  //(模擬堆疊) 彈出一個元素  
extern void* ArrayPeek(Array *array); //(模擬堆疊) 取得最上面的元素
extern void* ArrayLast(Array *array); // 取得最後一個元素
extern void ArrayEach(Array *array, FuncPtr1 f); //對每個元素都執行 f 函數

extern Array* split(char *str, char *spliter, SplitMode mode);

#endif

檔案:Array.c

#include <stdlib.h>
#include <string.h>
#include "Array.h"

void ArrayTest() {
  char *names[] = { "John", "Mary", "George", "Bob" };
  Array *array = ArrayNew(1);
  int i;
  for (i=0; i<4; i++)
    ArrayAdd(array, names[i]);
  ArrayEach(array, strPrintln);
  printf("ArrayPop()=%s\n", ArrayPop(array));
  printf("ArrayLast()=%s\n", ArrayLast(array));
  for (i=0; i<4; i++) {
    int arrayIdx = ArrayFind(array, names[i], strcmp);
    printf("ArrayFind(%s)=%d\n", names[i], arrayIdx);
  }
  ArrayEach(array, strPrintln);
  ArrayFree(array, NULL);
}

Array* ArrayNew(int size) {
  Array *array = ObjNew(Array, 1);
  array->count = 0;
  array->size = size;
  array->item = ObjNew(void*, array->size);
  return array;
}

void ArrayFree(Array *array, FuncPtr1 freeFuncPtr) {
  if (array == NULL) return;
  if (freeFuncPtr != NULL)
    ArrayEach(array, freeFuncPtr);
  ObjFree(array->item);
  ObjFree(array);
}

void ArrayAdd(Array *array, void *item) {
  ASSERT(array->count <= array->size);
  if (array->count == array->size) {
    int newSize = array->size*2;
    void **newItems = ObjNew(void*, newSize);
    memcpy(newItems, array->item, array->size*sizeof(void*));
//  printf("array grow from %d to %d\n", array->count, newSize);
    ObjFree(array->item);
    array->item = newItems;
    array->size = newSize;
  }
  array->item[array->count++] = item;
//printf("add item = %s\n", item);
}

void ArrayPush(Array *array, void *item) {
  ArrayAdd(array, item);
}

void* ArrayPop(Array *array) {
  ASSERT(array->count>0);
  return array->item[--(array->count)];
}

void* ArrayPeek(Array *array) {
  return ArrayLast(array);
}

void* ArrayLast(Array *array) {
  ASSERT(array->count > 0);
  return array->item[array->count-1];
}

Array* split(char *str, char *spliter, SplitMode mode) {
  Array *tokens = ArrayNew(10);
  int si, tokenCount=0;
  int begin=0, ti = 0;
  for (si=0; si<=strlen(str); si++) {
      if (str[si]=='\0' || strMember(str[si], spliter)) {
        int len = si-begin;
        if (len > 0)
          ArrayAdd(tokens, newSubstr(str, begin, len));
        if (mode == KEEP_SPLITER)
          ArrayAdd(tokens, newSubstr(str, si, 1));
//      printf("token1=%s token2=%s\n", tokens->item[ti-2], tokens->item[ti-1]);
        begin = si+1;
      }
  }
  return tokens;
}

int ArrayFind(Array *array, void *data, FuncPtr2 fcmp) {
  int i;
  for (i=0; i<array->count; i++)
    if (fcmp(array->item[i], data)==0)
      return i;
  return -1;
}

void ArrayEach(Array *array, FuncPtr1 f) {
  int i;
  for (i=0; i<array->count; i++)
    f(array->item[i]);
}

喜歡嗎?分享這篇文章給親朋好友︰
               感謝作者     

請注意︰利用多帳號發表自問自答的業配文置入性行銷廣告者,將直接禁訪或刪除帳號及全部文章!
您需要登錄後才可以回覆 登入 | 註冊


本論壇為非營利自由討論平台,所有個人言論不代表本站立場。文章內容如有涉及侵權,請通知管理人員,將立即刪除相關文章資料。侵權申訴或移除要求:abuse@oursogo.com

GMT+8, 2025-2-11 17:17

© 2004-2025 SOGO論壇 OURSOGO.COM
回頂部