Как правильно читать строки битов из TXT-файла, чтобы вычислить расстояние Хемминга ч / б всех комбинаций строк - PullRequest
0 голосов
/ 24 декабря 2018

Моя цель - иметь возможность перебирать все цепочки битов, считываемые из текстового файла, чтобы я мог вычислить расстояние Хемминга между всеми комбинациями строк.Например, у меня есть текстовый файл, который содержит 500 цепочек битов, где каждая цепочка битов имеет длину 5093. Я хотел бы прочитать строки s1 и s2 из файла, а затем вычислить расстояние Хемминга между ними.По сути, я пытаюсь перебрать строки в файле, чтобы вычислить HD для всех комбинаций 500 * 499/2 = 124 750, чтобы я мог вычислить среднее значение, стандартное отклонение и построить гистограмму.Я смог сделать это в Python с помощью readlines (), чтобы прочитать строки и сохранить их в списке.Затем используйте цикл for, чтобы выполнить итерацию по всем (s1) строкам и сравнить их со строками (s2), считанными из списка, используя вложенный цикл for.Теперь я снова подхожу к проблеме, чтобы освежить свой C. Мой текущий подход заключается в повторении файла аналогичным образом и чтении цепочек битов с использованием двух вызовов fgets (), а затем обрезки возврата каретки.У меня проблема в том, что когда я пытаюсь вызвать второй fgets () для получения s2, конец цепочки битов обрезается на ~ 300 символов, и я вычисляю расстояние Хемминга 499 раз вместо ожидаемых 127 450 вычислений расстояния.Когда я один раз использую fgets () и закомментирую вложенный цикл while, я могу прочитать всю цепочку битов.Если бы вы могли помочь мне понять проблему с моей реализацией и правильным подходом к достижению моей цели, я был бы очень признателен.Спасибо!

РЕДАКТИРОВАТЬ: инициализировать переменные и сбросить и я и HD для расчета HD.Предоставлен аналогичный пример txt-файла, содержащего строки битов.В этом примере имеется 4 цепочки битов длиной 16 вместо 500 цепочек битов длиной 5093. В этом случае целью является вычисление HD для всех 6 комбинаций пар цепочек битов.

образец текстового файла

0011010000111010
1001001001110100
1110110010000100
0111011011111001

Код

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define SIZE 6000
#define CHIPS 500

int main(int argc, char *argv[]) {

    FILE* fp;

    char buffer[SIZE];
    char s1[SIZE];
    char s2[SIZE];
    int i = 0, j = 0, hd = 0;

    if(argc != 2) {
        fprintf(stderr, "USAGE: ./<executable> <bitstring file>\n");
        return 1;
    }
    else if ((fp = fopen(argv[1], "r")) == NULL) {
        perror("ERROR: File not found.\n");
        return 1;
    }
/*    for(i = 0; i < CHIPS; i++) {
        fgets(s1,sizeof(s1),fp);
        s1[strlen(s1) - 1] = '\0';
        printf("%s\n", s1);
        printf("%d\n", i);
        for(j = 0; j < CHIPS; j++) {
            fgets(s2, sizeof(s2),fp);
            s2[strlen(s2) - 1] = '\0';
            printf("%s\n", s2);
            printf("%d", j);
        }

    }
    fclose(fp);
*/
    while(fgets(s1,sizeof(s1), fp) != NULL) {
        //memcpy(s1,buffer, sizeof(s1));
        s1[strlen(s1) - 1] = '\0';
        printf("%s\n", s1);

        while(fgets(s2, sizeof(s2), fp) != NULL) {
            s2[strlen(s2) - 1] = '\0';

            while(s1[i] != '\0') {
                if(s1[i] != s2[i])
                    hd++;
                i++;
            }
            printf("Hamming Distance: %d\n", hd);
            i = 0;
            hd = 0;
        }

    }
    fclose(fp);

    return 0;
}

Пример вывода

...
Hamming Distance: 2576

1 Ответ

0 голосов
/ 24 декабря 2018

OP уже понимает (согласно комментариям) об ошибке, чтобы теперь инициализировать переменные.

Для циклического анализа N*(N-1)/2 раз, простой подход запоминает смещение файла конца текущей строки s1,Более поздний код стремится к тому, чтобы каждый цикл.

Более надежный код считывал бы все во внутреннюю память - но ниже приведена альтернатива для быстрого кодирования.

Как и при разработке большого количества кода, сначала сконцентрируйтесьпри правильной настройке функции и улучшении производительности.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define SIZE 6000
#define CHIPS 500

int main(void) {
  FILE* fp;
  char s1[SIZE];
  char s2[SIZE];

  fp = fopen("junk.txt", "w");
  if (fp == NULL) {
    perror("ERROR: File.\n");
    return 1;
  }
  fprintf(fp, "%s\n","0011010000111010");
  fprintf(fp, "%s\n","1001001001110100");
  fprintf(fp, "%s\n","1110110010000100");
  fprintf(fp, "%s\n","0111011011111001");
  fclose(fp);

  FILE *fp1 = fopen("junk.txt", "r");
  if (fp1 == NULL) {
    perror("ERROR: File not found.\n");
    return 1;
  }

  long offset = 0;
  for (;;) {
    fseek(fp1, offset, SEEK_SET);
    if (fgets(s1, sizeof(s1), fp1) == NULL) break;
    s1[strcspn(s1, "\n")] = 0;
    offset = ftell(fp1);  // record location
    if (offset == -1) break;

    while (fgets(s2, sizeof(s2), fp1) != NULL) {
      s2[strcspn(s2, "\n")] = 0;
      size_t i = 0;
      size_t hd = 0;
      while (s1[i] >= '0' && s1[i] <= '1') {
        if (s1[i] != s2[i]) {
          hd++;
        }
        i++;
      }
      printf("s1 <%s> " "s2 <%s> " "Hamming Distance: %zu\n", s1 ,s2, hd);
    }

  }
  fclose(fp);
  puts("Done");
  return 0;
}

Вывод: 6 кодов Хэмминга, как ожидается, за 4 * 3/2

s1 <0011010000111010> s2 <1001001001110100> Hamming Distance: 8
s1 <0011010000111010> s2 <1110110010000100> Hamming Distance: 10
s1 <0011010000111010> s2 <0111011011111001> Hamming Distance: 6
s1 <1001001001110100> s2 <1110110010000100> Hamming Distance: 10
s1 <1001001001110100> s2 <0111011011111001> Hamming Distance: 8
s1 <1110110010000100> s2 <0111011011111001> Hamming Distance: 10
Done
...