检查结构元素并将其与 C 中的用户输入进行比较
Checking and comparing structure elements to a user input in C
我正在尝试用 C 编写一个函数,该函数 在包含客户信息的数据库中搜索 , 比较 某些用户的信息输入,并最终根据依赖于 Livenshtein 距离百分比的条件打印出良好的结果。
typedef struct Person_t
{
char Name[32];
char Email[64];
char City[96];
char Country[64];
} Person;
问题来了,用户被要求输入结构成员所代表的每一个信息,但他只能输入他想要的,例如:姓名:Emily,电子邮件:(没有用户输入又名左空),城市:(留空),国家:法国。
这里的目标是仅将这些属性(Emily、Country)与数据库中的相应属性进行比较,因为:正如我所说,比较算法基于与 Livenshtein 距离相关的条件,如果该条件没有通过 50,它不会将搜索验证为“好结果”,这可能会排除好的情况,比如:
姓名:杰克,电子邮件:jack.jack@gmail.com,城市:伯明翰,国家:美国
这个客户存在于我们的“大”数据库中(假设我们有很多 Jacks 和很多来自伯明翰的人),而 smbd 进行搜索时只知道一些关于 Jack 的信息,所以他输入:
姓名:Jackk,电子邮件:(空),城市:(空),国家:美国ss
(我故意打乱拼写是为了展示 LD 的用处,它仍然会在百分比上得分很高所以不要担心)
使用 LD 的百分比条件:percentage = (1 - LD/max(string1, string2)) * 100 ,我们将截止值设置为 50%。
这里的问题是,如果我们将每个结构成员与其对应的结构成员(与用户输入的内容相关的成员)进行比较,我们将减少 它获得高百分比的可能性,因为将空字符串与“存在的”字符串进行比较会使 Livenshtein 距离很大,因此百分比 低 这会带走很多好的结果。
请务必注意,我不想使用 OR 。我不知道如果他得到正确的“杰克”,它将通过(百分比 = 100),由于存在太多杰克(我们正在谈论一个大数据库),这将不会有效,所以我肯定会使用 AND,以确保所有用户输入都尽可能接近他想要的,同时尽量减少结果的数量。
请记住,除此之外,post-搜索结果将根据百分比进行排序,因此需要彻底处理空白字符串。
这是我的评论的一个例子。
compare_field
函数 returns 1 如果存在有效匹配并填充 percentage
out 参数;如果该字段无关紧要,它 returns 0。
compare_record
函数调用该函数 4 次,每个字段一次,并对字段比较函数返回的百分比进行平均。
#include <stdio.h>
#include <string.h>
typedef struct Person_t {
char Name[32];
char Email[64];
char City[96];
char Country[64];
} Person;
static Person database[] = {
{.Name = "Emily",
.Email = "emi@x.ly",
.City = "Paris",
.Country = "France"},
{.Name = "Jack",
.Email = "jack.jack@gmail.com",
.City = "Birmingham",
.Country = "United States"},
{.Name = "Jank",
.Email = "jankjank@gmail.com",
.City = "London",
.Country = "United Kingdom"},
};
static int compare_field(const char *record, const char *query,
float *percentage) {
if (strlen(record) == 0 || strlen(query) == 0) {
return 0; // Ignore this field in the search
}
// TODO: implement real levenshtein distance here
int distance = 0;
for (int i = 0;; i++) {
if (record[i] == 0 || query[i] == 0)
break;
if (record[i] != query[i])
distance++;
}
*percentage = (1.0f - distance / (float)strlen(record)) * 100.0f;
return 1;
}
static float compare_record(const Person *record, const Person *query) {
float total_match_percentage = 0, temp_percentage;
int total_match_fields = 0;
#define COMPARE_FIELD(field) if (compare_field(record->field, query->field, &temp_percentage)) { total_match_percentage += temp_percentage; total_match_fields++; }
COMPARE_FIELD(Name);
COMPARE_FIELD(Email);
COMPARE_FIELD(City);
COMPARE_FIELD(Country);
#undef COMPARE_FIELD
return total_match_percentage / (float)total_match_fields;
}
int main() {
int n_database = sizeof(database) / sizeof(Person);
Person query = {.Name = "Jamk", .City = "Pondon", .Country = "United K"};
for (int i = 0; i < n_database; i++) {
float match = compare_record(&database[i], &query);
printf("%s: %.2f\n", database[i].Name, match);
}
}
使用源代码中的 query
打印出来(因为 Emily 仍然匹配 P
aris 而我没有实现完整的 Levenshtein 距离算法)...
Emily: 13.33
Jack: 72.44
Jank: 86.11
我正在尝试用 C 编写一个函数,该函数 在包含客户信息的数据库中搜索 , 比较 某些用户的信息输入,并最终根据依赖于 Livenshtein 距离百分比的条件打印出良好的结果。
typedef struct Person_t
{
char Name[32];
char Email[64];
char City[96];
char Country[64];
} Person;
问题来了,用户被要求输入结构成员所代表的每一个信息,但他只能输入他想要的,例如:姓名:Emily,电子邮件:(没有用户输入又名左空),城市:(留空),国家:法国。
这里的目标是仅将这些属性(Emily、Country)与数据库中的相应属性进行比较,因为:正如我所说,比较算法基于与 Livenshtein 距离相关的条件,如果该条件没有通过 50,它不会将搜索验证为“好结果”,这可能会排除好的情况,比如:
姓名:杰克,电子邮件:jack.jack@gmail.com,城市:伯明翰,国家:美国
这个客户存在于我们的“大”数据库中(假设我们有很多 Jacks 和很多来自伯明翰的人),而 smbd 进行搜索时只知道一些关于 Jack 的信息,所以他输入:
姓名:Jackk,电子邮件:(空),城市:(空),国家:美国ss
(我故意打乱拼写是为了展示 LD 的用处,它仍然会在百分比上得分很高所以不要担心)
使用 LD 的百分比条件:percentage = (1 - LD/max(string1, string2)) * 100 ,我们将截止值设置为 50%。
这里的问题是,如果我们将每个结构成员与其对应的结构成员(与用户输入的内容相关的成员)进行比较,我们将减少 它获得高百分比的可能性,因为将空字符串与“存在的”字符串进行比较会使 Livenshtein 距离很大,因此百分比 低 这会带走很多好的结果。
请务必注意,我不想使用 OR 。我不知道如果他得到正确的“杰克”,它将通过(百分比 = 100),由于存在太多杰克(我们正在谈论一个大数据库),这将不会有效,所以我肯定会使用 AND,以确保所有用户输入都尽可能接近他想要的,同时尽量减少结果的数量。
请记住,除此之外,post-搜索结果将根据百分比进行排序,因此需要彻底处理空白字符串。
这是我的评论的一个例子。
compare_field
函数 returns 1 如果存在有效匹配并填充 percentage
out 参数;如果该字段无关紧要,它 returns 0。
compare_record
函数调用该函数 4 次,每个字段一次,并对字段比较函数返回的百分比进行平均。
#include <stdio.h>
#include <string.h>
typedef struct Person_t {
char Name[32];
char Email[64];
char City[96];
char Country[64];
} Person;
static Person database[] = {
{.Name = "Emily",
.Email = "emi@x.ly",
.City = "Paris",
.Country = "France"},
{.Name = "Jack",
.Email = "jack.jack@gmail.com",
.City = "Birmingham",
.Country = "United States"},
{.Name = "Jank",
.Email = "jankjank@gmail.com",
.City = "London",
.Country = "United Kingdom"},
};
static int compare_field(const char *record, const char *query,
float *percentage) {
if (strlen(record) == 0 || strlen(query) == 0) {
return 0; // Ignore this field in the search
}
// TODO: implement real levenshtein distance here
int distance = 0;
for (int i = 0;; i++) {
if (record[i] == 0 || query[i] == 0)
break;
if (record[i] != query[i])
distance++;
}
*percentage = (1.0f - distance / (float)strlen(record)) * 100.0f;
return 1;
}
static float compare_record(const Person *record, const Person *query) {
float total_match_percentage = 0, temp_percentage;
int total_match_fields = 0;
#define COMPARE_FIELD(field) if (compare_field(record->field, query->field, &temp_percentage)) { total_match_percentage += temp_percentage; total_match_fields++; }
COMPARE_FIELD(Name);
COMPARE_FIELD(Email);
COMPARE_FIELD(City);
COMPARE_FIELD(Country);
#undef COMPARE_FIELD
return total_match_percentage / (float)total_match_fields;
}
int main() {
int n_database = sizeof(database) / sizeof(Person);
Person query = {.Name = "Jamk", .City = "Pondon", .Country = "United K"};
for (int i = 0; i < n_database; i++) {
float match = compare_record(&database[i], &query);
printf("%s: %.2f\n", database[i].Name, match);
}
}
使用源代码中的 query
打印出来(因为 Emily 仍然匹配 P
aris 而我没有实现完整的 Levenshtein 距离算法)...
Emily: 13.33
Jack: 72.44
Jank: 86.11