问答题1:下面两个结构体大小分别是多少?
struct One{ double d; char c; int i; } struct Two{ char c; double d; int i; }在 VS 2017 中,编译器默认对齐数为 8,在类 One 第一个 double 占8个字节,char 占4个字节, int占四个字节,所以总共占16字节.
在类 Two中第一个 char 占8个字节,double占 8个字节,int占 4个字节,最大对齐数是8,所以最终大小要是最大对齐数的整数倍,24个字节.
当把默认对齐数设置为 #pragma pack(4) 的时候,类占的字节数也可能发生变化. 对于类 One 来说, double 依然占8个字节,char占4个字节,int占4个字节,最终占 16字节.
类 Two 中,char占4个字节,这时候 double 占8字节,编译器默认对齐数为4,所以对齐数选择4的整数倍,double 占8个字节,int占4个字节,总共是 16 字节.
结构体对齐规则
第一个成员在与结构体变量偏移量为0的地址处
其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处,对齐数 = 编译器默认的一个对齐数与该成员大小的较小值,VS中默认的值为8,Linux中的默认值为 4
结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍
如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍
问答题2:下列程序输出什么?
char p1[15]= "abcd",*p2= "ABCD", str[50]= "xyz"; strcpy(str+2,strcat(p1+2,p2+1)); printf("%s",str);提示:strcat的作用是将两个字符串连接到一起,p1+2 = "cd",p2+1="BCD"所以 strcpy 第二个参数字符串是"cdBCD",函数strcpy的功能是进行拷贝覆盖.将字符查拷贝到源字符串.拷贝的位置是z字符的位置,所以最终 str 字符串是"xycdBCD"
答案:xycdBCD
问答题3:若运行时从键盘上输入9876543210 则上面程序在 gcc 编译器下的输出结果是?
int main(){ int a; float b,c; scanf("-?O",&a,&b,&c); printf("\na=%d,b=%d,c=%f\n",a,b,c); }提示: 答案:a=98,b=0,c=0.000000
编程题1:统计回文字符串
回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。花花非常喜欢这种拥有对称美的回文串,生日的时候她得到两个礼物分别是字符串A和字符串B。现在她非常好奇有没有办法将字符串B插入字符串A使产生的字符串是一个回文串。你接受花花的请求,帮助她寻找有多少种插入办法可以使新串是一个回文串。如果字符串B插入的位置不同就考虑为不一样的办法
例:A = "aba",B = "b" ,这里有4种把B插入A的办法:
(1) 在A的第一个字母之前:"baba" 不是回文 (2) 在第一个字母‘a’之后: "abba" 是回文 (3) 在字母‘b’之后: "abba" 是回文 (4) 在第二个字母’a’之后 "abab" 不是回文 ;所以满足条件的答案为2
#include <iostream> #include <string> #include <vector> using namespace std; int backword(string str1){ size_t end = str1.size() - 1; size_t begin = 0; while (begin < end) { if (str1[begin] != str1[end]){ return 0; } ++begin; --end; } return 1; } int main(){ string A, B; getline(cin, A); getline(cin, B); size_t num = 0; for (size_t i = 0; i < A.size()+1; ++i){ string temp = A; //这个接口就是在i的前面插入B,最后返回插入后的字符串 temp.insert(i, B); if (backword(temp)){ ++num; } } cout << num << endl; return 0; }循环次数应该是 字符串长度+1 否则,最后一次并没有插入到结尾.
python 3解法
import sys if __name__ == "__main__": sa = str(sys.stdin.readline().strip()) sb = str(sys.stdin.readline().strip()) count = 0 for i in range(len(sa)+1): newS = sa[:i] + sb + sa[i:] if newS == newS[::-1]: count += 1 print(count)编程题2:连续最大和
一个数组有 N 个元素,求连续子数组的最大和。 例如:[-1,2,1],和最大的连续子数组为[2,1],其和为 3
输入描述:输入为两行。 第一行一个整数n(1 <= n <= 100000),表示一共有n个元素 第二行为n个数,即每个元素,每个整数都在32位int范围内。以空格分隔。
输出描述:所有连续子数组中和最大的值。
例:输入:3 -1 2 1 输出:3
方法一:只保存最大的子序列和
#include <iostream> #include <vector> #include <algorithm> using namespace std; int main(){ int n; while(cin>>n){ vector<int>v(n,0); for(int i=0;i<n;++i){ cin>>v[i]; } int sum = 0; int res = v[0]; for(int i=0;i<n;++i){ if(sum>=0){ sum+=v[i]; }else{ sum = v[i]; } res = max(res,sum); } cout<<res<<endl; } return 0; }方法二:动态规划,保存每一个状态的子序列和,输出子序列的最大和
转义方程:dp[i] = max(dp[i-1],0)+v[i]; dp[i]: 代表至当目前的下标位置为止,最大的子序列和 . 从前一个值和0比较,取出最大值加源数组的下标元素.
res = max(res,dp[i]); 找出最大的子序列,保存下来.
#include <iostream> #include <vector> #include <algorithm> using namespace std; int main(){ int n; while(cin>>n){ vector<int>v(n,0); for(int i=0;i<n;++i){ cin>>v[i]; } vector<int>dp(n,0); dp[0] = v[0]; int res= v[0]; for(int i=1;i<n;++i){ dp[i] = max(dp[i-1],0)+v[i]; res = max(res,dp[i]); } cout<<res<<endl; } return 0; }