C语言实验6

本文档记录了对字符数组和数值相似度的计算方法,包括字符串长度的正确处理、最值计算的优化以及字符数组相似度和数值归一化的实现。在解决问题的过程中,强调了避免使用起泡法求最值、正确引入字符串函数库以及在循环中正确处理结束符的重要性。此外,还展示了四个示例代码,分别涉及字符串相似度、离散化、归一化和矩阵相似度计算。
摘要由CSDN通过智能技术生成

大一时写的,很菜

实验目的:

修改上次实验题第二题和第四题,求解字符数组的相似度与数值的相似度。

实例:

①实验题第二题

②实验题第四题

③实验题第三题

④实验题第五题

实验思路:

①修改求最值的方法

②修改求最值的方法

③定义两个字符型数组,利用循环嵌套,计算相似度。

④把每一列归一化,就得求出每一列的最大最小值,所以可以把最大最小值定义为数组,然后利用循环嵌套,求出不同行之间的相似度。

遇到的问题:

③输出的结果会把结束符也算上。

④输出相似度的结果呈现递增趋势。

解决方法:

①用最普通的方法求最值而不用起泡法。

②用最普通的方法求最值而不用起泡法。

③利用strlen函数计算字符型数组实际长度,再利用if函数剔除结束符的比较。

修改前:

#include<stdio.h>

int main()

{char a[10]={"I am Lee."},b[10]={"I am Liu."};

int si,S=0,i;

for(i=0;i<10;i++)

{if(a[i]==b[i])

si=1;

else

si=0;

S=S+si;

}

printf("%d",S);//结果为8,故结束符也算在内

}

修改后:

#include<stdio.h>

#include<string.h>

...

int m=strlen(a),n=strlen(b);//计算两个字符串的实际长度,并分别赋给m,n

printf("a的实际长度为%d\nb的实际长度为%d\n",m,n);

if(m>=n)

{

for(i=0;i<n;i++)

{if(a[i]==b[i])

si=1;

else

si=0;

S=S+si;

}

}

if(m<n)

{

for(i=0;i<m;i++)

{if(a[i]==b[i])

si=1;

else

si=0;

S=S+si;

}

}

printf("a与b的相似度为%d",S);//结果为除去结束符的相似度

}

④在循环完一次后,将S的值取0。

吸取的经验与教训:

①、②离散化与归一化中求最值时,不要用起泡法排序,会打乱原数组顺序。

③运用strlen等字符函数时,要引入string.h库,strlen函数测量的是实际长度。

若回车会对结果产生影响,用getchar函数存放这个´\n´。

④求绝对值时,要用fabs函数,而且需要引入math.h库。

 参考代码:

①:


#include<stdio.h>
int main()
{double a[10],max=-1021212021,min=1015513666,M;
int i,j;
printf("请输入10个数字\n");//注意每输入一个是数字要回车 
for(i=0;i<10;i++)
scanf("%lf",&a[i]);
for(i=0;i<10;i++)
{if(a[i]<=min)
min=a[i];
if(a[i]>=max)
max=a[i];
}
printf("max=%f\nmin=%f\n",max,min);
int k=3;
M=(max-min)/k;
for(j=0;j<=3;j++)
for(i=0;i<10;i++)
{if(min+M*j<+a[i]&&min+M*(j+1)>=a[i])
a[i]=j;
}
for(i=0;i<10;i++)
printf("%f   ",a[i]);
}

②: 


#include<stdio.h>
int main()
{double c[10],max=-1021212021,min=1015513666,M;
int i,j;
printf("请输入10个数字\n");//注意每输入一个是数字要回车 
for(i=0;i<10;i++)
scanf("%lf",&c[i]);
for(i=0;i<10;i++)
{if(c[i]<=min)
min=c[i];
if(c[i]>=max)
max=c[i];
}
printf("max=%f\nmin=%f\n",max,min);
for(i=0;i<10;i++)
c[i]=(c[i]-min)/(max-min);
for(i=0;i<10;i++)
printf("%f   ",c[i]);
}

③: 


#include<stdio.h>
#include<string.h>
int main()
{char a[10],b[10];
int si,S=0,i;
printf("请输入一个长度小于10的字符串\n");
scanf("%s",a);
char h=getchar();//放回车字符
printf("请再输入一个长度小于10的字符串\n");
scanf("%s",b);
int m=strlen(a),n=strlen(b);//计算两个字符串的实际长度,并分别赋给m,n
printf("a的实际长度为%d\nb的实际长度为%d\n",m,n);
if(m>=n)
{
for(i=0;i<n;i++)
{if(a[i]==b[i])
si=1;
else
si=0;
S=S+si;
}
}
if(m<n)
{
for(i=0;i<m;i++)
{if(a[i]==b[i])
si=1;
else
si=0;
S=S+si;
}
}
printf("a与b的相似度为%d",S); //结果为除去结束符的相似度
}

④: 


#include<stdio.h>
#include<math.h>
int main()
{double a[6][6]={1,2,3,4,5,6,
             7,8,9,10,11,12,
             13,14,15,16,17,18,
			   19,20,21,22,23,24,
              25,26,27,28,29,30,
			   31,32,33,34,35,36};
int n;
printf("如果想用现成的数组,请输入1;如果想另外赋值,请输入2\n");
scanf("%d",&n);
int i,j,k;
if(n==2)
{printf("请输入36个数字\n");
for(i=0;i<6;i++)
for(j=0;j<6;j++)
scanf("%lf",&a[i][j]);
}
printf("原数组为\n");
for(i=0;i<6;i++)
 {for(j=0;j<6;j++)
 printf("%.2f      ",a[i][j]);//输出原数组
 printf("\n");
 }
  double max[6]={-10000000,-10000000,-10000000,-100000000,-11000000000,-100000000},
         min[6]={11000000,10000000,10000000,1000000,1000000,1000000};
   for(j=0;j<6;j++)
   for(i=0;i<6;i++)
   {if(a[i][j]>=max[j])
     max[j]=a[i][j];
    if(a[i][j]<=min[j])
     min[j]=a[i][j];
   }
    for(j=0;j<6;j++)
     printf("第%d列最小值为%f\n",j,min[j]);//输出每一列的最小值
    for(j=0;j<6;j++)
     printf("第%d列最大值为%f\n",j,max[j]);//输出每一列的最大值
     printf("归一化的数组为\n");
    for(i=0;i<6;i++) 
     {for(j=0;j<6;j++)
       {a[i][j]=(a[i][j]-min[j])/(max[j]-min[j]);
       printf("%f  ",a[i][j]);//输出每列归一化后的数组
       }
       printf("\n");
     }
      double Sij,S=0;
      printf("各行之间的相似度为\n");
      for(i=0;i<6;i++)
      for(j=0;j<6;j++)
      {
        if(i!=j)
        {for(k=0;k<6;k++)
         {if(fabs(a[i][k]-a[j][k])<=0.25)
          Sij=1-4*fabs(a[i][k]-a[j][k]);
         else
          Sij=0;
          S=S+Sij;
          }
         printf("第%d行与第%d行的相似度为%f\n",i,j,S);
        }
         S=0;
        }
      }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值