我写了一个程序来在 C 中找到两个数组的交集 b。 我的数组没有采用我想要输入的元素数量。这是为什么?
这是我的代码:
#include <stdio.h>;
int main() {
int a[100], b[100], n, m, i, j;
printf("enter n.o of ele to enter in A \n");
scanf("%d", &n);
printf("enter elements into array A:\n");
for (i = 0; i < n; i++) {
scanf("%d \n", &a[i]);
}
printf("enter n.o of ele to enter in B \n");
scanf("%d ", &m);
printf("enter elements into array B:\n");
for (j = 0; j < m; j++) {
scanf("%d \n", &b[j]);
}
printf("common ele are :\n");
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
if (a[i] == b[j]) {
printf("%d \n", a[i]);
break;
}
}
}
}
我希望程序输出数组中的公共元素,但它没有占用我想要的元素数量。 如果我想在数组中输入 4 个元素,则需要超过 4 个元素。
在测试代码时,主要问题在于“scanf”函数调用中使用的格式。例如,以下 scanf 调用因格式中包含换行符而变得混乱。
scanf("%d \n",&a[i]);
仔细阅读了您的代码,以下是一个重构版本,对 scanf 函数进行了一些清理,并添加了一些额外的输出文本,使程序更加用户友好。
#include<stdio.h>
int main()
{
int a[100],b[100],n,m,i,j;
printf("enter n.o of ele to enter in A \n");
scanf("%d",&n);
printf("enter elements into array A:\n");
for(i=0; i<n; i++)
{
printf("Element: "); /* To provide some user friendly prompting */
scanf("%d", &a[i]); /* Clean up of the scanf formatting */
}
printf("Enter n.o of ele to enter in B \n");
scanf("%d",&m); /* Clean up of the scanf formatting */
printf("Enter elements into array B:\n");
for(j=0; j<m; j++)
{
printf("Element: "); /* To provide some user friendly prompting */
scanf("%d", &b[j]); /* Clean up of the scanf formatting */
}
printf("Common ele are :\n");
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
if(a[i]==b[j])
{
printf("%d \n",a[i]);
//break; /* Should not want this if all matches are to be printed */
}
}
}
return 0;
}
请注意,换行符和空格填充等项目已被删除。通过这些重构,下面是对重构代码的测试。
@Vera:~/C_Programs/Console/Intersect/bin/Release$ ./Intersect
enter n.o of ele to enter in A
3
enter elements into array A:
Element: 44
Element: 88
Element: 77
Enter n.o of ele to enter in B
3
Enter elements into array B:
Element: 77
Element: 55
Element: 88
Common ele are :
88
77
你可能想对 scanf 函数做更多的研究,但试试这个重构代码,看看它是否符合你项目的精神。
问题是
scanf()
转换字符串:调用 scanf("%d \n", &a[i]);
执行以下阶段:
%d
从 stdin
读取字节,忽略任何初始空格,接受可选符号并将所有后续数字转换为基数为 10 的 int
,存储到 a[i]
中。然后
导致 scanf
读取并丢弃任何空白字符。输入的换行符被消耗,并且期望用户进一步输入,直到输入非空白字符(该字符被推回stdin
)或遇到流的结尾。\n
具有完全相同的效果,因此因为挂起的字符不是空白,所以什么都不做。尾随的
\n
是罪魁祸首:每次调用 scanf()
直到输入下一个数字的第一个字符才会返回。只需删除这些字符,程序就会按预期运行。
但是请注意,您应该测试
scanf()
的返回值以检测无效或丢失的输入。
还要注意
;
之后的尾随#include <stdio.h>
是无效的。
这里是修改版:
#include <stdio.h>
int main(void) {
int a[100], b[100], n, m, i, j;
printf("enter number of elements to enter for A:\n");
if (scanf("%d", &n) != 1)
return 1;
if (n < 0 || n > 100) {
printf("invalid number of elements: %d\n", n);
return 1;
}
printf("enter elements into array A:\n");
for (i = 0; i < n; i++) {
if (scanf("%d", &a[i]) != 1)
return 1;
}
printf("enter number of elements to enter for B:\\n");
if (scanf("%d", &m) != 1)
return 1;
if (m < 0 || m > 100) {
printf("invalid number of elements: %d\n", m);
return 1;
}
printf("enter elements into array B:\n");
for (j = 0; j < m; j++) {
if (scanf("%d \n", &b[j]) != 1)
return 1;
}
printf("common elements are:\n");
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
if (a[i] == b[j]) {
printf("%d\n", a[i]);
break;
}
}
}
return 0;
}
注意上面的算法没有正确处理重复项:
A = { 1, 1 }
和B = { 1 }
,输出是1 1
,它甚至不是B
的子集。输出应该是1
.你可以用一个额外的数组来纠正这个问题:
unsigned char seen[100] = { 0 };
printf("common elements are:\n");
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
if (a[i] == b[j] && !seen[j]) {
seen[j] = 1;
printf("%d\n", a[i]);
break;
}
}
}