我有一个函数,它返回字母表中可能的所有字母组合,并在长度为LENTH_MAX的字中重复。该函数在2D数组调用中返回这些组合' arr'。
因为计算数组总数是一件痛苦的事,因为你需要计算阶乘数[(n + r - 1)!/ r!(n - 1)!我决定越来越多地为阵列中的阵列重新分配内存。根据需要。
我设置了一个名为capacity的变量,用于确定' arr'的初始大小。和一个名为CAP_INCR的常量,它指定除了已分配的内存之外将重新分配内存的数组的数量。如果我将CAP_INCR设置为1,则程序编译好,这样每次找到新组合时,为该数组分配新内存,程序将使用Segmentation fault:11消息,如果我将CAP_INCR设置为100,如果正确完成但是输出是错误的,第一个组合' aa a'重复两次,最后一次组合' z z z'是使命。
我真的很感激一些帮助。我是其他语言的一个不错的程序员,但我只是从C开始。
代码是:
#include <stdio.h>
#include <stdlib.h>
const unsigned short LENGTH_MAX = 3;
const char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
#define CAP_INCR 1 /* memory increases */
unsigned char* combinations(unsigned char n, unsigned char r)
{
// n length of alphabet
// r length of figures
unsigned int set_counter = 0; //counting generated sequences
unsigned char *vector = NULL; //where the current figure is stored
unsigned char *arrTemp = NULL; // Temporary pointer store
unsigned int capacity = 100; // count current size of arr
unsigned char *arr = (unsigned char *)malloc(capacity * r * sizeof(unsigned char)); // multidimentional array
vector = (unsigned char *)malloc(sizeof(unsigned char) * r);
if(vector == NULL || arr == NULL)
{
fprintf(stderr, "error: insufficient memory\n");
exit(EXIT_FAILURE);
}
//initialize: vector[0, ..., r - 1] are 0, ..., r - 1
for(int l = 0; l < r; l++) //for(int l = 0; l < r; l++) // no repetition
vector[l] = 0;
//generate all successors
while(1)
{
set_counter++;
// check is arr current capacity is enough
if(set_counter > capacity)
{ // We need more memory
capacity += CAP_INCR;
arrTemp = (unsigned char *)realloc(arr, capacity * r * sizeof(unsigned char));
if(!arrTemp)
{
printf("Unfortunately memory reallocation failed.\n");
free(arr);
arr = NULL;
exit(0);
}
arr = arrTemp;
}
for(int x = 0; x < r; x++) { // assign a new combination to arr
//printf("%c ", alphabet[vector[x]]);
*(arr + set_counter*r + x) = vector[x];
}
//printf("(%u)\n", set_counter);
int j; //index
//easy case, increase rightmost element
if(vector[r - 1] < n - 1)
{
vector[r - 1]++;
continue;
}
//find rightmost element to increase
for(j = r - 2; j >= 0; j--) {
if(vector[j] != n - 1) {
break;
}
}
//terminate if vector[0] == n - r
if(j < 0)
break;
//increase
vector[j]++;
//set right-hand elements
for(j += 1; j < r; j++)
vector[j] = vector[j - 1];
}
return arr;
}
int main() {
unsigned char* arr = combinations(sizeof(alphabet)-1, LENGTH_MAX);
int c=0;
for (int i = 0; i < 3276; i++) // 3276 is the total number of combinations
{
for (int j = 0; j < 3; j++)
{
printf("%c ", alphabet[*(arr + i*3 + j)]);
}
printf("count: %d\n",++c);
}
return 0;
}