Kolakoski序列生成遇到的问题及调试过程

来源:互联网 发布:白衬衫 知乎 编辑:程序博客网 时间:2024/06/11 22:49


设计一个函数:给定输出序列长度n和源序列a[ ]以及源序列的长度m,三个参数,输出生成的Kolakoski序列的前n个序列。

整个设计及过程中出现的问题及逐步调试过程和解决方案,最后面时最终的代码。

初步设计为:

#include <stdio.h>#include <stdlib.h>int * Kolakoski(int n, int m, int a[]);int main(){int i = 0;//int n = 30, m = 4;//int a[4] = {2, 1, 3, 1};int n = 0, m = 0;scanf("%d %d", &n, &m);int *a = (int *)malloc(sizeof(int) * m);for (i=0; i<m; i++)scanf("%d", &a[i]);int * A = Kolakoski(n, m, a);for (i=0; i<n; i++)printf ("%d\n", A[i]);free(A);A = NULL;free(a);a = NULL;return 0;}int * Kolakoski(int n, int m, int a[]){/*j表示原始数组a[j]; i表示要输出的数组的序号;k表示到A[p]内的循环;p表示要输出的数组的前面的控制序号 */int i = 0, j = 0, k = 0, p = 0;int *A = (int *)malloc(sizeof(int) * n);A[p] = a[j];while(i < n){for(k = 0; k < A[p]; k++){A[i++] = a[j];}p++;j++;j = j % m;}return A;}

上述程序,在不同的输入时出现来两个问题

1.当源数组的第一个数为1时出现错误

2.不时的出现调试错误问题


#######################################################################################

问题1解决过程:

当源数组的第一个数为1时出现错误,原因是:

A[p] = a[j]
当第一个数为1时,A[0]为1了,刚好满足1,所以不再生成A[1],故在执行下一次for循环时需要A[1]的值,但A[1]的值并没有生成。

修改后如下:

int * Kolakoski(int n, int m, int a[]){/*j表示原始数组a[j]; i表示要输出的数组的序号;k表示到A[p]内的循环;p表示要输出的数组的前面的控制序号 */int i = 0, j = 0, k = 0, p = 0;int *A = (int *)malloc(sizeof(int) * n);A[p] = a[j];A[p+1] = a[j+1];while(i < n){for(k = 0; k < A[p]; k++){A[i++] = a[j];}p++;j++;j = j % m;}return A;}
只是多初始化了一个A[1]的值,如果后面不需要A[1]的值则会覆盖掉。


#####################################################################

问题2解决过程:

还有一个问题是在运行过程中不时地会出现调试错误问题:

但输出的结果是正确的,只是在运行结束后会出现这个问题。

接下来,探究这个问题!

最直接的方法就是找到一个出现此问题的例子进行试数调试,例如当n = 20 , m  = 2   ,a[ ] = [2, 3]时会出现此问题。

开始试数,当循环到k  < A[8]时,此时后面的序列已经循环到A[18],此时A[8]=3,显然若经过此次循环i=21,超出了数组的擦汗年长度,也就是问题所在。

解决方案为:

for(k = 0; k < A[p]; k++){A[i++] = a[j];if (i >= n)break;}

在for循环内加一条判断,当i 增加到n时 跳出循环,数组就不会溢出,问题也就解决了。


最终代码:

#include <stdio.h>#include <stdlib.h>int * Kolakoski(int n, int m, int a[]);int main(){int i = 0;//int n = 30, m = 4;//int a[4] = {2, 1, 3, 1};int n = 0, m = 0;scanf("%d %d", &n, &m);int *a = (int *)malloc(sizeof(int) * m);for (i=0; i<m; i++)scanf("%d", &a[i]);int * A = Kolakoski(n, m, a);for (i=0; i<n; i++)printf ("%d\n", A[i]);free(A);A = NULL;free(a);a = NULL;return 0;}int * Kolakoski(int n, int m, int a[]){/*j表示原始数组a[j]; i表示要输出的数组的序号;k表示到A[p]内的循环;p表示要输出的数组的前面的控制序号 */int i = 0, j = 0, k = 0, p = 0;int *A = (int *)malloc(sizeof(int) * n);A[p] = a[j];A[p+1] = a[j+1];while(i < n){for(k = 0; k < A[p]; k++){A[i++] = a[j];if (i >= n)break;}p++;j++;j = j % m;}return A;}









阅读全文
2 0
原创粉丝点击