我是一个C语言的学徒,试图在这里学习一些东西。我遇到了一个问题,我希望我能自己解决它。但是,我是一个短 Package 器和相当容易拖延,所以我需要你的良好支持。正如标题明确地说,我不知道为什么我的topMatches()函数输出一些随机浮点值,在scores[]数组的开头和结尾打印出来。
Output #1
(-0.00000, Lisa Rose),(0.99124, Gene Seymour),(0.92447, Michael Phillips),(0.89341, Claudia Puig),(0.66285, Mick LaSalle),(0.38125, Jack Matthews),(-1.00000, Toby)
Output #2
(107185664961793568883398204719104.00000, Lisa Rose),(0.99124, Gene Seymour),(0.92447, Michael Phillips),(0.89341, Claudia Puig),(0.66285, Mick LaSalle),(0.38125, Jack Matthews),(-1.00000, Toby)
Output #3
(0.99124, Lisa Rose),(0.92447, Gene Seymour),(0.89341, Michael Phillips),(0.66285, Claudia Puig),(0.38125, Mick LaSalle),(-118195603315995709432961818167345152.00000, Jack Matthews),(-1.00000, Toby)
...
该值应在-1和1之间。我非常希望看到您的反馈。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
//data types
struct mInfo
{
char mName[20];
float rating;
};
struct cInfo
{
char name[20];
struct mInfo movi[7];
};
//prototype fxns
typedef double (*sim_fp)(struct cInfo *, const char *, const char *);
double sim_D(struct cInfo *prefs, const char *person1, const char *person2);
void topMatches(sim_fp fp, struct cInfo *prefs, const char *person1, int num);
int cmpFxn (const void * a, const void * b);
void reverseFxn(float arr[], int num);
int main()
{
int num = 7;
struct cInfo critics[num];
critics[0] = (struct cInfo) {"Lisa Rose", {"Lady in the Water", 2.5, "Snakes on a Plane", 3.5, "Just My Luck", 3, "Superman Returns", 3.5, "The Night Listener", 3, "You, Me and Dupree", 2.5}};
critics[1] = (struct cInfo) {"Gene Seymour",{"Lady in the Water", 3, "Snakes on a Plane", 3.5, "Just My Luck", 1.5, "Superman Returns", 5, "The Night Listener", 3, "You, Me and Dupree", 3.5}};
critics[2] = (struct cInfo) {"Michael Phillips",{"Lady in the Water", 2.5, "Snakes on a Plane", 3, "Superman Returns", 3.5, "The Night Listener", 4}};
critics[3] = (struct cInfo) {"Claudia Puig",{"Snakes on a Plane", 3.5, "Just My Luck", 3, "Superman Returns", 4, "The Night Listener", 4.5, "You, Me and Dupree", 2.5}};
critics[4] = (struct cInfo) {"Mick LaSalle",{"Lady in the Water", 3, "Snakes on a Plane", 4, "Just My Luck", 2, "Superman Returns", 3, "The Night Listener", 3, "You, Me and Dupree", 2}};
critics[5] = (struct cInfo) {"Jack Matthews",{"Lady in the Water", 3, "Snakes on a Plane", 4, "Superman Returns", 5, "You, Me and Dupree", 3.5}};
critics[6] = (struct cInfo) {"Toby",{"Snakes on a Plane", 4.5, "Superman Returns", 4, "You, Me and Dupree",1}};
topMatches(sim_D, critics, "Toby", 7);
return 0;
}
double sim_D(struct cInfo *prefs, const char *person1, const char *person2)
{
int i=0;
int x=0;
int next=0;
int p1;
int p2;
float X = 0;
float Y = 0;
float sumSq1 = 0;
float sumSq2 = 0;
float pSum = 0;
float num = 0;
float den = 0;
float Pscore = 0;
int nElements =0;
for (i=0;i<7;i++) {
if(strcmp(prefs[i].name, person1) ==0)
{
p1 = i;
}
else if(strcmp(prefs[i].name, person2) ==0)
{
p2 = i;
}
}
for (x=0;x<7;x++) {
for (next=0;next<7;next++)
{
if (!prefs[p1].movi[x].rating && !prefs[p2].movi[next].rating);
else if (strcmp(prefs[p1].movi[x].mName, prefs[p2].movi[next].mName) == 0)
{
X += prefs[p1].movi[x].rating;
Y += prefs[p2].movi[next].rating;
sumSq1 += pow(prefs[p1].movi[x].rating,2);
sumSq2 += pow(prefs[p2].movi[next].rating,2);
pSum += (prefs[p1].movi[x].rating*prefs[p2].movi[next].rating);
nElements++;
}
}
next = 0;
}
num = pSum-(X*Y/nElements);
den=sqrt((sumSq1-pow(X,2)/nElements)*(sumSq2-pow(Y,2)/nElements));
if(den ==0) return -1;
Pscore = num/den;
return Pscore;
}
void topMatches(sim_fp fp, struct cInfo *prefs, const char *person1, int num)
{
float scores[8];
char *buf;
int i=0;
for (i=0;i<num;i++)
{
if(strcmp(person1, prefs[i].name)==0)
{
continue;
}
scores[i] = fp(prefs, person1, prefs[i].name);
}
qsort(scores, num, sizeof(float), (*cmpFxn));
reverseFxn(scores, num);
printf("\n\n");
for(i=0;i<num;i++)
{
if (i == num-1)
{
printf("(%.5f, %s)", scores[num-1], prefs[num-1].name);
}
else
{
printf("(%.5f, %s),", scores[i], prefs[i].name);
}
}
}
void reverseFxn(float arr[], int num)
{
float scoresTmp[num];
int j;
for(j=0;j<num;j++)
{
scoresTmp[num-1-j] = arr[j];
}
for(j=0;j<num;j++)
{
arr[j]=scoresTmp[j];
}
}
int cmpFxn (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
scores[]数组中每个元素的值必须在-1到1的范围内。
2条答案
按热度按时间zujrkrfu1#
至少这些问题:
qsort()
是用float
和cmpFxn
的数组调用的,但是cmpFxn()
比较的是int
。* 1需要转换为
float
。* 2否不使用
return (*(float*)a - *(float*)b )
,因为float
差值可能会溢出int
范围或截断为0。sqrt(some_negative)
**注意轻微的浮点伪像,它会导致从数学上讲永远不应小于0的负数。
代码对于混合
float
和double
对象和函数是随意的。建议仅使用double
。出于 * 调试 * 目的,使用
#define float double
临时执行此操作非常简单。cmpFxn()
对于int
也是弱比较函数,因为它有int
溢出的风险。如果涉及到非数字,那么比较就会更加复杂,现在让我们假设情况并非如此。
7uhlpewt2#
1.意外的变量输出提示正在使用未初始化的数据。在
struct cInfo
中,您有一个成员struct mInfo movi[7];
,但在main()
中分配了其中的3到6个成员。通过从分配切换到初始化,那些未显式设置的记录将初始化为零。这似乎足以获得一致的输出。下面是示例输出:
1.(未修复)考虑使用空主体重写不常见的if表达式:
致:
如果你引入一些虚变量,它可以写得更简洁。
1.将
float
替换为double
并修复排序函数:double scores[8];
,您只迭代了num
,即7
,并且没有为person1对应的条目设置scores [i],因此我建议您这样做:1.(未修复)审核代码中是否存在幻值,如7和20。如果需要数组的大小,请使用常量、传入参数或
sizeof a / sizeof *a
(当作为参数传递时,请小心数组降级为指针)。