7-1 估值一亿的AI核心代码
1.题意
把输入的字符串按以下要求改写:
无论用户说什么,首先把对方说的话在一行中原样打印出来;
消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉;
把原文中所有大写英文字母变成小写,除了 I;
把原文中所有独立的 can you、could you 对应地换成 I can、I could—— 这里“独立”是指被空格或标点符号分隔开的单词;
把原文中所有独立的 I 和 me 换成 you;
把原文中所有的问号 ? 换成惊叹号 !;
2.题解
遍历字符串,用tolower函数把大写字母改为小写字母,用isalnum函数判断字符是否为数字或字母,若不是,则插入一个空格,用stringstream流把字符串切割成字符串数组,用于判断单词。
3.代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int maxn = 1e5 + 5; 5 int n; 6 int main() { 7 cin >> n; 8 getchar(); 9 while(n--) { 10 string s; 11 getline(cin, s); 12 cout << s << endl; 13 cout << "AI:"; 14 15 for(int i = 0; i < s.size(); i++) { 16 if(isalnum(s[i])) { 17 if(s[i] != 'I') { 18 s[i] = tolower(s[i]); 19 } 20 } else { 21 s.insert(i, " "); 22 i++; 23 } 24 if(s[i] == '?') { 25 s[i]='!'; 26 } 27 } 28 29 int cnt = 0; 30 string str[1005]; 31 stringstream ss(s); 32 while(ss >> s) { 33 str[cnt++] = s; 34 } 35 36 // for(int j = 0; j < cnt; j++) { 37 // cout << str[j] << endl; 38 // } 39 if(!isalnum(str[0][0])) { 40 cout << " "; 41 } 42 for(int i = 0; i < cnt; i++) { 43 if(!isalnum(str[i][0])) { 44 cout << str[i]; 45 } else if((str[i] == "can" || str[i] == "could") && str[i+1] == "you") { 46 cout << " I " << str[i]; 47 i++; 48 } else if(str[i] == "I" || str[i] == "me") { 49 cout << " you"; 50 } else { 51 cout << " " << str[i]; 52 } 53 } 54 cout << endl; 55 } 56 57 return 0; 58 }
7-3 N个数求和
1.题意
求n个分数形式的有理数的和,结果表示为假分数,如果整数部分为0,则只输出分数部分。
2.题解
注意输入,将每个数累加,每加完一个化简一次。
3.代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 int main() { 5 int n; 6 scanf("%d", &n); 7 8 ll sfz, sfm; 9 scanf("%lld/%lld", &sfz, &sfm); 10 int g = __gcd(sfz, sfm); 11 if(sfz) { 12 sfz /= g; 13 sfm /= g; 14 } 15 ll fz, fm; 16 for(int i = 1; i < n; i++) { 17 scanf("%lld/%lld", &fz, &fm); 18 ll l = fm * sfm / __gcd(fm, sfm); 19 sfz = l / fm * fz + l / sfm * sfz; 20 sfm = l; 21 g = __gcd(sfz, sfm); 22 if(g) { 23 sfm /= g; 24 sfz /= g; 25 } 26 } 27 28 if(sfz && sfz / sfm == 0) { 29 cout << sfz % sfm << "/" << sfm << endl; 30 } else if(sfz % sfm == 0) { 31 cout << sfz / sfm << endl; 32 } else { 33 cout << sfz / sfm << " " << sfz % sfm << "/" << sfm << endl; 34 } 35 36 return 0; 37 }
7-10 链表去重
1.题意
给定一个n个结点的链表,将结点的键值绝对值重复的结点从原链表中去除,形成两个新链表。
2.题解
用结构体存键值和下个结点地址,下标存当前地址。遍历链表,将需要剔除的结点地址存到一个数组,剩下的存到另一个数组。输出地址时注意格式,当n为1时特判。
3.代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 struct node { 5 int data; 6 int next; 7 }li[100005]; 8 int n,fi; 9 int ad1[100005]; 10 int ad2[100005]; 11 int f[100005]; 12 int main() { 13 scanf("%d%d", &fi, &n); 14 int a1, a2, v; 15 for(int i = 1; i <= n; i++) { 16 scanf("%d%d%d", &a1, &v, &a2); 17 li[a1].data = v; 18 li[a1].next = a2; 19 } 20 21 int ans1 = 0; 22 int ans2 = 0; 23 while(fi != -1) { 24 if(f[abs(li[fi].data)] == 0) { 25 f[abs(li[fi].data)] = 1; 26 ad1[ans1++] = fi; 27 fi = li[fi].next; 28 } else { 29 ad2[ans2++] = fi; 30 fi = li[fi].next; 31 } 32 } 33 34 for(int i = 0; i < ans1 - 1; i++) { 35 printf("%05d %d %05d ", ad1[i], li[ad1[i]].data, ad1[i + 1]); 36 } 37 printf("%05d %d -1 ", ad1[ans1 - 1], li[ad1[ans1 - 1]].data); 38 if(n > 1) { 39 for(int i = 0; i < ans2 - 1; i++) { 40 printf("%05d %d %05d ", ad2[i], li[ad2[i]].data, ad2[i + 1]); 41 } 42 printf("%05d %d -1 ", ad2[ans2 - 1], li[ad2[ans2 - 1]].data); 43 } 44 45 46 return 0; 47 }