设计一个函数:给定输出序列长度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;
}