本文介绍了如何在 C 中定义和使用位数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个非常大的数组,在上面写上0"和1".我试图模拟一个称为随机顺序吸附的物理过程,其中长度为 2 的单位,二聚体,在随机位置沉积到 n 维晶格上,彼此不重叠.当晶格上没有更多空间用于沉积更多二聚体(晶格被堵塞)时,该过程停止.

I want to create a very large array on which I write '0's and '1's. I'm trying to simulate a physical process called random sequential adsorption, where units of length 2, dimers, are deposited onto an n-dimensional lattice at a random location, without overlapping each other. The process stops when there is no more room left on the lattice for depositing more dimers (lattice is jammed).

最初我从零点阵开始,二聚体由一对1"表示.随着每个二聚体的沉积,二聚体左侧的位点被封闭,因为二聚体不能重叠.所以我通过在晶格上放置三重1"来模拟这个过程.我需要多次重复整个模拟,然后计算平均覆盖率.

Initially I start with a lattice of zeroes, and the dimers are represented by a pair of '1's. As each dimer is deposited, the site on the left of the dimer is blocked, due to the fact that the dimers cannot overlap. So I simulate this process by depositing a triple of '1's on the lattice. I need to repeat the entire simulation a large number of times and then work out the average coverage %.

我已经使用一维和二维晶格的字符数组完成了这项工作.目前,在处理 3D 问题和更复杂的概括之前,我正在尝试使代码尽可能高效.

I've already done this using an array of chars for 1D and 2D lattices. At the moment I'm trying to make the code as efficient as possible, before working on the 3D problem and more complicated generalisations.

这基本上是一维代码的样子,简化了:

This is basically what the code looks like in 1D, simplified:

int main()
{
    /* Define lattice */
    array = (char*)malloc(N * sizeof(char));

    total_c = 0;

    /* Carry out RSA multiple times */
    for (i = 0; i < 1000; i++)
        rand_seq_ads();

    /* Calculate average coverage efficiency at jamming */
    printf("coverage efficiency = %lf", total_c/1000);

    return 0;
}

void rand_seq_ads()
{
    /* Initialise array, initial conditions */
    memset(a, 0, N * sizeof(char));
    available_sites = N;
    count = 0;

    /* While the lattice still has enough room... */
    while(available_sites != 0)
    {
        /* Generate random site location */
        x = rand();

        /* Deposit dimer (if site is available) */
        if(array[x] == 0)
        {
            array[x] = 1;
            array[x+1] = 1;
            count += 1;
            available_sites += -2;
        }

        /* Mark site left of dimer as unavailable (if its empty) */
        if(array[x-1] == 0)
        {
            array[x-1] = 1;
            available_sites += -1;
        }
    }

    /* Calculate coverage %, and add to total */
    c = count/N
    total_c += c;
}

对于我正在做的实际项目,它不仅涉及二聚体,还涉及三聚体、四聚体以及各种形状和大小(用于 2D 和 3D).

For the actual project I'm doing, it involves not just dimers but trimers, quadrimers, and all sorts of shapes and sizes (for 2D and 3D).

我希望我能够处理单个位而不是字节,但我一直在阅读,据我所知,一次只能更改 1 个字节,所以要么我需要做一些复杂的索引还是有更简单的方法?

I was hoping that I would be able to work with individual bits instead of bytes, but I've been reading around and as far as I can tell you can only change 1 byte at a time, so either I need to do some complicated indexing or there is a simpler way to do it?

感谢您的回答

推荐答案

如果我还不算太晚,这个 页面给出了很棒的例子解释.

If I am not too late, this page gives awesome explanation with examples.

int 数组可用于处理bits 数组.假设 int 的大小为 4 bytes,当我们谈论 int 时,我们处理的是 32 bits.假设我们有int A[10],表示我们正在处理10*4*8 = 320 bits,下图显示:(数组的每个元素有4个大块,每个块代表一个byte,每个较小的块代表一个bit)

An array of int can be used to deal with array of bits. Assuming size of int to be 4 bytes, when we talk about an int, we are dealing with 32 bits. Say we have int A[10], means we are working on 10*4*8 = 320 bits and following figure shows it: (each element of array has 4 big blocks, each of which represent a byte and each of the smaller blocks represent a bit)

因此,要设置数组 A 中的 k 位:

So, to set the kth bit in array A:

// NOTE: if using "uint8_t A[]" instead of "int A[]" then divide by 8, not 32
void  SetBit( int A[],  int k )
{
    int i = k/32;        //gives the corresponding index in the array A
    int pos = k%32;      //gives the corresponding bit position in A[i]

    unsigned int flag = 1;   // flag = 0000.....00001

    flag = flag << pos;      // flag = 0000...010...000   (shifted k positions)

    A[i] = A[i] | flag;      // Set the bit at the k-th position in A[i]
}

或缩短版

void  SetBit( int A[],  int k )
{
    A[k/32] |= 1 << (k%32);  // Set the bit at the k-th position in A[i]
}

类似于清除 k 位:

void  ClearBit( int A[],  int k )
{
    A[k/32] &= ~(1 << (k%32));
}

并测试是否第 k 位:

int TestBit( int A[],  int k )
{
    return ( (A[k/32] & (1 << (k%32) )) != 0 ) ;
}

如上所述,这些操作也可以写成宏:

As said above, these manipulations can be written as macros too:

// Due order of operation wrap 'k' in parentheses in case it
// is passed as an equation, e.g. i + 1, otherwise the first
// part evaluates to "A[i + (1/32)]" not "A[(i + 1)/32]"
#define SetBit(A,k)     ( A[(k)/32] |= (1 << ((k)%32)) )
#define ClearBit(A,k)   ( A[(k)/32] &= ~(1 << ((k)%32)) )
#define TestBit(A,k)    ( A[(k)/32] & (1 << ((k)%32)) )

这篇关于如何在 C 中定义和使用位数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-16 16:08
查看更多