-
题目大意:火星数字以13为基数,我需要写一个程序使火星数字和地球数字互相转换。这里只考虑最多两位火星数字。
- 地球 -> 火星:int(地球 / 13)为火星的十位数,(地球 % 13)为火星的个位数
- 火星 -> 地球:十位的火星 * 13 + 个位的火星
-
思路:用2个数组分别表示火星的个位数和火星的十位数
-
知识点:
- string
- vector
- getline(cin, str):火星数字之间可能有空格,所以用getline(cin, str)接收字符串
- isdigit(char)
-
代码:
#include <iostream> #include <vector> #include <string> using namespace std; int main(){ string one[13] = {"tret", "jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"}; string ten[12] = {"tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"}; int n, i, j, k; string num; cin >> n; cin.ignore(); // getline(cin, str)前面有cin,需先ignore一个'\n' for(i = 0; i < n; i++){ getline(cin, num); string result; if(isdigit(num[0])){ // 地球 -> 火星 if(int(stoi(num) / 13) != 0) // 两位数 if(stoi(num) % 13 == 0) // 还要13的倍数!!! result = ten[int(stoi(num) / 13) - 1]; else result = ten[int(stoi(num) / 13) - 1] + ' ' + one[stoi(num) % 13]; else // 一位数 result = one[stoi(num) % 13]; } else{ // 火星 -> 地球 string one_part = "", ten_part = ""; if(num.size() > 4){ ten_part = num.substr(0, 3); one_part = num.substr(4); } else one_part = num; if(ten_part == ""){ // 一位数 j = 0, k = 0; // 还要考虑13的倍数!!! for(int m = 0; m < 13; m++){ if(m < 12 && ten[m] == one_part){ // 从下面复制ten[m] == ten_part忘记改成ten[m] == one_part j = m + 1; //因为j可能会是0,所以应该+1 break; } if(one[m] == one_part){ k = m; break; } } if(j != 0) result = to_string(j * 13); else result = to_string(k); } else{ // 两位数 j = 0, k = 0; for(int m = 0; m < 13; m++){ if(m < 12 && ten[m] == ten_part) j = m; if(one[m] == one_part) k = m; } result = to_string((j + 1) * 13 + k); } } printf("%s\n", result.c_str()); } return 0; }
代码太长了,可以把数字转换过程封装成函数。
-
改进的代码:
-
将转换数字的代码封装成函数,并且用了重载的概念;
-
用
while()
来找火星数字的下标。注意:
- 若火星数字只有一位时,要判断这个数是不是13的整数;
- 若火星数字只有一位时,要注意**
k==0
**的情况。
#include <iostream> #include <vector> #include <string> using namespace std; vector<string> one = {"tret", "jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"}; vector<string> ten = {"###", "tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"}; // 这样更好找 void decode(int num){ if(int(num / 13) != 0) // 两位数 if(num % 13 == 0) // 13的倍数 printf("%s\n", ten[int(num / 13)].c_str()); else printf("%s\n", (ten[int(num / 13)] + ' ' + one[num % 13]).c_str()); else printf("%s\n", one[num % 13].c_str()); } void decode(string num){ // 重载 int i, j, k; string one_part = "", ten_part = ""; // 获取每部分数字 if(num.size() > 4){ ten_part = num.substr(0, 3); one_part = num.substr(4); } else one_part = num; // 转换 if(ten_part == ""){ // 一位数 j = 0, k = 0; // 还要考虑13的倍数,所以要设置j来判断是否有该情况; while(j < 13 && ten[j] != one_part) j++; while(k < 13 && one[k] != one_part) k++; if(j > 0 && j < 13) // 13的倍数 printf("%s\n", to_string(j * 13).c_str()); else if(k >= 0 && k < 13) // 还要考虑为tret(0)的情况 printf("%s\n", to_string(k).c_str()); }else{ // 两位数 j = 0, k = 0; while(j < 13 && ten[j] != ten_part) j++; while(k < 13 && one[k] != one_part) k++; printf("%s\n", (to_string(j * 13 + k)).c_str()); } } int main(){ int n, i; string num; cin >> n; cin.ignore(); // getline(cin, str)前面有cin,需先ignore一个'\n' for(i = 0; i < n; i++){ getline(cin, num); string result; if(isdigit(num[0])) // 地球 -> 火星 decode(stoi(num)); else // 火星 -> 地球 decode(num); } return 0; }
-
-
总结:
-
若
getline(cin, str)
前面有cin
,需先cin.ignore()
,再getline(cin, str)
; -
isdigit()
不需要调用什么包; -
可用
str.substr()
分割字符串; -
这里出现段错误的原因: 之前用了
while(one[j] != one_part) j++;
找火星语对应的数,没考虑到数组越界的问题,改成了用了for
去找 ,就能解决段问题; -
可以将完成某项工作的代码封装成函数,如“判断素数”、“数字转换”和“计算和”之类的;
-
细节:
-
有关数字的问题,要注意
num == 0
的情况; -
遇到数字转换的问题,要注意**数值为基数的倍数(
num % 基数 == 0 && num / 基数 != 0
)**的情况。- 若数值为基数的倍数时有单独的表示:在存十位数字的数组里找
num / 基数
; - 若数值为基数的倍数时没有单独的表示:直接
(num / 基数) * 10
- 若数值为基数的倍数时有单独的表示:在存十位数字的数组里找
-
-
粗心:
-
在访问数组元素时,经常用错下标,比如:
for(i = 0; i < 10; i++){ for(j = 0; j < 5; j++){ if(s[j] == '0') // 我经常会粗心写成s[i] printf("%c\n", s[j]); } }
-
有时候偷懒,想复制之前写好的部分,会忘记改了,比如:
if(m < 12 && ten[m] == one_part){ // 从下面复制ten[m] == ten_part忘记改成ten[m] == one_part
-
有时候会只考虑测试用例给的值,没设置成变量,比如:
- 测试用例设置有n条,我就直接设置n = 3;
- 若数为13的整数时,应该都做特殊处理,但我只考虑了测试用例给出的13。
-
注意
while()
允许运行的条件是满足条件的时候,还要注意i == 0
的情况的!
-