c语言典型问题处理方法小结

c语言典型问题处理方法小结

  • 循环问题

1)、数论问题

1、求素数

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

    if(a%i==0)

    break;

  if (a==i)

    printf("yes\n");

  else

第一个if判断是否能被234……直到本身整除。

第二个if判断是否只能被本身整除。

printf("no\n");

素数概念:

对于某个整数a>1,如果它仅有平凡约数1a,则我们称a为素数(或质数)

整数 1 被称为基数,它既不是质数也不是合数。

整数 0 和所有负整数既不是素数,也不是合数。

2、求最大公约数和最小公倍数

a

  if(a>b)

  {

    t=a;

    a=b;

    b=t;

  }

  for(i=a;i>=1;i--)

    if(a%i==0&&b%i==0)

    break;

  printf("largest common divisor:%d\n",i);

  printf("least common multiple:%d\n",(a*b)/is);

b、辗转相除法求解

    a1=a;

    b1=b;

    while(a%b!=0)

    {

      t=a%b;

      a=b;

      b=t;

    }

    printf("largest common divisor:%d\nleast common    multiple:%d",b,a1*b1/b);

3、求完数

   一个数如果恰好等于它的因子之和,这个数就称为完数

     例如:6的因子为123,而6123,因此6完数

for(a=1;a<=1000;a++)

   {

   s=0;

   for(i=1;i<=a;i++)

     if (a%i==0)

     {

     s+=i;

     if(s>=a)

     break;

     }

  if(s==a)

  printf("%d\t",a);

注意S=0所放的位置

  }

4、分解质因数

      将一个整数写成几个质因数的连乘积,如: 输入36,则程序输出36=2*2*3*3

解一、

看似简单,但要自己完整地写出来还真不容易!!!

竟然还动用了goto语句,正好可以熟悉一下goto语句的用法!!!

main()

{

  int a,z,i;

  clrscr();

  scanf("%d",&a);

判断下一个数开始有要重新从2

开始了。所以用loop语句回到for语句,这是for语句仍从2初始化。

2开始的原则不变,变的是a的值。

  loop: for(z=2;z<=a;z++)

       {

判断是否为质数

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

         if(z%i==0)

         break;

判断是否为a的质因数

         if(z==i)

           if(a%z==0)

           {

           k++;

           if(k==1)

           printf("%d=%d",a1,z);

用计数器来解决每行输入不同的问题。

           else

           printf("*%d",z);

           a/=z;

           goto loop;

           }

       }

}

解二:

main()

 {   int n, k=2, isfirst=1;

      printf("Input n=");       scanf("%d",&n);

      while(k<=n)

      if(n%k==0)

         {  if(isfirst) { printf("%d=%d", n, k); isfirst=0; }

             else printf("*%d",k);

             n/=k;

          }

      else k++;

      printf("\n");

}

5、从键盘输入两个整数,输出这两个整数的商的小数点后所有1000位整数

 for(i=1;i<=1000;i++)

    {

    t=a%b;

主要体会除法运算中小数形成的原因

解决这类题目从本质出发

    printf("%d",t*10/b);

    a=t*10;

    }

  printf("\n");

6、编程计算并输出两个带分数的差。带分数就是由一个整数和一个真分数合成的数,两个带分数(整数、分子、分母均大于0)从键盘输入,且带分数1大于带分数2,输入格式为:整数1[分子1/分母1],整数2[分子2/分母2]。差要求化简,整个输出样式为(如差为整数,则无分数部分,如差的整数为0,则无整数部分):

整数1[分子1/分母1]-整数2[分子2/分母2]=整数[分子/分母]

例如:输入:12[6/35],8[3/5]

输出:12[6/35]-8[3/5]=3[4/7]

又如:输入:6[2/3],4[12/18]

      输出:6[2/3]-4[12/18]=2

又如:输入:9[7/8],9[3/8]

      输出:9[7/8]-9[3/8]=[1/2]

main()

{

  int z1,fz1,fm1,fz1x,z2,fz2,fm2,fz2x,z,fz,fm,fzx,i;

  scanf("%d[%d/%d],%d[%d/%d]",&z1,&fz1,&fm1,&z2,&fz2,&fm2);

    fz1x=z1*fm1+fz1;

    fz2x=z2*fm2+fz2;

    fm=fm1*fm2;

    fz=fz1x*fm2-fz2x*fm1;

    for(i=fm;i>=2;i--)

     if(fm%i==0&&fz%i==0)

     {

       fz/=i;

       fm/=i;

     }

    z=fz/fm;

    fzx=fz%fm;

    if(fzx==0)

    printf("%d[%d/%d]-%d[%d/%d]=%d\n",z1,fz1,fm1,z2,fz2,fm2,z);

    else if(z==0)

    printf("%d[%d/%d]-%d[%d/%d]=[%d/%d]\n",z1,fz1,fm1,z2,fz2,fm2,fzx,fm);

    else

    printf("%d[%d/%d]-%d[%d/%d]=%d[%d/%d]\n",z1,fz1,fm1,z2,fz2,fm2,z,fzx,fm);

}

2)近似问题

1、书P122习题4-6

注意千万不要忘记添加

#include “math.h”

#include "math.h"

main()

{

  float x,j=1,k,s,so;

  int n;

  scanf("%f",&x);

  s=x;

  so=x+1;

  for(n=1;fabs(s-so)>1e-6;n++)

  {

    for(k=1;k<=n;k++)

    j*=k;

  so=s;

  if(n%2!=0)

  s-=x*x*x/((2*n-1)*j);

  else

  s+=x*x*x/((2*n-1)*j);

  }

  printf("%f\n",s);

2、解方程问题:

编程用二分法求解方程x3+4x2-10=0的解。

#include "math.h"

main()

{

可以省略此句

  float x,x1=1,x2=4,f1=-1,f;

  /*f1=x1*x1*x1+4*x1*x1-10;*/

  while(fabs(x2-x1)>1e-6)

    {

    x=(x1+x2)/2;

    f=x*x*x+4*x*x-10;

可以用/*if(f*f1<0)*/替代

    if(f>0)

    x2=x;

    else

    x1=x;

    }

  printf("%f\n",x);

}

3)枚举法

4)数列问题

二、数组问题

1)排序问题

1、从小到大排序

main()

{

 int a[10],i,j,t;

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

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

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

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

       if(a[j]>a[j+1])

       {

       t=a[j+1];

       a[j+1]=a[j];

       a[j]=t;

       }

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

 printf("%d ",a[i]);

 printf("\n");

注意排序问题:

1、须迅速,熟练,无差错

经常插入在程序中间

2、现使用最大数下沉冒泡法

还可以使用最小数上浮冒泡法

3j控制前面一个数和后面一个数一一比较。由于是最大数下沉,i+1j仍要从0开始。

4i控制这样的操作一共要做多少次

5、注意i j的控制次数

}

2、从大到小排序

main()

现使用最大数上浮冒泡法

还可使用最小数下沉冒泡法

{

 int a[10],i,j,t;

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

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

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

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

   if(a[j]>a[j-1])

   {

    t=a[j-1];

    a[j-1]=a[j];

    a[j]=t;

   }

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

 printf("%d ",a[i]);

}

2)二维数组

三、字符或字符串输入输出问题

1)字符打印

1、打印*

此类题的溯源为书P122  4.111),其他题都是它的拓展

         for (i=1;i<=n;i++)                     一共要输出的行数

            {

            for(j=1;j<=i;j++)                    每行要打印的*

            printf("*");

            printf("\n");

            }

a

*

**

***

****

解题要点:

此类题关键在于找到每行要打印的个数和行数的关系。此题j==i

       

j==n-i+1

b

****

***

**

*

         for(i=1;i<=n;i++)               一共要输出的行数

          {

          for(j=1;j<=n-i;j++)           控制空格数

          printf(" ");

          for(k=1;k<=i;k++)            每行要打印的*

          printf("*");

          printf("\n");

          }

c

   *

  **

 ***

****

解题要点:

在出现空格的时候,在找到每行要打印的‘*’个数和行数的关系后,还应找到空格和行数的关系,分不同的参数进行循环。此题k==i j==n-i

       

j==i-1

k==n-i+1

d

****

 ***

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

   {

   for(j=1;j<=n-i;j++)

   printf(" ");

   for(k=1;k<=2*i-1;k++)

   printf("*");

   printf("\n");

   }

  **

   *

e

   *

  ***

 *****

*******

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

   {

   for(j=1;j<=n-i;j++)

   printf(" ");

   for(k=1;k<=2*i-1;k++)

   printf("*");

   printf("\n");

   }

   for(i=1;i<=n-1;i++)

   {

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

   printf(" ");

   for(k=1;k<=2*(n-1-i)+1;k++)

   printf("*");

   printf("\n");

   }

   *

  ***

 *****

*******

 *****

  ***

   *

2、打印9*9乘法表

解题要点:注意寻找行与列的规律。

i*j

i代表列

j代表行

for(i=1;i<=9;i++)

{

    for(j=1;j<=9;j++)

     printf("%-3d ",i*j);  注意输出格式的控制

     printf("\n");

    }

3、九九乘法表

1    2    3    4    5    6     7    8     9

2    4    6    8   10   12    14   16    18

3    6    9   12   15   18    21   24    27

9   18   27   36   45   54    63   72    81

4、杨晖三角形

1

1   1

1   2   1

1   3   3   1

1   4   6   4   1

1   5   10  10  5   1

1   6   15  20  15  6   1

2)字符串打印问题

for(i=1;i<=7;i++)

    {

    a[i][1]=1;

    a[i][i]=1;

    }

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

      for(j=2;j<=i-1;j++)

      a[i][j]=a[i-1][j-1]+a[i-1][j];

 

gets(a);

 puts(a);

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

   {

   t=a[5];

   for(j=5;j>0;j--)         

     a[j]=a[j-1];

     a[0]=t;

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

   printf("%c",a[k]);

   printf("\n");

   }

1

注意交换过程和把所有的数后移一位的方法

A B C D E Z

Z A B C D E

E Z A B C D

D E Z A B C

C D E Z A B

B C D E Z A

注意点:

  1. int i,不要误打成char i
  2. a[i]!=’\0’不要误打成i!=’\0’
  3. 逻辑与&&
  4. 单引号内表示字符
  5. 不加单引号的字符型数据为其ASCII

2、输入一字符串小写换大写

char a[81];

  int i;

  gets (a);

  for(i=0;a[i]!='\0';i++)

    if(a[i]>='a'&&a[i]<='z')

    a[i]-=32;

  puts (a);

3、逆序输出

gets (a);

 c=strlen(a);

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

     {

     t=a[i];

     a[i]=a[c-1-i];

     a[c-1-i]=t;

     }

 puts(a);

注意此问题的思想方法:

要求一组数的逆序实质就是将其对称换位

for(int i=n;i>=0;i--)               蓝色部分可以简写为绿色部分

cout<<a[i-1];

4、如输入:ab1   @3,;z

   输出:ab1

注意点:

1、‘= =

2while语句的使用处体会

3、全面考虑问题

         @3,;z

gets(a);

  while(a[0]==' ')

  for(i=0;a[i]!='\0';i++)

    a[i]=a[i+1];

  for(i=0;a[i]!='\0';i++)

if(a[i]==' '&&a[i+1]!=' ')           

    printf("\n");

    else if(a[i]==' '&&a[i+1]==' ')

      {

      for(k=i;a[k]!='\0';k++)

      a[k+1]=a[k+2];

      i--;

      }

    else

printf("%c",a[i]);

5、输入3个字符串,按从小到大排序输出这3个字符串。 使用一个两维数组贮存多个字符串

char a[81][81];

注意:如何使用一个两维数组贮存多个字符串

  int i,j;

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

  gets(a[i]);

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

  puts(a[i]);

注意:

1scanf("%d%s",&n,str) 其中%s为字符串格式

2、逐个给字符串赋值的方法见书140页。

   不可fori=0a[i]!=’\0’;i++

3str[i]=str[i]-'A'+10;

4pow函数

5、任何进制转为十进制的方法

6、输入一个整数n和一个字符串str,计算并输出n进制数str的值。

   如输入:7    16

则输出:13               (16)7=(13)10

如输入:16   3A

则输出:58               (3A)16=(58)10

#include "stdio.h"

#include "math.h"

main()

{

  char str[81];

  int n,i,s=0,t;

  clrscr();

  scanf("%d%s",&n,str);

    for(i=0;str[i]!='\0';i++)

      if(str[i]<='Z'&&str[i]>='A')

      str[i]=str[i]-'A'+10;

      else

      str[i]=str[i]-'0';

    t=strlen(str);

    for(i=0;str[i]!='\0';i++)

      s+=str[t-i-1]*pow(n,i);

  printf("%d",s);

}

编写程序,将一个十进制正整数转换成十六进制数。

                                               注意类比

#include <stdio.h>

main()

{

       char a[20];

       int x,i=0,j;

       clrscr();

       scanf("%d",&x);

       while(x)

       {

          if(x%16>=10&&x%16<=15)

            a[i]=x%16-10+'A';

          else

            a[i]=x%16+'0';

              x=x/16;

              i++;

       }

       for(j=i-1;j>=0;j--)

              printf("%c",a[j]);

              printf("\n");

}

7、输入一个字符串,将其中的缩写形式展开,并输出展开后的该字符串。所谓展开缩写形式就是将其中由大小写字母或数字构成的形如"a-f""U-Z""3-8" 的形式展开成为 "abcdef" "UVWXYZ" "345678",若出现"f-a""A-7""9-5"等形式则不予理睬。例如:

输入:qwe246e-hA-d$-%4-7A-Dz-xp-R4-0

输出:qwr246efghA-d$-%4567ABCDz-xp-R4-0

main()

{

  char a[81];

  int i,c,s,k,t;

  gets(a);

  for(i=0;a[i]!='\0';i++)

    if(a[i]=='-')      if(a[i-1]<a[i+1]&&(a[i-1]>='A'&&a[i+1]<='Z'||a[i-1]>='a'&&a[i+1]<='z'||a[i-1]>='0'&&a[i+1]<='9'))

注意:

  1. 必须在结尾处加上结束标记,才能实现puts语句。
  2. 加上结束标记后for(i=0;a[i]!='\0';i++)语句才能实现。
  3. 逻辑&&与逻辑||的优先级。
  4. s=strlen(a)摆放的位置。

      {

      s=strlen(a);

      c=a[i+1]-a[i-1];

      t=i+c-2;

      for(k=s-1;k>i;k--)

       a[k+c-2]=a[k];

       a[s-1+c-2+1]='\0';

      for(;i<=t;i++)

      a[i]=a[i-1]+1;

      }

   puts(a);

}

补充:

循环:

求:a+aa+aaa+…..的值

#include<iostream.h>

void main()

{

       int a,n,i=1,sn=0,tn=0;

       cout<<"input a and n"<<endl;

       cin>>a>>n;

       while(i<=n)

       {

              tn=tn+a;

              sn+=tn;

              a*=10;i++;

       }

       cout<<"the answer is "<<sn<<endl;

}

      

两个乒乓球队进行比赛,各出3人。甲队为A,B,C;已对是X,Y,Z;已经抽签决定比赛名单。有人向队员大厅比赛的名单。A说他不和X比,C说他不和X,Z比。请编程序找出3对赛手的名单。

#include<iostream.h>

void main()

{

       char i,j,k;

       for(i='X';i<='Z';i++)

              for(j='X';j<='Z';j++)

                     if(i!=j)

                            for (k='X';k<='Z';k++)

                                   if(i!=k&&j!=k)

                                          if(i!='X'&&k!='X'&&k!='Z')

                                                 cout<<"A--"<<i<<"   B--"<<j<<"   C--"<<k<<endl;

}

枚举

口袋中有红,黄,蓝,白,黑5种颜色的球若干。每次从口袋中任意取出3歌,问得到3种不同颜色球的可能取法,输出每种排列的情况。

#include<iostream.h>

#include<iomanip.h>    //C语言中不用加这句

void main()

{enum color{red ,yellow ,blue,white, black};

       color pri;

       int i,j,k,n=0,loop;

       for(i=red;i<=black;i++)

              for(j=red;j<=black;j++)

                     if(i!=j)

                     {

                            for (k=red;k<=black;k++)

                                   if((k!=i)&&(k!=j))

                                   {

                                          n++;

                                          cout<<setw(3)<<n;         //setw是输出格式的限定

                                          for(loop=1;loop<=3;loop++)

                                          {

                                                 switch(loop)

                                                 {

                                                 case 1:pri=color(i);break;

                                                 case 2:pri=color(j);break;

                                                 case 3:pri=color(k);break;

                                                 default:break;

                                                 }

                                          switch(pri)

                                          {

                                          case red:cout<<setw(8)<<"red";break;

                                          case yellow:cout<<setw(8)<<"yellow";break;

                                          case blue:cout<<setw(8)<<"blue";break;

                                          case white:cout<<setw(8)<<"white";break;

                                          case black:cout<<setw(8)<<"black";break;

                                          default:break;

                                          }

                                   }

                                   cout<<endl;

                                   }

                     }

                     cout<<"total:"<<n<<endl;

}

      

数组:

不用strcat函数,编写程序,将两个字符串串接起来。

#include<iostream>

using namespace std;

void main()

{

       int i=0;

       char a[20],b[10];

       gets(a);gets(b);

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

              if(a[i]=='\0')break;

       for(int j=0;j<10;j++)

       {a[i]=b[j];i++;if(b[j]=='\0')break;}

       cout<<a<<endl;

}

输入一行字符,统计其中有多少个单词,单词之间用空格分开。

#include<iostream>

using namespace std;

void main()

{

       char string[100];

       int i,num=0,word=0;

       char c;

       gets(string);

       for(i=0;(c=string[i])!='\0';i++)

              if(c==' ')word=0;

              else if(word==0)

              {word=1;num++;}

       cout<<"There are "<<num<<" words"<<endl;

}

给出年,月,日,计算该日是该年的第几天

#include<iostream>

using namespace std;

void main()

{

       int sum_day(int,int);   //函数声明

       int leap(int year);                    //函数声明

       int year,month,day,days;

       cout<<"input date"<<endl;

       cin>>year>>month>>day;

       cout<<year<<"/"<<month<<"/"<<day;

       days=sum_day(month,day);

       if(leap(year)&&month>=3)days++;           //若是闰年,且在3月以后,则加一天

       cout<<"is the "<<days<<" th day in this year"<<endl;

}

int sum_day(int month,int day)

{

       int i;

       int day_tab[12]={31,28,31,30,31,30,31,31,30,31,30,31};

       for(i=0;i<month-1;i++)

              day+=day_tab[i];

       return(day);

}

int leap(int year)

{

       int leap;

       leap=year%4==0&&year%100!=0||year%400==0;

       return(leap);

}

这道题虽然用了你们不考的函数调用,但是相信你还是看的懂的,这道题主要是体现了知识的综合运用

杨辉三角(不做了,相信你会的吧)

3*4矩阵中的最大最小元素(用循环,也不难

输入一个矩阵的各个元素,求转置矩阵(用循环进行赋值,然后再定义个矩阵,然后进行赋值,例如:若a矩阵为2*3,则for(i=0;i<=1;i++)

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

                                                                                    b[j][i]=a[i][j];

输出魔方阵,就是每一行每一列和对角线数字之和相等。(方阵阶数由终端输入,但只需是奇数即可)

#include<iostream.h>

#include<iomanip.h>

void main()

{

       int a[16][16],i,j,k,p=1,n;

       while(p==1)

       {

              cout<<"enter n(from 1 to 15)";

              cin>>n;

              if((n!=0)&&(n<=15)&&(n%2!=0))p=0;

       }

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

              for(j=1;j<=n;j++)

                     a[i][j]=0;

              j=n/2+1;

              a[1][j]=1;

              for(k=2;k<=n*n;k++)

              {

                     i--;j++;

                     if(i<1&&j>n)

                     {i=i+2;j--;}

                     else

                     {if(i<1)i=n;if(j>n)j=1;}

                     if(a[i][j]==0)

                            a[i][j]=k;

                     else

                     {i=i+2;j--;a[i][j]=k;}

              }

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

              {for(j=1;j<=n;j++)

                     cout<<setw(5)<<a[i][j];

              cout<<endl;

              }

}这道题目当时觉得很有难度,刚刚看到时没有思路

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫一样的女子245

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值