统计回文字符串,连续最大和

    xiaoxiao2023-11-25  166

    问答题

    问答题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; }
    最新回复(0)