我的目标是能够迭代从文本文件读取的所有位串,以便我可以计算所有字符串组合之间的汉明距离。例如,我有一个txt文件,其中包含500个位串,每个位串的长度为5093。我想从文件中读取字符串s1和s2,然后计算它们之间的汉明距离。本质上,我试图遍历文件中的字符串以计算所有500 * 499/2 = 124,750个组合的HD,以便可以计算均值,std dev并绘制直方图。通过使用readlines()读取字符串并将它们存储在列表中,我能够在python中做到这一点。然后,使用for循环迭代所有(s1)字符串,然后使用嵌套的for循环将它们与从列表中读取的(s2)字符串进行比较。现在,我正在重新解决这个问题以重新使用我的C语言。我当前的方法包括以类似的方式遍历文件,并使用对fgets()的两次调用读取位串,然后剥离回车符。我遇到的问题是,当我尝试调用第二个fgets()以获取s2时,位串的末尾被缩短了约300个字符,并且我计算了汉明距离499次,而不是预期的127450次距离计算。当我使用fgets()一次并注释掉嵌套的while循环时,我能够读取完整的位串。如果您能帮助我理解实施过程中的问题以及实现目标的正确方法,将不胜感激。谢谢!
编辑:初始化变量,并重置i和hd以进行HD计算。提供了包含位串的txt文件的类似示例。在此示例中,有4个长度为16的位串,而不是500个长度为5093的位串。在这种情况下,目标是计算所有6个位串对组合的HD。
样本txt文件
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
答案 0 :(得分:0)
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;
}
输出:每个4 * 3/2预期6个汉明码
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