我遇到以下问题:我有两个文件 file1.dat 和 file2.dat,每个文件各有一列,其中有 9 个数字。例如:
文件1.dat = 1,1,1,2,2,4,4,4,7
文件2.dat = 2,4,7,3,4,1,3,7,1
我试图编写一个程序,应该在这个网络中找到三元组,对于三元组,我的意思是一组以这个数字之一开头的三个数字,传递到另外两个链接在一起的数字,然后返回到原来的。在本例中,file1.dat 描述从何处开始的“节点”,file2.dat 描述到达的节点(1->2、1->4、1->7、2->3 ... )。这个小“网络”中有两个三元组,它们由1、2、4和1、4、7组成。我编写了以下程序:
#include <stdio.h>
#include <stdlib.h>
#define N 9
int main (void){
int A[N],B[N],i,j,l,m,k;
int x,y;
int valueA,valueB,count,middle_value,new_value;
FILE *fp,*fq;
if ((fp = fopen("file1.dat", "r")) == NULL ) {
printf("Error opening file 1\n");
exit(EXIT_FAILURE);
}
for (i = 0; i < N; i++) {
fscanf(fp,"%d", &x);
A[i] = x;
}
if ((fq = fopen("file2.dat", "r")) == NULL ) {
printf("Error opening file 2\n");
exit(EXIT_FAILURE);
}
for (i = 0; i < N; i++) {
fscanf(fq,"%d", &y);
B[i] = y;
}
up代码用于将两个文件中的所有数据填充到两个数组A和B中。
for (i=0;i<N;i++){
valueA=0;
valueB=0;
valueA=A[i];
valueB=B[i];
count=0;
middle_value=0;
new_value=0;
//Start the research of the first node of the file2.dat in the file1.dat
for(k=i+1;k<N;k++){
if(A[k]==valueB){
count++;
在这里,我放置了一个计数器“count”,该计数器增加到 1,让我知道是否在第一个文件中找到了与第一个参与节点具有相同值的数字。现在,如果计数器 = 1,我希望计算机记住值 B = A[k],并将其作为三元组的中间项写在文件末尾。然后我将新值赋予“valueB”,即与 A[k]--> B[k] 的起始位置对应的“节点到达”;
if(count==1){
middle_value = valueB;
valueB = B[k];
然后我在文件中向前查找,从我之前停止的位置 (l = k+1 ) 开始增加 for 三元组的最后一个值,该值必须类似于 A[l] --> A = 的第一个值=B[l]。然后我增加计数器,当计数器达到 2 时,程序应该打印 3 个值,否则应该保留 counter == 1,如果在 file1 中找不到第一个 valueB,则保留 counter == 0 (这就是为什么我把 else 放在最后..)
for(l=k+1;l<N;l++){
new_value=A[l];
if(new_value==valueB && valueA==B[l]){
count++;
if(count==2){
printf ("%d,%d,%d\n\n",valueA,middle_value,valueB);
}else{
count=1;
}
}
}
}else{
count=0;
}
}
}
}
fclose(fp);
fclose(fq);
return (0);
}
但是它并没有按照我想要的方式工作。但是,例如,如果我创建 2 个新文件,例如
文件1.dat = 1,1,1,2,3
文件2.dat = 2,4,7,3,1
哪里有三元组1,2,3,程序就可以工作(必须把#define N 6放在第三行)..有人可以帮助我吗?
<小时/>我认为存在的问题是,程序在开始文件时,当它关联到 valueA = 1、valueB=2 时,它会再次查找文件 1 2 的位置(现在变成“middle_value”) ") 并给出新值 B = 3。现在它将在 file1 中搜索 3,但没有找到。因此,它应该在 file1 中的第二个“2”处传递,并给出新的 valueB = 4,然后一切都会顺利进行。但事实并非如此。我不明白为什么
最佳答案
所以,我发现您的方法存在一些问题。也许最大的问题是你有三个循环:
for(i=0 ;i<N;i++){
for(k=i+1;k<N;k++){
for(l=k+1;l<N;l++){
每个循环从另一个循环结束的地方开始。但是,一般来说,您可能需要查看较小的节点才能找到循环。例如,如果您有以下图表:
1 2 3
3 1 2
您可以验证您的方法是否行不通。所以我们马上就知道我们需要扩大循环的范围。
此外,还有很多变量存在。有时(但并非总是),这表明该程序不必要地复杂。很多时候,不需要太多中间变量就可以解决相当复杂的问题。
您的 x
和 y
变量显然是不必要的,因为您将它们用作简单的中间体,所以我删除了它们。
您使用了两个文件指针变量,但实际上只需要一个。我剪掉了第二个。
我还将 fclose
语句移至更靠近您在文件中读取的位置,以便它们在尽可能短的时间内打开,这是一种礼貌的读取文件的方式。
您的 valueA
、valueB
和 count
变量立即让我觉得有问题。尤其是这一点:
valueA=0;
valueB=0;
valueA=A[i];
valueB=B[i];
您给他们值,然后立即更改这些值。
但是深入研究代码会发现您正在使用 valueA
和 valueB
来跟踪哪个 A
和 B
你正在看。您可以使用 count
来跟踪您在循环中的深度。 但是这些都是代码结构所固有的!
所以我删除了所有这些并扩大了循环范围,如上所述,结果是:
#include <stdio.h>
#include <stdlib.h>
#define N 9
int main () {
int A[N], B[N];
FILE *fp;
if ((fp = fopen ("file1.dat", "r")) == NULL) {
printf ("Error opening file 1\n");
exit (EXIT_FAILURE);
}
for (i = 0; i < N; i++)
fscanf (fp, "%d", &A[i]);
fclose (fp);
if ((fp = fopen ("file2.dat", "r")) == NULL) {
printf ("Error opening file 2\n");
exit (EXIT_FAILURE);
}
for (i = 0; i < N; i++)
fscanf (fp, "%d", &B[i]);
fclose (fp);
for(int i=0; i<N; i++)
for(int j=0; j<N; j++)
for(int k=0; k<N; k++)
if(B[i]==A[j] && B[j]==A[k] && B[k]==A[i])
printf("%d,%d,%d\n",A[i],A[j],A[k]);
return 0;
}
它会找到每个三重循环三次,这很不幸,但它会找到所有循环。有稍微复杂的算法可以一次找到循环或更有效地找到循环,但该算法最接近您的原始代码,因此它现在可能对您最有用。
关于c - 使用 C 程序在网络中查找三元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14210945/