当前位置:   article > 正文

【牛客网】华为机试题(00、C++版本)_牛客网华为编程题答案 c+++

牛客网华为编程题答案 c+++

华为机试题,本来以为对一些基础的程序还是有点信心的;不过不练不知道,一练吓一跳。平时虽然也都码程序,但是一到机试题就各种乱七八的不适应。还是要加强一下练习。

 

1、字符串最后一个单词的长度

题目描述:计算字符串最后一个单词的长度,单词以空格隔开。

例如:输入Hello World,输出5。

解答:这道题主要是练习一下字符串的输入和指定字符的查找。

  1. #include <iostream>
  2. using namespace std;
  3. #include <string>
  4. int main(){
  5. string s;
  6. getline(cin,s);
  7. int j=0;
  8. for(int i=s.length()-1; i>=0; i--){
  9. if(s[i]!=' '){
  10. j++;
  11. }else{
  12. break;
  13. }
  14. }
  15. cout<<j;
  16. return 0;
  17. }

如果熟悉C++的各种函数的话,可以使用String的rfind()函数(寻找某个字符最后一次出现的序号)、find()函数(寻找某个字符第一次出现的序号)。

  1. #include <iostream>
  2. using namespace std;
  3. #include <string>
  4. int main() {
  5. string s;
  6. getline(cin, s);
  7. int j;
  8. j = s.length() - 1 - s.rfind(' ');
  9. cout << j;
  10. return 0;
  11. }

 

2、计算字符个数

题目描述:写出一个程序,接受一个有字母和数字以及空格组成的字符串,和一个字符,然后输出输入字符串中含有该字符的个数。不区分大小写。

例如:输入ABCDEF A,输出1。

解答:这道题主要是练习一下大小写的改写。

  1. #include <iostream>
  2. using namespace std;
  3. #include <string>
  4. int main()
  5. {
  6. string s;
  7. getline(cin, s);
  8. char c;
  9. cin >> c;
  10. int count = 0;
  11. for (int i = 0; i<s.length(); i++) {
  12. if (s.at(i)== toupper(c)|| s.at(i) == tolower(c))
  13. count++;
  14. }
  15. cout << count;
  16. return 0;
  17. }

或者,也可以使用C语言来编写:

  1. #include <stdio.h>
  2. #include <string.h>
  3. int main()
  4. {
  5. char str[10000];
  6. char ch;
  7. int len = 0;
  8. gets(str);
  9. ch = getchar(); //scanf("%c",&ch);
  10. for(int i = 0; i < strlen(str); i++)
  11. {
  12. if(str[i] == ch || str[i] == ch -32 || str[i] == ch + 32)
  13. len++;
  14. }
  15. printf("%d\n",len);
  16. return 0;
  17. }

注意一点:在C++中字符串长度可以用.size()、.length()方法;而strlen(char *),若放入一个字符串常量是可以求长度的,但是若放入一个字符串变量则不行。这三个方法都不计算字符串最后的结束符'\0',甚至可以说是,遇到第一个字符串结束符'\0'就停止计算个数了。

注意:如果使用sizeof()来计算字符串变量的长度是不正确的!C++标准库中的string类的对象在创建时会保留额外的内存空间,以便于用户调用append成员函数或者给string对象重新赋值时不会发生越界行为。所以,最小默认为28。

sizeof 操作函数类型:

  1. int f1(){return 0;};
  2. double f2(){return 0.0;}
  3. void f3(){}
  4. cout<<sizeof(f1())<<endl;     // f1()返回值为int,因此被认为是int
  5. cout<<sizeof(f2())<<endl;     // f2()返回值为double,因此被认为是double
  6. cout<<sizeof(f3())<<endl;     // 错误!无法对void类型使用sizeof
  7. cout<<sizeof(f1)<<endl;      // 错误!无法对函数指针使用sizeof
  8. cout<<sizeof*f2<<endl;      // *f2,和f2()等价,被认为是double

 

3、明明的随机数

题目描述:明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤1000),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作(同一个测试用例里可能会有多组数据,希望大家能正确处理)。

例如:输入11 10 20 40 32 67 40 20 89 300 400 15,输出10 15 20 32 40 67 89 300 400。

解答:原本做这道题就是很机械地排序来做:

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int count;
  6. while (cin >> count) {
  7. int temp, flag = 0;
  8. int num[1000];
  9. for (int i = 0; i < count; i++) {
  10. cin >> num[i];
  11. }
  12. for (int i = 0; i < count - 1; i++) {
  13. for (int j = i + 1; j < count - flag; j++) {
  14. if (num[i] > num[j]) {
  15. temp = num[i];
  16. num[i] = num[j];
  17. num[j] = temp;
  18. }
  19. if (num[i] == num[j]) {
  20. flag++;
  21. for (int k = j; k < count - 1; k++) {
  22. num[k] = num[k + 1];
  23. }
  24. j--;
  25. }
  26. }
  27. }
  28. for (int i = 0; i < count - flag; i++) {
  29. cout << num[i] << endl;
  30. }
  31. }
  32. return 0;
  33. }

看得出来,算法复杂度很高。后来发现了一个很巧妙的方法,通过计数排序来完成:

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. int N, n;
  5. while (cin >> N) {
  6. int a[1001] = { 0 };
  7. while (N--) {
  8. cin >> n;
  9. a[n] = 1;
  10. }
  11. for (int i = 0; i < 1001; i++)
  12. if (a[i])
  13. cout << i << endl;
  14. }
  15. return 0;
  16. }

这个方法在之前大疆的笔试题中也遇到了:【嵌入式基础】2014大疆嵌入式笔试题(附超详细解答,上篇)

 

4、字符串分隔

题目描述:连续输入两个字符串,请按长度为8拆分每个字符串后输出到新的字符串数组; 长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。 

例如:输入abc 123456789,输出abc00000 12345678 90000000。

解答:拆分字符串,很传统的方法是:

  1. #include <iostream>
  2. using namespace std;
  3. #include <string>
  4. void fun(string s)
  5. {
  6. char str[13][8];
  7. int num = 0, count = 0;
  8. for (int j = 0; j < s.length(); j++) {
  9. if (count == 8) {
  10. count = 0;
  11. num++;
  12. }
  13. str[num][count] = s.at(j);
  14. count++;
  15. }
  16. while (count != 8) {
  17. str[num][count] = '0';
  18. count++;
  19. }
  20. for (int i = 0; i < num + 1; i++) {
  21. for (int j = 0; j < 8; j++) {
  22. cout << str[i][j];
  23. }
  24. cout << endl;
  25. }
  26. }
  27. int main()
  28. {
  29. string s1, s2;
  30. getline(cin, s1);
  31. getline(cin, s2);
  32. fun(s1);
  33. fun(s2);
  34. return 0;
  35. }

这样做虽然也能获得答案,但是很明显,还是有点绕的。其实可以利用string的substr()方法来解决:

  1. #include <iostream>
  2. using namespace std;
  3. #include <string>
  4. void fun(string s)
  5. {
  6. while (s.size() > 8) {
  7. cout << s.substr(0, 8) << endl;
  8. s = s.substr(8);
  9. }
  10. cout << s.append(8 - s.size(), '0') << endl;
  11. }
  12. int main() {
  13. string s1, s2;
  14. getline(cin, s1);
  15. getline(cin, s2);
  16. fun(s1);
  17. fun(s2);
  18. return 0;
  19. }

瞬间感觉整个程序都清晰了许多!下面分析一下string的substr()和substring()的区别:

 

  • stringvar.substr(start , [length]):索引,长度
  • strVariable.substring(start, end):索引,索引

说明:

 

  • 如果substr()函数的length为0或负数,将返回一个空字符串。如果没有指定该参数,则子字符串将延续到 stringvar 的最后;
  • substring()方法将返回一个包含从start 到最后(不包含end)的子字符串的字符串;
  • substring()方法使用start和end两者中的较小值作为子字符串的起始点。

 

5、进制转换

题目描述:写出一个程序,接受一个十六进制的数值字符串,输出该数值的十进制字符串。(多组同时输入 )

例如:输入0xA,输出10。

解答:采取进制转换的计算方法,但是需要注意的是这里的方法不是那种死板的计算方法:

  1. #include <iostream>
  2. using namespace std;
  3. #include <string>
  4. int main() {
  5. string str;
  6. while (getline(cin, str)) {
  7. long num = 0;
  8. for (int i = 2; i < str.length(); ++i) {
  9. if (str[i] >= '0' && str[i] <= '9')
  10. num = num * 16 + (str[i] - '0');
  11. else
  12. num = num * 16 + (str[i] - 'A' + 10);
  13. }
  14. cout << num << endl;
  15. }
  16. return 0;
  17. }

但是这样的做法,不能够对输入的数值进行十六进制的判断。当然,本题还有一个非常投巧的方法,利用输入的办法来进行数制转换,而且可以完成十六进制的判断(hex:十六进制、oct:八进制、dev:十进制)

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int a;
  6. while(cin>>hex>>a){
  7.      cout<<a<<endl;
  8. }
  9. }

利用C语言也可以实现:

  1. #include <stdio.h>
  2. int main()
  3. {
  4. int a;
  5. while (scanf_s("%X", &a)) {
  6. printf("%d\n", a);
  7. }
  8. }

 

6、质数因子

题目描述:输入一个正整数,按照从小到大的顺序输出它的所有质数的因子,最后一个数后面也要有空格。

例如:输入180,输出2 2 3 3 5 。

解答:这道看似很简单的题目,原来也是有坑的!刚开始的思路就是按部就班地循环--判断是否为质数--判断是否是因子:

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. long num;
  6. cin >> num;
  7. for (int i = 2; i <= num; i++) {
  8. bool flag = true;
  9. for (int j = 2; j < i; j++) {
  10. if (i%j == 0) {
  11. flag = false;
  12. break;
  13. }
  14. }
  15. if (flag) {
  16. if (num%i == 0) {
  17. num = num / i;
  18. cout << i << ' ';
  19. i--;
  20. }
  21. }
  22. }
  23. return 0;
  24. }

后来看了别人写的程序,突然发现自己智商可能真的不够用:

  1. #include <iostream>
  2. using namespace std;
  3. int main(void)
  4. {
  5. long input;
  6. while (cin >> input)
  7. {
  8. while (input != 1)
  9. {
  10. for (int i = 2; i <= input; i++)
  11. {
  12. if (input % i == 0)
  13. {
  14. input /= i;
  15. cout << i << ' ';
  16. break;
  17. }
  18. }
  19. }
  20. }
  21. return 0;
  22. }

这个程序算不上完美,每次更新完input之后又都从2开始循环,在这一点上明显复杂度比我的代码高了不少。但是,这个程序让我突然发现,这道题目其实和是不是质数没有关系!从2开始循环,如果都有一个非质数因子,那么在这个因子的前面,该非质数的质数因子又是怎么能“幸免于难”的呢?

也就是说,这道题的程序只要如下就行了:

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. long num;
  6. cin >> num;
  7. for (int i = 2; i <= num; i++) {
  8. if (num%i == 0) {
  9. num = num / i;
  10. cout << i << ' ';
  11. i--;
  12. }
  13. }
  14. return 0;
  15. }

 

7、取近似值

题目描述:写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于5,向上取整;小于5,则向下取整。

例如:输入5.5,输出6。

解答:float强制转换成int为截取。

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. float f;
  6. cin >> f;
  7. if ((f - (int)f) >= 0.5)
  8. cout << (int)f + 1;
  9. else
  10. cout << (int)f;
  11. return 0;
  12. }

后来看见网友的一个答案,瞬间觉得很赞,算是开拓一下:

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. float a;
  6. cin >> a;
  7. cout << int(a + 0.5);
  8. return 0;
  9. }

 

8、合并表记录

题目描述:数据表记录包含表索引和数值,请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出。

例如:输入4 0 1 0 2 1 2 3 4,输出0 3 1 2 3 4。

解答:用数组来装数据表记录进行解答。

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int a[1000][2];
  6. int num;
  7. int temp;
  8. cin >> num;
  9. for (int i = 0; i < num; i++) {
  10. cin >> a[i][0] >> a[i][1];
  11. }
  12. for (int i = 0; i < num - 1; i++) {
  13. for (int j = i + 1; j < num ; j++) {
  14. if (a[i][0] > a[j][0]) {
  15. temp = a[i][0];
  16. a[i][0] = a[j][0];
  17. a[j][0] = temp;
  18. temp = a[i][1];
  19. a[i][1] = a[j][1];
  20. a[j][1] = temp;
  21. }
  22. if (a[i][0] == a[j][0]) {
  23. a[i][1] = a[i][1] + a[j][1];
  24. for (int k = j; k < num-1 ; k++) {
  25. a[k][0] = a[k + 1][0];
  26. a[k][1] = a[k + 1][1];
  27. }
  28. num--;
  29. j--;
  30. }
  31. }
  32. }
  33. for (int i = 0; i < num ; i++) {
  34. cout << a[i][0] << ' ' << a[i][1] << endl;
  35. }
  36. return 0;
  37. }

我看网友其他人的答案,发现很多还是用第三题的计数排序的方法来解答的,也通过了测试。其实,这道题并没有规定索引值一定是整数啊!要是有小数,计数排序就没办法了。算是题目的锅吧,同样也附上代码:

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int Key_Value[10000] = { 0 }, Key, Value, Number, i;
  6. cin >> Number;
  7. for (i = 0; i<Number; i++)
  8. {
  9. cin >> Key >> Value;
  10. Key_Value[Key] += Value;
  11. }
  12. for (i = 0; i<10000; i++)
  13. {
  14. if (Key_Value[i] != 0)
  15. cout << i << ' ' << Key_Value[i] << endl;
  16. }
  17. return 0;
  18. }

 

9、提取不重复的整数

题目描述:输入一个int型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。

例如:输入9876673,输出37689。

解答:很容易就想到用计数的方法来进行解决这道题:

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int num;
  6. cin >> num;
  7. int result;
  8. result = num;
  9. int a[10][2] = { 0 };
  10. while (num) {
  11. a[num % 10][0]++;
  12. num = num / 10;
  13. }
  14. while (result) {
  15. if (a[result % 10][0] == 1|| (a[result % 10][0] > 1&& a[result % 10][1]==0)) {
  16. cout << result % 10;
  17. a[result % 10][1] = 1;
  18. }
  19. result = result / 10;
  20. }
  21. return 0;
  22. }

但是发现自己是一个很按部就班的人,总是把问题分成很多小目标,然后分别一一解决。但是缺少把几个目标相互关联的本事,就像这道题,可以将两个循环合并来解决:

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int n;
  6. int a[10] = { 0 };
  7. int num = 0;
  8. cin >> n;
  9. while (n)
  10. {
  11. if (a[n % 10] == 0)
  12. {
  13. a[n % 10]++;            //这一步是更新,遇到下次相同的数会跳过
  14. num = num * 10 + n % 10;
  15. }
  16. n /= 10;
  17. }
  18. cout << num << endl;
  19. return 0;
  20. }

 

10、字符个数统计

题目描述:编写一个函数,计算字符串中含有的不同字符的个数。字符在ACSII码范围内(0~127)。不在范围内的不作统计。

例如:输入abc,输出3。

解答:很简单的一个程序,计数法(华为机试题好像很喜欢这个方法,一定要注意):

  1. #include <iostream>
  2. using namespace std;
  3. #include <string>
  4. int main()
  5. {
  6. string s;
  7. getline(cin, s);
  8. int a[128] = { 0 }, num = 0;
  9. for (int i = 0; i<s.size(); i++) {
  10. a[(int)s.at(i)]++;
  11. }
  12. for (int i = 0; i < 128; i++) {
  13. if (a[i] != 0)
  14. num++;
  15. }
  16. cout << num;
  17. return 0;
  18. }

 

11、数字颠倒

题目描述:输入一个整数,将这个整数以字符串的形式逆序输出。程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001。

例如:输入123,输出321。

解答:很简单的一个程序,只不过注意一下用do...while,而不是while:

  1. #include <iostream>
  2. using namespace std;
  3. #include <string>
  4. int main()
  5. {
  6. int i;
  7. cin >> i;
  8. do {
  9. cout<<(char) (i % 10 + 48);
  10. i = i / 10;
  11. } while (i);
  12. return 0;
  13. }

将数字转化为char的方法:

  1. (char) (i % 10 + 48);
  2. (char) (i % 10 + '0');

常见的ASCII码还是有点印象比较好:

0-9:48-57;A-Z:65-90;a-z:97-122。

 

12、句子逆序

题目描述:将一个英文语句以单词为单位逆序。所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符。

例如:输入“I am a boy”,输出“boy a am I”。

解答:单词逆序,但仍然要保持单词。通过substr()函数来进行截取:

  1. #include <iostream>
  2. using namespace std;
  3. #include <string>
  4. int main()
  5. {
  6. string s, s1, s2;
  7. int flag = 0, i = 0;
  8. getline(cin, s);
  9. for (int j = 0; j < s.size(); j++) {
  10. if (s.at(j) == ' ') {
  11. s1 = s.substr(flag, j - flag);
  12. if (i == 0) {
  13. s2 = s1;
  14. i++;
  15. }
  16. else
  17. s2 = s1 + " " + s2;
  18. flag = j + 1;
  19. }
  20. if (j == s.size() - 1) {
  21. s1 = s.substr(flag, j - flag + 1);
  22. s2 = s1 + " " + s2;
  23. }
  24. }
  25. cout << s2;
  26. return 0;
  27. }

参考网上的一些程序,发现一个很巧妙的方法!通过stack“先进后出”的特性:

  1. #include <iostream>
  2. #include <stack>
  3. #include <string>
  4. using namespace std;
  5. int main()
  6. {
  7. stack<string> ss;
  8. string s;
  9. while (cin >> s)
  10. {
  11. ss.push(s);
  12. }
  13. while (!ss.empty())
  14. {
  15. cout << ss.top();
  16. ss.pop();
  17. if (!ss.empty())
  18. cout << ' ';
  19. }
  20. cout << endl;
  21.         return 0;
  22. }

 

13、字串的连接最长路径查找

题目描述:给定n个字符串,请对n个字符串按照字典序排列。

例如:输入9 cap to cat card two too up boat boot,输出boat boot cap card cat to too two up。

解答:直接排序就行了。对于字符串“>、<、==、+”这些运算符都被重载了,可以直接用:

  1. #include <iostream>
  2. using namespace std;
  3. #include <string>
  4. int main()
  5. {
  6. int num;
  7. cin >> num;
  8. string s[1000], temp;
  9. for (int i = 0; i < num; i++) {
  10. cin >> s[i];
  11. }
  12. for (int i = 0; i < num-1; i++) {
  13. for (int j = 0; j < num-i-1; j++) {
  14. if (s[j] > s[j+1]) {
  15. temp = s[j];
  16. s[j] = s[j+1];
  17. s[j+1] = temp;
  18. }
  19. }
  20. }
  21. for (int i = 0; i < num; i++)
  22. cout << s[i] << endl;
  23. return 0;
  24. }

参考其他人的程序,发现一堆使用STL封装的数据结构和函数的……总感觉脱离了出题人的本意了,原本考验算法的,直接一个函数就解决……(可能是因为自己不太熟悉这些函数就酸吧):

  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <algorithm>
  5. using namespace std;
  6. int main()
  7. {
  8. int input;
  9. while (cin >> input)
  10. {
  11. string str;
  12. vector<string> vs;
  13. while (input--)
  14. {
  15. cin >> str;
  16. vs.push_back(str);
  17. }
  18. sort(vs.begin(), vs.end());
  19. vector<string>::iterator vit;
  20. for (vit = vs.begin(); vit != vs.end(); vit++)
  21. {
  22. cout << *vit << endl;
  23. }
  24. }
  25. return 0;
  26. }

 

14、求int型正整数在内存总存储时1的个数

题目描述:输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数。

例如:输入5,输出2。

解答:这道题可以使用i&(i-1)的方式来求1的个数:

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int i,j=0;
  6. cin >> i;
  7. while (i) {
  8. i=i & (i - 1);
  9. j++;
  10. }
  11. cout << j;
  12. return 0;
  13. }

当然,看了其他网友的程序,也有其他的方法:

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int a, count;
  6. cin >> a;
  7. count = 0;
  8. while (a>0)
  9. {
  10. if (a & 1)
  11. count++;
  12. a >>= 1;
  13. }
  14. cout << count << endl;
  15. return 0;
  16. }

或者:

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int t;
  6. cin >> t;
  7. int count = 0;
  8. while (t>0)
  9. {
  10. if (t % 2) count++;
  11. t = t / 2;
  12. }
  13. cout << count << endl;
  14. return 0;
  15. }

 

15、坐标移动

题目描述:开发一个坐标计算工具, A表示向左移动,D表示向右移动,W表示向上移动,S表示向下移动。从(0,0)点开始移动,从输入字符串里面读取一些坐标,并将最终输入结果输出到输出文件里面。输入:合法坐标为A(或者D或者W或者S) + 数字(两位以内),坐标之间以“;”分隔。非法坐标点需要进行丢弃。如AA10;  A1A;  $%$;  YAD; 等。

例如:输入A10;S20;W10;D30;X;A1A;B10A11;;A10;,输出10,-10。

解答:这道题还是在华为机试题里第一次遇到的比较复杂的题目。想了蛮久,用了一堆的标志位:

  1. #include <iostream>
  2. using namespace std;
  3. #include <string>
  4. int main()
  5. {
  6. string s;
  7. while (getline(cin, s)) {
  8. int x = 0, y = 0;
  9. int m = 0, n = -1, k = 0;
  10. bool flag = false, flag1 = false;
  11. for (int i = 0; i < s.size(); i++) {
  12. if (s.at(i) == 'W' || s.at(i) == 'A' || s.at(i) == 'S' || s.at(i) == 'D') {
  13. if (n != -1) flag1 = true;
  14. if (s.at(i) == 'W') n = 0;
  15. if (s.at(i) == 'A') n = 1;
  16. if (s.at(i) == 'S') n = 2;
  17. if (s.at(i) == 'D') n = 3;
  18. if (k == 0) flag = true;
  19. }
  20. k++;
  21. if (flag) {
  22. if (s.at(i) <= '9'&&s.at(i) >= '0') {
  23. m = m * 10 + s.at(i) - '0';
  24. }
  25. }
  26. if (s.at(i) == ';') {
  27. if (flag1) m = 0;
  28. if (n == 0) y = y + m;
  29. if (n == 1) x = x - m;
  30. if (n == 2) y = y - m;
  31. if (n == 3) x = x + m;
  32. n = -1;
  33. m = 0;
  34. k = 0;
  35. flag = false;
  36. flag1 = false;
  37. }
  38. }
  39. cout << x << ',' << y << endl;
  40. }
  41. return 0;
  42. }

需要注意的是:我这边采用循环输入的方式:

 

  1. while (getline(cin, s)) {
  2.         ...
  3. }

如果不采用这种方式的话,会报错,通过不了测试……具体什么时候需要循环输入,什么时候不需要循环输入……不知道……

参考网上的解答,发现了一个不错的程序:

  1. #include<iostream>
  2. #include<string>
  3. #include<cstddef> //std::size_t
  4. using namespace std;
  5. int main()
  6. {
  7. string str;
  8. while (cin >> str) {
  9. pair<int, int> point(0, 0); //point.first point.second
  10. size_t found = str.find_first_of(';'); //找到第一个';'的位置
  11. int start = 0;
  12. while (found != string::npos) {
  13. string s1 = str.substr(start, found - start);
  14. start = found + 1;
  15. found = str.find_first_of(';', found + 1);
  16. if (s1.size()>1 && s1.size() <= 3) { //合法的字符个数:2或3
  17. char c = s1[0];
  18. int n = 0;
  19. int invalid = 0; //数字为是否非法
  20. for (int i = 1; i<s1.size(); ++i) { //数字位判断与提取,A1A
  21. if (s1[i] >= '0'&&s1[i] <= '9')
  22. n = n * 10 + (s1[i] - '0');
  23. else {
  24. invalid = 1;
  25. break;
  26. }
  27. }
  28. if (invalid == 0) {
  29. switch (c)
  30. {
  31. case 'A': {point.first -= n; break; }
  32. case 'D': {point.first += n; break; }
  33. case 'W': {point.second += n; break; }
  34. case 'S': {point.second -= n; break; }
  35. }
  36. }
  37. }
  38. }
  39. cout << point.first << ',' << point.second << endl;
  40. }
  41. return 0;
  42. }

这段程序采用substr()函数来截取字符串的一部分,同时使用find_first_of()函数来寻找字符串当中的字符。需要注意的是,find_first_of()函数的第二个参数为:查找的起始索引位置。

注意:find()函数和find_first_of()函数两者的意义大体相同,它们之间最大的区别就是如果在一个字符串str1中使用find_first_of()来查找另一个字符串str2,如果str1中含有str2中的任何字符,则就会查找成功;而find则不同。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/328747
推荐阅读
相关标签
  

闽ICP备14008679号