Loading... # 机试day6 ## 首字母大写 [首字母大写_牛客题霸_牛客网 (nowcoder.com)](https://www.nowcoder.com/practice/91f9c70e7b6f4c0ab23744055632467a?tpId=61&tqId=29529&tPage=2&ru=/kaoyan/retest/1002&qru=/ta/pku-kaoyan/question-ranking) **描述** 对一个字符串中的所有单词,如果单词的首字母不是大写字母,则把单词的首字母变成大写字母。 在字符串中,单词之间通过空白符分隔,空白符包括:空格(' ')、制表符('\t')、回车符('\r')、换行符('\n')。 **输入描述**: 输入一行:待处理的字符串(长度小于100)。 **输出描述**: 可能有多组测试数据,对于每组数据, 输出一行:转换后的字符串。 ~~~ 输入: if so, you already have a google account. you can sign in on the right. 输出: If So, You Already Have A Google Account. You Can Sign In On The Right. ~~~ 思路:设置flag位,初始为1,表示句子首字母得大写;如果碰到空白符(使用isspace判断),则flag置1,否则置0;这样碰到flag=1表明上一个字符位空白符,此字符该大写了 ~~~c++ #include <cstdio> #include <iostream> #include <string> #include <cctype> using namespace std; int main() { string s; while (getline(cin ,s)) { int flag = 1; for (int i = 0; i < s.size(); i++) { if (isspace(s[i])) { flag = 1; printf("%c", s[i]); } else { if (flag && 'a' <= s[i] && s[i] <= 'z') { printf("%c", s[i] + 'A' - 'a'); } else { printf("%c", s[i]); } flag = 0; } } } } ~~~ 也可以直接toupper转换 ## 浮点数加法 [浮点数加法_牛客题霸_牛客网 (nowcoder.com)](https://www.nowcoder.com/practice/ddec753f446e4ba4944e35378ba635c8?tpId=61&tqId=29551&tPage=3&ru=/kaoyan/retest/1002&qru=/ta/pku-kaoyan/question-ranking) **描述** 求2个浮点数相加的和 题目中输入输出中出现浮点数都有如下的形式: P1P2...Pi.Q1Q2...Qj 对于整数部分,P1P2...Pi是一个非负整数 对于小数部分,Qj不等于0 **输入描述**: 对于每组案例,每组测试数据占2行,分别是两个加数。 **输出描述**: 每组案例是n行,每组测试数据有一行输出是相应的和。 输出保证一定是一个小数部分不为0的浮点数 ~~~ 输入: 0.111111111111111111111111111111 0.111111111111111111111111111111 输出: 0.222222222222222222222222222222 ~~~ 思路:难点在于小数点前后位数不同的情况下得补0,因此采用了获取小数点位置,然后分别计算前后带0的数目。选取带0最多的作为标准,少的补0。然后视为字符串一位位相加,如果大于10,则flag置1并加到下一位 ~~~c++ #include <iostream> #include <string> #include <math.h> using namespace std; int main() { string a, b; while (cin >> a >> b) { int pos1 = a.find('.'); int pos2 = b.find('.'); int num1 = max(pos1, pos2); int num2 = max(a.size()-pos1-1, b.size()-pos2-1); a.insert(0, num1-pos1, '0'); b.insert(0, num1-pos2, '0'); a.insert(a.size(), num1+num2+1-a.size(), '0'); b.insert(b.size(), num1+num2+1-b.size(), '0'); int sum = 0, flag = 0; for (int i = a.size() - 1; i >= 0; i--) { if (a[i] != '.') { sum = (a[i] - '0') + (b[i] - '0') + flag; a[i] = sum % 10 + '0'; flag = sum / 10; } } cout << a << endl; } } ~~~ ## 后缀子串排序 **描述** 对于一个字符串,将其后缀子串进行排序,例如grain 其子串有: grain rain ain in n 然后对各子串按字典顺序排序,即: ain,grain,in,n,rain **输入描述**: 每个案例为一行字符串。 **输出描述**: 将子串排序输出 ~~~ 输入: grain 输出: ain grain in n rain ~~~ 思路:使用algorithm库的sort来排序,传入两个字符串比较第一位、第二位直到两个字符不同,返回较小的排前面 ~~~c++ #include <iostream> #include <string> #include <algorithm> using namespace std; bool compare(string x, string y) { int i = 0; while (1) { if (x[i] == y[i]) { i++; continue; } else { return x[i] < y[i]; } } } int main() { string s; while (cin >> s) { string ss[s.size()]; for (int i = 0; i < s.size(); i++) { ss[i] = s.substr(i, s.size()); } sort(ss, ss+s.size(), compare); for (int i = 0; i < s.size(); i++) { cout << ss[i] << endl; } } } ~~~ 汗!!!发现不用写compare,sort会自动排序,修改后如下 ~~~c++ #include <iostream> #include <string> #include <algorithm> using namespace std; int main() { string s; while (cin >> s) { string ss[s.size()]; for (int i = 0; i < s.size(); i++) { ss[i] = s.substr(i, s.size()); } sort(ss, ss+s.size()); for (int i = 0; i < s.size(); i++) { cout << ss[i] << endl; } } } ~~~ ## 字符串变形 [字符串变形_牛客题霸_牛客网 (nowcoder.com)](https://www.nowcoder.com/practice/c3120c1c1bc44ad986259c0cf0f0b80e?tpId=295&tqId=44664&ru=/exam/oj&qru=/ta/format-top101/question-ranking&sourceUrl=%2Fexam%2Foj) **描述** 对于一个长度为 n 字符串,我们需要对它做一些变形。 首先这个字符串中包含着一些空格,就像"Hello World"一样,然后我们要做的是把这个字符串中由空格隔开的单词反序,同时反转每个字符的大小写。 比如"Hello World"变形后就变成了"wORLD hELLO"。 数据范围: $1\le n\le 10^6$ , 字符串中包括大写英文字母、小写英文字母、空格。 进阶:空间复杂度 $O(n)$ , 时间复杂度 $O(n)$ **输入描述**: 给定一个字符串s以及它的长度n(1 ≤ n ≤ 10^6) **返回值描述**: 请返回变形后的字符串。题目保证给定的字符串均由大小写字母和空格构成。 ~~~ 输入: "This is a sample",16 返回值: "SAMPLE A IS tHIS" 输入: "nowcoder",8 返回值: "NOWCODER" ~~~ ### 法1:先大小写转换,再逆向整个,最后逆向单词 思路:可以设置一个reverse函数用来反转一个单词/句子,对于如何根据空格划分单词,使用start接收一个单词开始位置,碰到空格记录i,即可截取句子中的单词(注意,**最后一个单词**需要判断是否到结尾,再起一个分支来处理) ~~~c++ #include <cctype> #include <string> string reverse(string s) { char c; for (int i = 0, j = s.size() - 1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } return s; } class Solution { public: string trans(string s, int n) { for (int i = 0; i < n; i++) { if (isupper(s[i])) { s[i] = tolower(s[i]); } else if (islower(s[i])) { s[i] = toupper(s[i]); } } s = reverse(s); int start = 0; string new_s; for (int i = 0; i < n; i++) { if (isspace(s[i])) { new_s = reverse(s.substr(start, i - start)); s.erase(start, i - start); s.insert(start, new_s); start = i + 1; } else if (i == n - 1) { new_s = reverse(s.substr(start, i + 1 - start)); s.erase(start, i + 1 - start); s.insert(start, new_s); } } return s; } }; ~~~ 其中reverse函数可以由algorithm的reverse替换 ps:经法2启发,在结尾加个空格会更简单 ~~~c++ class Solution { public: string trans(string s, int n) { for (int i = 0; i < n; i++) { if (isupper(s[i])) { s[i] = tolower(s[i]); } else if (islower(s[i])) { s[i] = toupper(s[i]); } } s = reverse(s); s += ' '; int start = 0; string new_s; for (int i = 0; i < n + 1; i++) { if (isspace(s[i])) { new_s = reverse(s.substr(start, i - start)); s.erase(start, i - start); s.insert(start, new_s); start = i + 1; } } s.erase(n, 1); return s; } }; ~~~ ### 法2:栈! 思路: 1. 使用栈stack,定义数据类型为string 2. 使用str接收每个单词,同时s后加一个空格好判断 3. 栈先入后出,因此可以实现句子单词逆序,而不需要反转单词本身,快了很多 ~~~c++ #include <cctype> class Solution { public: string trans(string s, int n) { stack<string> sk; string str; s.push_back(' '); // s后加空格 for (int i = 0; i <= n; i++) { if (s[i] == ' ') { sk.push(str); str = ""; } else { if (s[i] >= 'a' && s[i] <= 'z') { str += (s[i] - 'a' + 'A'); } else { str += (s[i] - 'A' + 'a'); } } } string ans; while (!sk.empty()) { ans += sk.top(); // 取栈顶值 sk.pop(); // 弹出栈顶 ans.push_back(' '); // 加空格 } ans.pop_back(); // 去除最后的空格 return ans; } }; ~~~ ### 法3:超级无敌改进法1 思路:就是reverse,使用官方库好了,甚至不需要加空格,以及不需要开辟新空间接收反转的字符串 ~~~c++ #include <cctype> class Solution { public: string trans(string s, int n) { reverse(s.begin(), s.end()); int i = 0, j = 0; while (i < n) { j = i; while (j < n && s[j] != ' ') { if (isupper(s[j])) { s[j] = tolower(s[j]); } else if (islower(s[j])) { s[j] = toupper(s[j]); } j++; } reverse(s.begin() + i, s.begin() + j); i = j + 1; } return s; } }; ~~~ ## 最长公共前缀 **描述** 给你一个大小为 n 的字符串数组 strs ,其中包含n个字符串 , 编写一个函数来查找字符串数组中的最长公共前缀,返回这个公共前缀。 数据范围: $0\le n\le 5000$, $0\le len(strs_i)\le 5000$ 进阶:空间复杂度 $O(1)$,时间复杂度 $O(n∗len)$ ~~~ 输入: ["abca","abc","abca","abc","abcc"] 返回值: "abc" 输入: ["abc"] 返回值: "abc" ~~~ 思路:以第一个作为参照一个个比 ~~~c++ class Solution { public: /** * * @param strs string字符串vector * @return string字符串 */ string longestCommonPrefix(vector<string>& strs) { string s; if (!strs.size()) return ""; for (int i = strs[0].size(); i >= 0; i--) { int flag = 0; for (int j = 0; j < strs.size(); j++) { if (i > strs[j].size() || strs[0].substr(0, i) != strs[j].substr(0, i)) { flag = 0; break; } else { flag = 1; } } if (flag) return strs[0].substr(0, i); } return ""; } }; ~~~ nice!看了下和官方思路差不多,大多数思路差不多 最后修改:2023 年 06 月 04 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,请随意赞赏