问题序列中的问题复制阵列

时间:2019-02-17 09:32:55

标签: c

我正在尝试执行外观序列(wiki),但被卡住了。

我认为这些行是char数组。 首先,我通过数组line进入for循环,找到“边界/差异”(在1211:1 | 2 | 11中),并在int数组diff中将它们记为位置。然后,我计算count并找出范围内的数字,并在新数组line_new中记下它。然后,我需要将新数组line_new复制到旧数组line,这就是我认为问题所在。

我相信有更好的方法可以完全做到这一点,但我正在努力使其尽可能简单。

预期结果:

1
11
21
1211
111221
312211

实际结果:

1
11
21
1211 \\line_new
12 \\line

代码:

#include<stdio.h>
#include <string.h>
#define length(x)  (sizeof(x) / sizeof((x)[0]))

void spocitej(int n){

    int count = 1;
    char line[] = {"21"};
    char line_new[] = {" "};
    int diff[] = {0};

    char num;

    int len, len_d;
    int i, j, k, l, X, m;

    printf("1\n");
    printf("11\n");
    printf("21\n");

    for(i = 4; i < n; i++){

        j = 0;
        len = strlen(line)-1;

        for(i = 0; i < len; i++){
        if(line[i] != line[i+1]){
                diff[j] = i;
                j++;
            }
       }

       len_d = length(diff);
       l = 0;


       for(k = 0; k < len_d; k++){

            if(k == 0){
                count = diff[k]+1;
                num = line[0];
                line_new[l] = count+'0';
                line_new[l+1] = num;
                l = l+2;
            }else if(k!=0 && k!=len_d-1){
                count = diff[k]-diff[k-1];
                line_new[l] = count+'0';
                line_new[l+1] = line[diff[k]];
                l = l+2;
            }

            if(k == len_d-1){
                count = (len - diff[k]);
                num = line[len];
                line_new[l] = count+'0';
                line_new[l+1] = num;
                line_new[l+2] = '\0';
            }
          }

        puts(line_new);

//        strcpy(line, line_new);
        strncpy(line, line_new, sizeof(line_new));


        puts(line);

        printf("\n");
    }
}




int main()
{
    int n = 5;
    spocitej(n);

    fflush(stdin);
    getchar();

    return 0;
}

2 个答案:

答案 0 :(得分:1)

阵列的大小可能与您预期的不一样

  • line包含3个字符(以'2','1'和'\ 0'初始化)
  • line_new仅包含2个字符(以''和'\ 0'初始化)
  • diff仅包含1个int(用0初始化),一个数组无用,可以是int diff;

因此length(diff)始终为1,实际上您将其放入循环中可能意味着您假设它已更改,但事实并非如此。

当您填充line_new时,并不总是放置空字符终止符,因此puts(line_new);可以继续从数组中移出,直到找到'\ 0',这是未指定的行为

如果 n 代表您计算的最大位数,则需要数组 n + 1 个字符,不仅是3个字符,而且是2个字符。但是我不确定目标是什么的 n ,因为您期望 n = 5

111221

一个提案,第一个参数是第一个数字,第二个是循环数:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char ** argv)
{
  if (argc != 3)
    return -1;

  int f = atoi(argv[1]); /* the first digit */
  int n = atoi(argv[2]); /* the number of turn */

  if ((f < 1) || (f > 9) || (n < 1))
    return -1;

  /* grow in length is like 30% per generation */
  size_t maxsz = (int) pow(1.4, n+1) + 1;

  /* the two arrays and their used size */
  char * arr1 = malloc(maxsz);
  char * arr2 = malloc(maxsz);
  size_t sz1, sz2;

  /* starting with 1 time first digit */
  arr1[0] = f;
  sz1 = 1;

  while (n--) {
    size_t i;

    for (i = 0; i != sz1; ++i)
      printf("%d", arr1[i]);
    putchar('\n');

    /* add a final not possible 10 to not have a special case for the last digit */
    arr1[sz1] = 10;
    sz2 = 0;
    i = 1;

    /* counts */
    do {
      arr2[sz2] = 1;
      while (arr1[i] == arr1[i-1]) {
        arr2[sz2] += 1;
        i += 1;
      }
      arr2[sz2 + 1] = arr1[i-1];
      sz2 += 2;
    } while (++i <= sz1);

    /* exchange role between arr1 and arr2 to avoid to copy arr2 into arr1 */
    char * arr = arr1;

    arr1 = arr2;
    arr2 = arr;
    sz1 = sz2;
  }

  free(arr1);
  free(arr2);
  return 0;
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra -g cc.c -lm
pi@raspberrypi:/tmp $ ./a.out 1 1
1
pi@raspberrypi:/tmp $ ./a.out 1 2
1
11
pi@raspberrypi:/tmp $ ./a.out 1 3
1
11
21
pi@raspberrypi:/tmp $ ./a.out 1 4
1
11
21
1211
pi@raspberrypi:/tmp $ ./a.out 1 5
1
11
21
1211
111221
pi@raspberrypi:/tmp $ ./a.out 1 6
1
11
21
1211
111221
312211
pi@raspberrypi:/tmp $ ./a.out 1 10
1
11
21
1211
111221
312211
13112221
1113213211
31131211131221
13211311123113112211
pi@raspberrypi:/tmp $ ./a.out 3 10
3
13
1113
3113
132113
1113122113
311311222113
13211321322113
1113122113121113222113
31131122211311123113322113

valgrind

下执行
pi@raspberrypi:/tmp $ valgrind ./a.out 1 20
==5026== Memcheck, a memory error detector
==5026== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==5026== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==5026== Command: ./a.out 1 20
==5026== 
1
11
21
1211
111221
312211
13112221
1113213211
31131211131221
13211311123113112211
11131221133112132113212221
3113112221232112111312211312113211
1321132132111213122112311311222113111221131221
11131221131211131231121113112221121321132132211331222113112211
311311222113111231131112132112311321322112111312211312111322212311322113212221
132113213221133112132113311211131221121321131211132221123113112221131112311332111213211322211312113211
11131221131211132221232112111312212321123113112221121113122113111231133221121321132132211331121321231231121113122113322113111221131221
31131122211311123113321112131221123113112211121312211213211321322112311311222113311213212322211211131221131211132221232112111312111213111213211231131122212322211331222113112211
1321132132211331121321231231121113112221121321132122311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112311332111213122112311311123112111331121113122112132113213211121332212311322113212221
11131221131211132221232112111312111213111213211231132132211211131221131211221321123113213221123113112221131112311332211211131221131211132211121312211231131112311211232221121321132132211331121321231231121113112221121321133112132112312321123113112221121113122113121113123112112322111213211322211312113211
==5026== 
==5026== HEAP SUMMARY:
==5026==     in use at exit: 0 bytes in 0 blocks
==5026==   total heap usage: 3 allocs, 3 frees, 3,368 bytes allocated
==5026== 
==5026== All heap blocks were freed -- no leaks are possible
==5026== 
==5026== For counts of detected and suppressed errors, rerun with: -v
==5026== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)

答案 1 :(得分:1)

基于行21,下一条要生成的行是1211。要将这一行存储在计算机的内存中,需要4个字节作为可见字符,再加上1个字节作为终止NUL字符'\0'

在当前代码中,您将保留一个固定长度的数组,其中包含1个可见字符的空间以及结尾的'\0'。这还不够。

您的代码将覆盖此数组及其后的内存,这将调用未定义的行为,并且可能会或可能不会导致您的程序现在或以后崩溃。在这方面,C是一种讨厌的编程语言。

可悲的是,C不提供任何数据结构,例如StringBufferStringBuilder,因此您必须自己做。基本成分是malloc函数,该函数为您分配内存。一个安全的选择就是:

char *line_new = malloc(2 * strlen(line) + 1);

这给您足够的空间。当您不再需要此空间时,必须调用free(line_new),否则您的程序将很快耗尽计算机的所有内存。