0

我有以下问题:我有两个文件 file1.dat 和 file2.dat,每列有 9 个数字。举个例子:

file1.dat = 1,1,1,2,2,4,4,4,7

file2.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++;

在这里,我放了一个增加到 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[ 的第一个值升]。然后我增加计数器,当计数器达到 2 时,程序应该打印出 3 个值,否则它应该留下计数器 == 1,如果它在 file1 中找不到第一个值 B,则留下计数器 == 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 个新文件,例如

file1.dat = 1,1,1,2,3

file2.dat = 2,4,7,3,1

哪里有三合会 1,2,3,程序可以工作(必须把#define N 6 放在第 3 行).. 有人可以帮助我吗?


我认为存在的问题是,带有开始文件的程序,当它与 valueA = 1,valueB=2 相关联时,它再次向文件 1 查找 2 的位置(现在变成“中间值”)和它给出了新的值 B = 3。现在它将在 file1 中搜索 3,但找不到它。所以它应该在 file1 中的第二个“2”处传递并赋予新的 valueB = 4,然后一切都会顺利进行。但事实并非如此。我不明白为什么

4

1 回答 1

1

因此,我发现您的方法存在许多问题。也许最大的问题是你有三个循环:

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

您可以验证您的方法是否行不通。所以我们马上就知道我们需要扩大循环的范围。

此外,您还有很多变量。有时(但并非总是),这表明程序不必要地复杂。很多时候,不需要太多中间变量就可以解决相当复杂的问题。

你的xy变量显然是不必要的,因为你把它们用作简单的中间体,所以我把它们删掉了。

您使用了两个文件指针变量,但实际上只需要一个。我剪掉了第二个。

我还将fclose语句移到更靠近您在文件中读取的位置,以便它们在尽可能短的时间内打开,这是读取文件的一种礼貌方式。

valueAvalueB, 和count变量立即让我觉得有问题。尤其是这一点:

valueA=0;
valueB=0;     

valueA=A[i];
valueB=B[i];

你给他们值,然后立即改变这些值。

但是更深入地查看代码表明您正在使用valueAvalueB跟踪您正在查看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;
}

它将找到每个三元组循环 3 次,这是不幸的,但它会找到所有循环。有一些更复杂的算法可以找到循环一次或更有效地找到它们,但是这个算法最接近你的原始代码,所以它现在可能对你最有用。

于 2013-01-08T11:33:02.097 回答