本帖更新一些某校的编程真题,总体来说不难,考察的都是基本功,92高校大一期末的难度,不过有些细节颇为繁琐,各位还是需要一定程度上注意的~
目录
一.分数求和
二.大小写字母转换
三.判断当年天序
四.交替合并字符串
五.指针形态的冒泡排序
六.递归方式的倒序输出
七.黑色星期五
八.卡布列克运算
九.只出现一次的字符
十.产生0-1的随机数
一.分数求和
#include <iostream>
using namespace std;
int main(int argc, char** argv) {int n=0;cin>>n;double answer=0.000;for(int i=1;i<=n;i++){if(i%2!=0)answer+=(1.0/i);elseanswer-=(1.0/i);}cout<<answer<<endl;return 0;
}
过于简单,唯一需要注意的地方是需要用1.0除以第n项的值,如果用1除永远是1,因为整数除不尽!
二.大小写字母转换
复习两个知识点:
1.ASCII码你好意思还没背会? 小写字母反而大,大小相差32,大写A为65,小写a为97——一定要记清楚!
2.在初试考文件已经过时了,要是觉得不保险把这篇帖子的内容掌握即可:一篇入门C语言【文件】-CSDN博客文章浏览阅读609次,点赞3次,收藏6次。本科期间C语言的课本无论哪个版本都会有【文件】这一章节,不过好多学校基本上不讲或者就出一道选择题,讲得很浅,今天这篇详细总结一下这部分的知识~https://blog.csdn.net/jsl123x/article/details/141827614?spm=1001.2014.3001.5501
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char** argv) {string s;cin>>s;for(int i=0;i<=s.size()-1;i++)if(s[i]>=97&&s[i]<=122)s[i]-=32;cout<<"大写形态为:"<<s<<endl;FILE* p;p=fopen("./text.txt","r+");for(int i=0;i<=s.size()-1;i++)fputc(s[i],p);fclose(p);}
结果没什么问题:
这里博主用的是r+,也即十进制的读写,实际上也可以用a+也即二进制的读写,大家看题目要求~
三.判断当年天序
输入格式为2024 12 09,然后判断这是今年的第几天,很简单,只需要用一个类似哈希表的数组存储每个月的天数即可,如果是闰年可能会要多一天。
#include <iostream>
#include <string>
using namespace std; struct Date{int year;int month;int day;
};int main(int argc, char** argv) {int days[12]={31,28,31,30,31,30,31,31,30,31,30,31};int answer=0;Date date;cin>>date.year>>date.month>>date.day;if((date.year%400==0)||(date.year%100!=0&&date.year%4==0)) //闰年!days[1]++;//二月要多一天,别搞混数组下标for(int i=0;i<=date.month-2;i++)answer+=days[i];answer+=date.day;cout<<"这是"<<date.year<<"的第"<<answer<<"天~"<<endl; }
几点说明:
- 博主用的结构体,其实写完以后觉得有点多余。。。直接定义变量就行了,大家没必要学我
- days存放每个月不是闰年的天数
- 然后单独判断是否为闰年——可以整除400亦或整除4的同时不能整除100——如果是闰年2月要加一天
- 注意数组的下表,你要是晕,就直接把0位空出来从一开始赋值
- 最后加上当月天数即可~
测试后没什么问题~
四.交替合并字符串
唉,写得我都觉得乏味,但是做事一定要有头有尾哈哈~
#include <iostream>
#include <string>
using namespace std; int main(int argc, char** argv) {string A,B;cin>>A;cin>>B;int i=0,j=0; string target;while(i<=A.size()-1&&j<=B.size()-1){target+=A[i++];target+=B[j++];}while(i<=A.size()) target+=A[i++];while(j<=B.size()) target+=B[j++];cout<<target<<endl; FILE* p;p=fopen("./text.txt","r+");for(int i=0;i<=target.size()-1;i++)fputc(target[i],p);fclose(p);}
- 本质上就是用两个指针分别扫描两个字符串——各位一定要注意这种操作:在双指针类的题目,亦或什么n复杂度内实现字符串的逆转,经常会这么写。
- 此外就是扫描长度——这里是直到扫描完一个才单独扫描另一个,其实就是归并排序经典的写法。里面的【i++】各位一定要理清楚,这是先操作,再自增~
测试一下也没什么问题~
五.指针形态的冒泡排序
该说不说,有点“装神弄鬼”,姑且理解为他想考察指针数组吧。。。代码如下:
#include <iostream>
#include <string>
using namespace std; void BubbleSort(char* arr[],int length)
{for(int i=0;i<=length-1;i++)//忽略最后一位for(int j=i+1;j<=length;j++)if((*arr[i])>(*arr[j])){char* temp=arr[i];arr[i]=arr[j];arr[j]=temp;}
}
注意,上面传进来的是一个存储了元素地址的指针数组,而并非元素的值,因此:
- 我们在比较大小时,应该对指针进行解引用,不然比较的是地址的大小
- 但在交换的时候,只需要交换元素的地址即可~
- 此外,最外层循环可以少对比一位,这时冒泡的基本功了,别糊涂
int main(int argc, char** argv) {string target;cin>>target;char* arr[target.size()-1];for(int i=0;i<=target.size()-1;i++)arr[i]=&target[i];cout<<"排序前:"; for(int i=0;i<=target.size()-1;i++)cout<<(*arr[i])<<" "; cout<<endl; BubbleSort(arr,target.size()-1);cout<<"排序后:";for(int i=0;i<=target.size()-1;i++)cout<<(*arr[i])<<" "; return 0;
}
主函数测试一下。
没什么毛病~
六.递归方式的倒序输出
虽然递归的时间复杂度很高,实践中肯定不这样写,但是作为思维的练习值得关注~
#include<iostream>
using namespace std;void MyReverse(char* string)
{if (*string != '\0')MyReverse(string + 1); printf("%c", *string);
}int main()
{char arr[1000];cin>>arr;MyReverse(arr);return 0;
}
如果当前不为【\0】,就一直向后递归,直到为\0后再递归输出前面的字母,以此实现逆序~
这里就不输出到文件中了,和前面同理~
七.黑色星期五
没什么技术含量,就是编起来细节比较多,这种题只要能读懂题干,考出来不怕他~~
#include <iostream>
using namespace std;
int main(){int n=0,num=1; //1900.1.1是星期一因此,这个一般在题干会给出~ cin>>n; int year=1900,month,day=0;//从1900年开始向后遍历 int count[7]={0};int mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};for(int i=0;i<n;i++,year++){if((year%4==0&&year%100!=0)||year%400==0)mon[2]=29;for(month=1;month<13;month++)for(day=1;day<=mon[month];day++){if(day==13)count[num]+=1;num=(num+1)%7;}mon[2]=28;}cout<<count[6]<<endl;for(int i=0;i<5;i++)cout<<count[i]<<" ";cout<<count[5]<<endl;return 0;
}
八.卡布列克运算
还是和黑色星期五一样,没有任何思维上的难度,只是操作的技巧问题:
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;int main(){int n=0;cin>>n;vector<int>V;int max=0,min=0;int temp=0;while(n){temp=n%10;n/=10;V.push_back(temp);}sort(V.begin(),V.end()); //排序后为从小到大 for(int i=3;i>=0;i--){min+=V[3-i]*pow(10,i);max+=V[i]*pow(10,i); }cout<<max-min<<endl;
}
博主还是用了大量的STL标准库,各位想自己写一些底层操作也可以,博主就浅浅偷懒一下了~
测试如下,没问题:
九.只出现一次的字符
简单,博主的思维是可以使用结构体类型的哈希表,这样只需要遍历一次即可出结果——因为这里限制为英文字母,哈希表长度为26,遍历哈希表在N很大的情况下可以看为常数级别。还有一点要复习,字符串的0和大小字母A的差值为65,大家一定要记清楚,这一点可以有效帮助我们构造散列函数,也即如下这一段:
for(int i=0;i<=target.size()-1;i++){int temp=0; temp=target[i]-65;hash[temp].count++;if(hash[temp].first==-2)hash[temp].first=i;}
不过非常遗憾,可能是电脑的问题,博主写的代码出现了找不到的bug——即遍历哈希表会出现意想不到的情况,只能把哈希表冒泡排序了一遍。。。其实大家可以试试找出哈希表中first最小的值即可,复杂度为n。这段加了冒泡的是n方,也还行吧。。。
#include <iostream>
#include <string>
using namespace std;struct Hash{int count;int first;char tag;
};int main(){string target;cin>>target;Hash hash[26];for(int i=0;i<=25;i++){hash[i].count=0;hash[i].first=-2;hash[i].tag='A'+i;}for(int i=0;i<=target.size()-1;i++){int temp=0; temp=target[i]-65;hash[temp].count++;if(hash[temp].first==-2)hash[temp].first=i;} for(int i=0;i<=24;i++)for(int j=i+1;j<=25;j++)if(hash[i].first>=hash[j].first){Hash temp;temp=hash[i];hash[i]=hash[j];hash[j]=temp;}for(int i=0;i<=25;i++)if(hash[i].count==1){cout<<"第一个只出现一次的字母是:"<<hash[i].tag<<endl;break;}return 0;
}
测试一下,没什么bug:
十.产生0-1的随机数
非常冷门,了解一下即可:
#include <iostream>
#include <cstdlib>
using namespace std;
int main(int argc, char** argv) {for(int i=1;i<=10;i++) {double num=0;num=(double)rand()/100000;cout<<num<<endl; }return 0;
}