算法与编程实验报告

算法与编程实验

实验报告

第一题

一、题目:统计字母的使用频率

二、目的与要求

1.目的:

通过编写程序统计字母的使用频率,培养学生综合利用C语言进行程序设计的能力,熟悉字符串的操作方法,加强函数的运用,提高软件系统分析能力和程序文档建立、归纳总结的能力。

2.基本要求:

1)要求用C语言编程,在Visual C++环境下调试完成;

2)要求按照程序功能分成几个功能模块来实现,各个功能模块分别使用函数来完成;

3)要求应用本课所讲授的程序设计语言知识来解决问题

三、设计方法和基本原理

1.课题功能描述

本程序的功能,就是要统计英文字母的使用频率。

2.问题详细描述

为统计英文字母的使用频率,输入一个不包括空格的由英文字母组成的字符串,长度不超过200个字符。统计26个英文字母的使用频率,不区分大小写。最后按使用频率从大到小输出字母(小写字母)和使用频率(出现的次数)。

3.问题的解决方案

按照程序要求,本程序应采用模块化设计方法,设计几个功能模块。例如(仅供参考):

u  将字符串中的大写字母转换为小写字母

u  统计输入的字符串中字母的使用频率

u  按使用频率从大到小进行排序

主函数中控制输入、函数调用和输出。

四、主要技术问题的描述

根据三的分析,主要问题在于:

1)  为统计字母的使用频率,定义一个长度为26的int数组存放所统计的各个字母的使用频率。

2)  在统计字母的使用频率时,不要使用if语句或switch语句,利用字母的ASCII码与数组元素下标之间的关系来求得。

3)  按使用频率从大到小进行排序时,建议使用指针数组更为方便。

五、创新要求

实现程序功能后,可进行创新设计:

1)  使用多文件,即主函数和各个函数分别存放在不同的.c文件中,在头文件中进行函数原型声明。

2)  读入一篇英文文档,并对其进行字母频率分析。

  

   六、问题的解决

Ø  流程图

                     

                            开始

 

                                             

                

                                输入一段字符串

 

   

 


                                                         N

                                       判断是否为

                                        小写字母

 

                                                                     大写字母转化

                                                   Y                  为小写字母

 

                                                                   

 

                                        统计字母

                                        使用频率

 

                                         

                                      根据字母使用频率

                                        排序并输出

               

                            

                                          结束

Ø  主要函数描述

??????????????????????????????????????????????????????????????????????????

1.char m.c函数:实现大小写转换函数

 char m(char y)      

 {

   if(y>='A'&&y<='Z')

   y=y+32;

   return(y);

 }

??????????????????????????????????????????????????????????????????????????   

2.主函数:

#include<stdio.h>

void main()

{

 char m(char y);

 char a[200],b[26];        

 int c[26]={0};

 char x;

 int i,j,k;

 printf("请输入一个不包括空格的由英文字母组成的字符串:\n");

 scanf("%s",&a);

 for(i=0;i<200;i++)           //大小写全部转换

 {

  a[i]=m(a[i]);

 }

 for(j=0,x='a';j<26;j++,x++)    //大循环,字母一个一个判断过去

 {

  for(i=0;i<200;i++)            //i代表输入最多200个

  {

   if(a[i]==x)                 //判断输入的数字为哪个字母

   {

    c[j]++;

   }

  }

 }

 for(k=0;k<26;k++)              //给b[k]附上初值,即a,b,c,d、、、  

  b[k]='a'+k;

 for(i=0;i<25;i++)              //比较大小,让字母使用次数从大到小排列

 {

  for(j=25;j>i;j--)    

  {

   if(c[j]>c[j-1])              //比较大小,然后交换

   {

    k=c[j-1];

    c[j-1]=c[j];

    c[j]=k;

    x=b[j-1];

    b[j-1]=b[j];

    b[j]=x;

   }

  }

 }

printf("以下是输出结果:\n");

for(k=0;k<26;k++)

printf("字母%c使用的次数是:%d\n",b[k],c[k]);

}

???????????????????????????????????????????????????????????????????????????????

运行结果:

??????????????????????????????????????????????????????????????????????????????

Ø  主要技术问题

     一、在统计字母的使用频率时,定义一个长度为26的int数组存放所统计的各个字母                                                                                                                                                                                                                                                的使用频率。  

     二、 在统计字母的使用频率时,不要使用if语句或switch语句,利用字母的ASCII码与数组元素下标之间的关系来求得。

Ø  实验心得

1.这是实习的第一个程序,由于刚过暑假,c语言忘得差不多了,刚开始很不顺手,错误百出。

2.通过这次“统计字母频率”算法编程的实习,我学习并掌握了函数的调用、形参为指针或数组的传递方法以及读取文件数据的方法,巧用ASCII码,针对字符串中字母与ASCII码关系灵活处理使用频率,使代码更为简便。但是由于在一开始没有想到好的对字母排序的方法导致了走了很多弯路,对于题目中要求的指针数组使用起来还不是很有把握,所以选择了比较保守的冒泡排序。

  

第二题

一、题目:序列小游戏

二、目的与要求

1.目的:

(1)让学生体会到鸽巢原理(或抽屉原理)的乐趣并使学生更加系统地理解和掌握C语言的函数间参数传递方法、数组和指针的应用等编程技巧。培养学生综合利用C语言进行科学计算,使学生将所学知识转化为分析和设计简单实际问题的能力,学会查资料和工具书。  

(2)提高学生建立程序文档、归纳总结的能力。 

2.基本要求:

(1)要求用C语言编程,在Visual C++环境下调试完成; 

(2)要求按照程序功能分成几个功能模块来实现,各个功能模块分别使用函数来完成; 

(3)要求应用本课所讲授的程序设计语言知识来解决问题.

三、设计方法和基本原理

1. 课题功能描述  

任意给定5个数字,其中必定存在3个数字已经有序(或者升序,或者降序),找出这5个数字中最长的升序或降序序列。  

例如:1,7,5,3,9。则{1,7,9},{1,5,9},{1,3,9}都是最长的升序序列;  

而{7,5,3}是最长的降序序列。  

再如:1,3,2,5,7。最长的升序序列为{1,3,5,7}和{1,2,5,7}。  

2. 问题的解决方案:  

自动生成各种可能的序列,对于5个数字所有可能的序列为:  {0,1,2,3}、{0,1,2,4}、{0,1,3,4}、{0,2,3,4}、{1,2,3,4}  {0,1,2}、{0,1,3}、{0,2,3}、{1,2,3}  {0,1,4}、{0,2,4}、{1,2,4}  {1,3,4}  

{2,3,4}、{0,3,4}  

考察各种可能的序列是否升序或是降序,若是则打印;

四、创新要求

    在基本要求达到后,进行创新设计,10个数据,必定会有至少4个数据已经有序(或升序或降序),找出最长的升序或降序序列

   五、问题的解决               

Ø  主要函数描述

???????????????????????????????????????????????????????????????????????????????

      1.主函数:

      #include<stdio.h>

      int m=0;

      void main( )

     {  

             int s[5],i;

             printf("请输入五个数字:\n");  

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

             {

                  scanf("%d",&s[i]);

              }

              if(s[0]<s[1]&&s[1]<s[2]&&s[2]<s[3]&&s[3]<s[4])             //判断五位升序

         {       

                     printf("最长的升序序列:%d,%d,%d,%d,%d\n",s[0],s[1],s[2],s[3],s[4]);                                                             

            }

              else

            {

                  n1(s);                    

            }

             if(m==0)

               {

                      n2(s);              

               }

             if(s[0]>s[1]&&s[1]>s[2]&&s[2]>s[3]&&s[3]>s[4])                //判断五位降序                    

            {     

                  printf("最长的降序序列:%d,%d,%d,%d,%d\n",s[0],s[1],s[2],s[3],s[4]);                                                                                  

            }

             else

              {

                     n3(s);     

              }

             if(m==0)

            {

                 n4(s);      

            }

      }

???????????????????????????????????????????????????????????????????????????????

     2.void n1(int s[])函数:实现判断输入的数字是否为四位升序。

     void n1(int s[])          

    {

           int i,j,k,t;

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

          {

                  for(j=i+1;j<3;j++)

                  {

                           for(k=j+1;k<4;k++)

                           {

                                    for(t=k+1;t<5;t++)

                                    {      if(s[i]<s[j]&&s[j]<s[k]&&s[k]<s[t])

                                    {

                                           printf("最长的升序序列:%d,%d,%d,%d\n",s[i],s[j],s[k],s[t]);

                                                    

                                    }

                                    }

                           }

                  }

         }

}

???????????????????????????????????????????????????????????????????????????????

     3.void n2(int s[])函数:实现判断输入的数字是否为三位升序。

       void n2(int s[])              

      {

             int i,j,k;

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

           {

                  for(j=i+1;j<4;j++)

                  {

                           for(k=j+1;k<5;k++)

                    {

                                    if(s[i]<s[j]&&s[j]<s[k])

                                    {

                                             printf("最长的升序序列:%d,%d,%d\n",s[i],s[j],s[k]);

                                    }

                           }

                  }

         }

}

??????????????????????????????????????????????????????????????????????????????

     3.void n3(int s[])函数:实现判断输入的数字是否为四位降序。

      void n3(int s[])              

     {

             int i,j,k,t;

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

           {

                   for(j=i+1;j<3;j++)

                   {

                            for(k=j+1;k<4;k++)

                           {

                                    for(t=k+1;t<5;t++) 

                                    {   

                                             if(s[i]>s[j]&&s[j]>s[k]&&s[k]>s[t])

                                    {

                                    printf("最长的降序序列:%d,%d,%d,%d\n",s[i],s[j],s[k],s[t]);

                        

                                    }

                                    }

                      }

                   }

            }

   }

???????????????????????????????????????????????????????????????????????????????

     4.void n4(int s[])函数:实现判断输入的数字是否为三位降序。

      void n4(int s[])            

     {

            int i,j,k;

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

            {

                   for(j=i+1;j<4;j++)

                   {

                           for(k=j+1;k<5;k++) 

                           {

                                    if(s[i]>s[j]&&s[j]>s[k])

                                    {

                                             printf("最长的降序序列:%d,%d,%d\n",s[i],s[j],s[k]); 

                                    }

                             } 

                    }

             }

     }

???????????????????????????????????????????????????????????????????????????????

运行结果:  

???????????????????????????????????????????????????????????????????????????????

Ø  主要技术问题

在实现该功能时要进行五位升序、四位升序、三位升序、五位降序、四位降序、三位降序的判定,为了得到结果,提高程序的可读性,要尽可能的保证思维清晰,用最少的语句来实现该程序的功能。

Ø  实验心得

       1.通过本题,定义了函数,学习并掌握了函数的定义、调用以及数组的运用和多重

          循环的使用。

        2.本程序的可读性不是最佳,由于C语言没有学的很好,只能用这种比较麻烦、死  

          板、冗长的程序。

   

第三题

   一、题目:判断点时候在三角形内

二、目的与要求

1.目的:

在一个二维坐标系中,已知三角形顶点的坐标,那么对于坐标系中的任意一点,如何判断该点是否在三角形内(点在三角形边上即可)?通过编写程序实现该功能,培养学生分析问题和算法设计的能力,利用C语言进行程序设计的能力及归纳总结的能力。

2.基本要求:

1)要求用C语言编程,在Visual C++环境下调试完成;

2)要求按照程序功能分成几个功能模块来实现,各个功能模块分别使用函数来完成。

三、设计方法和基本原理

1.课题功能描述

   如果在一个二维坐标系中,已知三角形顶点的坐标,那么对于坐标系中的任意一点,如何判断该点是否在三角形内(点在三角形边上即可)?通过编写程序实现该功能。

2.问题的解决方案

  按照程序要求,本程序应采用模块化设计方法,设计几个功能模块。例如(仅供参考):

1)用户可以自由设定三角形(三个顶点:A,B,C);

2)程序可以自动判定三个顶点是否构成三角形;

3)用户输入D点坐标;

4)程序判断出D和三角形ABC的关系。

      主函数中控制输入、函数调用和输出。

四、主要技术问题的描述

     根据三的分析,主要问题在于:

            1)怎样判定A,B和C点构成三角形;

            2)怎样设计算法判定D是否位于三角形内部并验证之。

五、创新要求

     实现程序功能后,可进行创新设计:

           (1)程序可以判定D点是否位于三角形边界上;

           (2)计算点D与三角形ABC质心之间的距离;

           (3)画出三角形ABC与D的关系示意图。   

   六、问题的解决

Ø  流程图

                                         开始 

 

                                

 

                                    输入A、B、C三点

 

            

                               Y      A、B、C是否         N

                输入点D               构成三角形

   

 


              判断点D是否        N                     

              在△ABC内

 

 

              点D在                                    点D不在

             △ABC内                              △ABC内   

             

             

                                  结束

Ø  主要函数描述

??????????????????????????????????????????????????????????????????????????

#include<stdio.h>

#include<math.h>

void main()

{

    int i,m=0;                             

    double a,b,c,d,e,f,l;   

    double s,s1,p[4][2];

    printf("请输入三角形的三个顶点ABC:\n");   

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

        scanf("%lf,%lf",&p[i][0],&p[i][1]);                        //输入ABC三个顶点

    a=sqrt(pow(p[0][0]-p[1][0],2)+pow(p[0][1]-p[1][1],2));            //计算出AB

    b=sqrt(pow(p[0][0]-p[2][0],2)+pow(p[0][1]-p[2][1],2));            //计算出BC

    c=sqrt(pow(p[2][0]-p[1][0],2)+pow(p[2][1]-p[1][1],2));            //计算出AC

         if(a+b>c && b+c>a && a+c>b)

         {

                  m=1;                                    //当m为1时,构成三角形,进入判断点D

                  printf("构成三角形!\n");

         }

         else

         {

                  m=0;

                  printf("不能构成三角形!\n");                //m为0时输出不能够成三角形

         }

         if(m==1)

         {

    l=(a+b+c)/2;                                   //运用海伦公式S^2=p(p-a)(p-b)(p-c) 

    s=sqrt(l*(l-a)*(l-b)*(l-c));

    printf("请输入点D:\n");

    scanf("%lf,%lf",&p[3][0],&p[3][1]);

    d=sqrt(pow(p[3][0]-p[0][0],2)+pow(p[3][1]-p[0][1],2));        //计算由D产生的三条边

    e=sqrt(pow(p[3][0]-p[1][0],2)+pow(p[3][1]-p[1][1],2));

    f=sqrt(pow(p[3][0]-p[2][0],2)+pow(p[3][1]-p[2][1],2));

    l=(a+d+e)/2;                 //将三个三角形相加,如果等于大的三角形,则在这个三角形里面

    s1=sqrt(l*(l-a)*(l-d)*(l-e));

    s=(b+d+f)/2;

    s1+=sqrt(l*(l-b)*(l-d)*(l-f));

    s=(c+e+f)/2;

    s1+=sqrt(l*(l-c)*(l-e)*(l-f));

    printf("经判断:");

    if(s==s1)

         {

       printf("点在三角形内\n");

            }

    else

         {

       printf("点不在三角形内\n");

            }

         }

}

??????????????????????????????????????????????????????????????????????????

运行结果:

??????????????????????????????????????????????????????????????????????????

Ø  主要技术问题

   1.要先判断三角形是否构成才能进行判断点与三角形之间的关系。

   2.在判断点与三角形之间的关系时,应该怎么设计算法。

   3.怎么样可以在进行判断三角形是否成立以后减少算法增强程序的可读性。

    

Ø  实验心得

   1.通过本题,学会并掌握了如何使用数组。

   2.本题在判断D点是否在三角形ABC内运用的是面积法,判断语句是s=s1,这是存

     在一定缺陷的,因为计算机在判断s与s1是否相等时若

     s=10.00000,s1=10.00001,计算机判定为点D不在三角形内。因此,在老师的

     指导下将判断语句改成fabs(s-s1)在一定误差范围内。

相关推荐