2020/4/4日常碎碎念
上一次写pta大概是将近一年前(我错了),才写了2道题,另外还错了一道…真的要花时间在编程上了!
· 6-2 多项式求值
此题需格外关注循环内部!注意i是从0到n,i=0时,f(x) = a[0]; i=1时,f(x) = a[0]+a[1]*x,···
正解:
double f(int n,double a[],double x)
{
int i;
double sum = a[0];//在这时就把i=0的情况考虑进去;这里之前是用的sum=0,想着可以直接用一个循环把结果弄出来,注意当i=0时不是x而是1!
for(i = 1;i <= n;i++) //这里也有点糊涂,一个循环足够了!
{
sum = sum + x * a[i]; //这俩顺序我也弄反了...以后遇见循环,内部的顺序也很重要!
x *= x;
}
return sum;
}
总结 :看见这种函数公式题目,提前在脑子里或者直接把过程展开写一个,再根据顺序一步步来。提交了很多次才正确,还是要练习自己的代码思维啊!
·6-3 多项式求和
本题要求实现一个函数,求给定的N个整数的和。
int Sum ( int List[], int N );
一个循环求和完事。
正解:
int Sum ( int List[], int N )
{
int i,sum = 0;
for(i=0;i<N;i++) //注意N是元素个数。
{
sum=sum+List[i];
}
return sum;
}
总结:哇,第一次这么快就提交正确,虽然题真的真的很简单哈哈,没啥好说的。
·6-4 求自定类型元素的平均
本题要求实现一个函数,求N个集合元素S[]的平均值,其中集合元素的类型为自定义的ElementType。
ElementType Average( ElementType S[], int N );
其中给定集合元素存放在数组S[]中,正整数N是数组元素个数。该函数须返回N个S[]元素的平均值,其值也必须是ElementType类型。
正解:
ElementType Average( ElementType S[], int N )
{
int i;
ElementType a=0,sum=0;
for(i=0;i<N;i++)
{
sum = sum + S[i];
}
a = (ElementType)sum/N;
return a;
}
总结: 这一题是对上一题的延续,把sum求出来再求平均数就ok了,要注意的是返回值也要是Elementype,所以要转换。
·6-5 求自定类型元素的最大值
本题要求实现一个函数,求N个集合元素S[]中的最大值,其中集合元素的类型为自定义的ElementType。
ElementType Max( ElementType S[], int N );
其中给定集合元素存放在数组S[]中,正整数N是数组元素个数。该函数须返回N个S[]元素中的最大值,其值也必须是ElementType类型。
正解1:
ElementType Max( ElementType S[], int N )
{
int i,j;
ElementType t;
for(i=0;i<N;i++) //我是用的冒泡排序法,取最大值,但很麻烦
{
for(j=i+1;j<N;j++) //这里还可以用for(j=n-1;j<N
{
if(S[i]<S[j])
{
t = S[i];
S[i] = S[j];
S[j] = t;
}
}
}
return S[0];
}
正解2:
ElementType Max( ElementType S[], int N )
{
int i = 0;
ElementType max = S[0]; //假设一开始是最大值
for(i=0;i<N;i++)
{
if(S[0]<S[i]) //利用假定最大值与后面的元素进行比较,若大于它交换即可。
max = S[i];
}
return max;
}
总结: 感觉自己还是想偏了,求最大值不需要进行一个排序再取第一个元素。直接假定最大值再比较交换就完事了。
·6-6 求单链表结点的阶乘和
本题要求实现一个函数,求单链表L结点的阶乘和。这里默认所有结点的值非负,且题目保证结果在int范围内。
函数接口定义:
int FactorialSum( List L );
其中单链表List的定义如下:
typedef struct Node *PtrToNode;
struct Node {
int Data; /* 存储结点数据 */
PtrToNode Next; /* 指向下一个结点的指针 */
};
typedef PtrToNode List; /* 定义单链表类型 */
思路:这一题实质上是一个求阶乘的问题,只不过需要考虑单链表的情况(咳…我数据结构还得再来 ) 。求阶乘这里是设置循环,从1开始自增至Data,然后相乘。最后加起来完事。
int FactorialSum( List L )
{
int i,sum=0,a;
while(L!=NULL)
{
a = 1;
for(i=1;i<=L->Data;i++)
a *= i;
sum += a;
L=L->Next;
}
return sum;
}
总结:
1、关于.和->:
a->b中a为指针,b为成员变量。
a.b中a为结构体变量/类对象,b为成员变量。
题中L是一个指针,所以用->来访问其成员Data,Next。
2、关于*和&:
*是指针所指地址处所保存的数值,
&是取一个变量的地址。
题中PtrToNode是指针类型,那么List也是指针,L就是指针。
3、外循环的条件为L!=NULL,搭配L=L->Next实现指针的更新,这里我最初是用的L->Next!=NULL,然后发生了段错误 。因为Next是要去到的下一个位置,你对下一个位置进行改变当然得不到正解噢,这里混淆了当前指针和下一个指针。
4、记住求阶乘的方法,这么多问题暴露出来不要气馁,弄懂才是真的。
·6-7 统计某类完全平方数
6-7 统计某类完全平方数 (20分)
本题要求实现一个函数,判断任一给定整数N是否满足条件:它是完全平方数,又至少有两位数字相同,如144、676等。
函数接口定义:
int IsTheNumber ( const int N );
其中N是用户传入的参数。如果N满足条件,则该函数必须返回1,否则返回0。
解题思路:
本题有两个条件:判断完全平方数、有两位数字相同。
1、对于判断完全平方数:利用sqrt(N),若是完全平方数,则该值为整数,其与sqrt(N)的int值是相等的。这就可以作为一个大循环。(我没这么用哈,不过差不多)
2、判断其中的两位数字相同:利用%10运算逐步得出其余数(其实就是从后往前的数),并用一个计数器数组进行计数,再将原数除以10,进入下一次循环。
正解:
int IsTheNumber ( const int N )
{
int m = sqrt(N),a=N;
int count[10]={0}; //数组初始化要{}。
int n;
if(sqrt(N)==m)
{
while(a) //a不能为0!!!!
{
n = a%10;
count[n]++; //计数器
a/=10;
}
}
else
return 0;
for(int i=0;i<10;i++)
{
if(count[i]>=2) //若有相同的,那么计数一定大于等于2。
return 1;
}
return 0;
}
总结:
首先要学会计数器计数来判断重复,此题不要求存储哈,数组计数就okk了。还有一些需要注意的,a必须要进行限定,因为0不能做除数(在这里卡了很久 ),数组初始化啥的。总之这道题很好,需要掌握!
·6-8 简单阶乘计算
这题没啥好说的,同理6-6。
·6-9 统计个位数字
本题要求实现一个函数,可统计任一整数中某个位数出现的次数。例如-21252中,2出现了3次,则该函数应该返回3。
函数接口定义:
int Count_Digit ( const int N, const int D );
其中N和D都是用户传入的参数。N的值不超过int的范围;D是[0, 9]区间内的个位数。函数须返回N中D出现的次数。
解题思路:
看起来和6-7一样,其实不然,这一题是统计D这个数在N中出现的次数,核心思想和6-7一样,取余。但需要考虑多方面
正解:
int Count_Digit ( const int N, const int D )
{
int a=N,count=0,c;
if(a<0) //当N是负数,那么得到的余数也是负数。所以需要其绝对值
{
a=-a;
}
if(a==0) //当N是0,且不能做除数,但0也确实出现了,则直接返回1。
return 1;
while(a) //一般情况下
{
c=a%10;
if(c==D)
count++;
a/=10;
}
return count;
}
总结:
要考虑多种情况,不要漏掉。