第一题
这个题目比较容易卡住的地方是cin.getline
这个函数的使用上面,目前实测下来这块如果不将第二个参数设置得较大一点以使得其读取到结束符号的话可能会阻塞后续的输入读取过程。这块感兴趣的同学可以读下这块的源码,这个链接讲解的还是不错的cin.getline源码解读,总而言之这个函数使用的时候需要主要让它读取到结束符号,嫌麻烦的同学可以用别的函数代替它。
随后这一题相对来说就没有什么思考难度了,按照题目意思一个个读取并输出就可以了。定义的时候可以用string存字符串,然后用一个int数组输出,也可以直接用char数组存字符串,随时读取随时输出,了解用法就好
#include <iostream>
using namespace std;
int main()
{
/*Start your code here*/
int n;
cin >>n;
string s;
cin >>s;
int* arr = new int[n];
for(int i=0;i<n;i++)
cin >>arr[i];
for(int i=0;i<n;i++)
cout <<s[arr[i]];
/*end your code*/
return 0;
}
第二题
这个题目意思还是很清楚的,重点是弄清楚指针可以直接修改数据本身,题目中输出的三个数字分别是myfun函数的返回值,y和x,那么我们按照题目给的要求将对应的数据填写进去就可以了
#include <iostream>
using namespace std;
int myfun(int* a, int* b);
// do not change main function
int main() {
int x, y;
cin >> x >> y;
cout << myfun(&x, &y) << ' ';
cout << y << ' ' << x;
return 0;
}
int myfun(int* a, int* b) {
// write your code here
int x = *a;
int y = *b;
*a = 2 * y;
*b = 3 * x;
return (x - y ) % 10;
}
第三题
这个题目了解一些指向数组的指针这个概念就好
-
第一小问:首先,需要明确*(a+1)存放的是什么,指向的是一个存放有5个元素的一维数组, (int)((a+1))表示将(a+1)强制类型转换成为(int*)类型,等价于将指针修改为指向a[1][0]的一个int指针,另外&a就是获取一个指向二维数组的指针,这个二维数组一共有2*5=10个元素:再将其转化为int类型的指针,也就是指向整个数组的下一个元素
-
第二小问就是一个简单的思维转换,一个char指针数组,里面的每一个元素就是一个char指针,也就是说每一个元素指向一个字符串,弄懂这一点就没啥问题了
cpp就是一个单纯的指向一个二维数组的指针 -
第三小问:题目需要修改下,有个符号漏掉了,这个题目本质上就是在说明
*
和[]
之间没啥大区别,一开始对应的数据分别是这样的
随后++cpp
这个执行的是cpp指向的内存增加一个数组元素大小的地址空间,比如一个char数组ch,* (ch+1)就比 * ch指向的区域多增加一个元素的地址,( cpp)指向的是一个二维数组,cpp++就是增加一个元素也就是一个字符串的长度了,所有要除数的时候cpp指向的是这样
-
第四题这个也是一样的思路,
&
就是将指向的地址的层数+1,&int就得到一个int指针,&(&int)就得到一个指向int指针的指针,也可以理解位指向int一维数组的指针,有点绕,这块了解就好,实际上的效果类似这样
-
这个地方还有一套有趣的指针题目,有兴趣的同学可以自己看看https://zhuanlan.zhihu.com/p/548605352
第四题
这个题目的算法都讲过好多遍了,这里就只强调一点,函数中的变量在函数return之后会被马上销毁,如果希望保存函数的某个变量,需要用new 的方法为其在程序堆中申请一块地址用于存储(你可以认为平时变量都放在系统的栈里面,变量生命周期结束之后它就会被回收,而new是被放在程序员自己的一个被称为堆的结构,系统不会管你往里面放啥,只要不越界,那这块的内存就有程序员自己维护)
#include <iostream>
#include <cstring>
#include<stdio.h>
using namespace std;
char * julian(int year, int day) {
//仅补全该函数,main函数保持不变
const char* months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"};
int daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool isLeap = false;
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
isLeap = true;
}
int max=365;
if(isLeap)
{
max++;
daysInMonth[1]++;
}
if(day < 1 || day > max)
return nullptr;
int month = 0;
for (int i = 0; i < 12; i++) {
if (day > daysInMonth[i]) {
day -= daysInMonth[i];
}
else {
month = i;
break;
}
}
char* result = new char[8];
sprintf(result, "%s %02d", months[month], day);
return result;
}
int main() {
int year, day;
char * res;
cin >> year >> day;
res = julian(year, day);
if (res) cout << res << endl;
delete [] res;
return 0;
}
第五题
这个题目读懂思路就好,直接用双指针模拟题目的操作。
- 设置slow和fast指针,fast用于判断是否是
*
号,如找到一个*
就抵消掉slow当前指向的一个字符;slow指针指向当前已经完成消除的字符串的最后一个字符 - slow的抵消是怎么做到呢,就是将当前字符置空(消除一个字符)并返回上一个位置
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
/*Start your code here*/
string s;
cin >>s;
int slow = 0, fast = 0;
while(fast < s.size()) {
if(s[fast] == '*') {
if(slow > 0)
--slow;
++fast;
}
else
s[slow++] = s[fast++];
}
s.resize(slow);
cout <<s;
/*end your code*/
return 0;
}