题目要求:
一个游泳馆里有很多储物柜,每个储物柜都有一个ID号,但是老板不喜欢4这个数字,所以ID号里都不能有4,ID号从1开始编号,让你设计所有储物柜的ID号,用程序输出,比如
输入 4
输出 5
输入 5
输出 6
输入 14
输出 16
如果题目看不懂,看下这张数据对应表:
输入:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
输出:1 2 3 5 6 7 8 9 10 11 12 13 15 16 17
也就是根据输入的序号,求出实际的序号,实际的序号是去除掉含有4的数字
类似很多大厂的题目,初看简单,几乎每个人多少都能写点,但仔细一想,要写出高效、简洁的代码并不简单。按照常规思路,实现如下(效率较低)
1 #include "stdafx.h" 2 #include <iostream> 3 using namespace std; 4 5 bool include4(int n) 6 { 7 while (n) 8 { 9 if ((n%10) == 4) 10 return true; 11 n /=10; 12 } 13 14 return false; 15 } 16 17 int GetNumber(int n) 18 { 19 if (n < 0) 20 return 0; 21 22 int pos = 0; 23 24 while (n--) 25 while (include4(++pos)); 26 27 return pos; 28 } 29 30 int _tmain(int argc, _TCHAR* argv[]) 31 { 32 for (int i = 0; i < 100; ++i) 33 { 34 cout << i << ":" << GetNumber(i) << endl; 35 } 36 return 0; 37 }
转换下思路,考虑去掉4,等效于从10个数里拿走一个数,剩余9个数,所以新的数据模式可认为是9进1。
十进制情况下,我们要想表达一个数,m = n*10 + a; //n为除数; a为余数,取值范围为(0~9)
同理,“9进制”情况下m = n*9 + a; //n为除数;a为余数,取值范围为(0,1,2,3,5,6,7,8,9)
代码如下:
1 int GetNumber(int n) 2 { 3 if (n < 0) 4 { 5 return 0; 6 } 7 8 int symbols[] = { 0, 1, 2, 3, 5, 6, 7, 8, 9 }; 9 int count = sizeof(symbols)/sizeof(symbols[0]); 10 return n <= count ? symbols[n] : GetNumber(n / count) * 10 + GetNumber(n % count); 11 }