2010-09-19 7 views
12

iOS/Objective-C: Tôi có một mảng lớn các giá trị boolean.Làm cách nào để triển khai mảng bit trong C/Objective C

Đây là cách không hiệu quả để lưu trữ các giá trị này - ít nhất tám bit được sử dụng cho mỗi phần tử khi chỉ cần một bit.

Tôi làm cách nào để tối ưu hóa?

+1

có bạn đã cố gắng tìm kiếm để xem nếu ai đó đã viết một cái gì đó bạn có thể sử dụng không? Mọi người sẽ không viết mã cho bạn. –

+2

Tôi đã thực sự cố gắng chia sẻ một số mã tôi đã viết bằng cách đặt câu hỏi và trả lời nó, nhưng trang web này quá nhanh !!! trong vòng 10 phút nó đã đưa tôi đến lắp ráp câu trả lời của tôi, đã có hai câu trả lời đã xuất hiện! –

+0

SO không có nghĩa là đăng các câu hỏi mà bạn có thể tự trả lời. Và thậm chí sau đó bạn có thể xem xét tìm hiểu những gì tồn tại trên chủ đề trên web và so sánh cách tiếp cận của bạn với những gì bạn tìm thấy, trước tiên. –

Trả lời

14

thấy CFMutableBitVector/CFBitVector cho một lựa chọn CFType

+2

http://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFBitVectorRef/Reference/reference.html – JeremyP

+0

Nhưng những lớp này lưu trữ các đối tượng CFBit, được gõ vào inte 32 bit. Vì vậy, giải pháp này lãng phí chỉ là bộ nhớ nhiều. –

+8

@whitman các giá trị được chuyển thành CFBit; điều đó không có nghĩa là chúng được lưu trữ * như vậy. tôi chỉ nhìn vào việc thực hiện CFBitVector (r.550.13). mức tiêu thụ bộ nhớ là một chút, trong khi kích thước phân bổ được làm tròn lên đến một số chia hết cho 64. một tổng thể thực hiện rất thận trọng. – justin

6

Bạn sử dụng các phép toán logic bit và dịch chuyển bit. (A tìm kiếm Google cho những điều khoản này có thể cung cấp cho bạn một số ví dụ.)

Về cơ bản bạn khai báo một kiểu số nguyên (bao gồm cả int, char, vv), sau đó bạn "thay đổi" giá trị số nguyên để bit mà bạn muốn, sau đó bạn làm một OR hoặc một AND với số nguyên.

Một số ví dụ minh họa nhanh chóng (trong C++):

inline bool bit_is_on(int bit_array, int bit_number) 
{ 
    return ((bit_array) & (1 << bit_number)) ? true : false; 
} 

inline void set_bit(int &bit_array, int bit_number) 
{ 
    bit_array |= (1 << bit_number); 
} 

inline void clear_bit(int &bit_array, int bit_number) 
{ 
    bit_array &= ~(1 << bit_number); 
} 

Lưu ý rằng điều này cung cấp "mảng chút" kích thước không đổi (sizeof(int) * 8 bit). Có lẽ điều đó là tốt cho bạn, hoặc có thể bạn sẽ muốn xây dựng một cái gì đó trên đầu trang này. (Hoặc sử dụng lại bất kỳ thư viện nào cung cấp.)

Điều này sẽ sử dụng ít bộ nhớ hơn bool mảng ... Mã trình biên dịch tạo ra để truy cập các bit này sẽ lớn hơn và chậm hơn. Vì vậy, trừ khi bạn có một số lượng lớn các đối tượng cần chứa các mảng bit này, nó có thể có tác động tiêu cực ròng đến cả tốc độ và mức sử dụng bộ nhớ.

+1

Câu hỏi không được gắn thẻ C++. Có lẽ bạn nên chuyển đổi mã của bạn thành C. – JeremyP

+2

@JeremyP - Đó là một ví dụ minh họa. Tôi quyết định sử dụng tài liệu tham khảo thay vì con trỏ vì tôi nghĩ rằng nó sẽ phân tâm ít hơn từ câu hỏi được hỏi. Tôi nghĩ rằng điểm đã qua OK, và câu trả lời là không có nghĩa là để được sao chép dán vào giải pháp của ai đó anyway. – asveikau

+4

câu hỏi là về C. Người hỏi có thể thậm chí không biết tham chiếu là gì. Nếu đó là trường hợp, bạn đã không phân tâm ít hơn, bạn đã mất tập trung hơn. – JeremyP

11

Hãy thử điều này:

#define BITOP(a,b,op) \ 
((a)[(size_t)(b)/(8*sizeof *(a))] op ((size_t)1<<((size_t)(b)%(8*sizeof *(a))))) 

Sau đó, đối với bất kỳ mảng của các yếu tố nguyên unsigned không lớn hơn size_t, các BITOP vĩ mô có thể truy cập vào các mảng như một mảng bit . Ví dụ:

unsigned char array[16] = {0}; 
BITOP(array, 40, |=); /* sets bit 40 */ 
BITOP(array, 41, ^=); /* toggles bit 41 */ 
if (BITOP(array, 42, &)) return 0; /* tests bit 42 */ 
BITOP(array, 43, &=~); /* clears bit 43 */ 

, vv

+1

Và thay thế số 8 bằng 'CHAR_BIT' nếu bạn quan tâm đến tính di động hoàn chỉnh đối với bất kỳ môi trường C. –

+0

Trên thực tế, 8 hoạt động tốt ở bất cứ nơi nào nếu bạn không nhớ lãng phí bit trên nền tảng nơi 'CHAR_BIT> 8', và nó sẽ cho hiệu suất tốt hơn so với giới thiệu những thứ như chia 9 hoặc 10 ... –

+0

Để hỗ trợ hoạt động rõ ràng & = ~ đó là hai toán tử, & = và ~, bạn cần phải bọc nửa sau của macro trong một bộ parens khác. Nếu không, bạn viết một cái gì đó bạn không có ý định. '#define BITOP (a, b, op) ((a) [(size_t) (b)/(8 * sizeof * (a))] op ((size_t) 1 << ((size_t) (b)% (8 * sizeof * (a))))) ' –

0

Tôi đã xem qua câu hỏi này như tôi đang viết một chút khuôn khổ mảng đó là ý định để quản lý một lượng lớn 'bit' tương tự như Java BitSet. Tôi đang tìm xem liệu cái tên mà tôi quyết định có xung đột với các khung Objective-C khác không.

Dù sao, tôi chỉ mới bắt đầu điều này và quyết định xem có đăng nó trên SourceForge hoặc các trang web lưu trữ nguồn mở khác không.

Hãy cho tôi biết nếu bạn quan tâm

Edit: Tôi đã tạo dự án, được gọi là BitArray, trên SourceForge. Nguồn nằm trong kho lưu trữ SF SVN và tôi cũng đã tải lên một khung công tác đã biên dịch. Điều này LINK sẽ nhận được của bạn ở đó.

  • Frank
2
#define BITOP(a,b,op) \ 
    ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a)))) 

sẽ không làm việc ...

Fix:

#define BITOP(a,b,op) \ 
((a)[(size_t)(b)/(8*sizeof *(a))] op ((size_t)1<<((size_t)(b)%(8*sizeof *(a)))))