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


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









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值