这是一道某公司的上机面试题:
microsoft excel 中栏目是用 A,B,C...Z;AA,AB,...ZZ ... ZZZZ ....这样表示序列的它对应是这样
请写出这个对应关系。
输入是多行输入,输出是输出=原串+空格+值
例子:
A 0
AA 26
AAA 702
AAAA 18278
因为看到了A-Z我就以为是26进制,然后推出 (第一位) (第二位) (第三位) 这样表示的excel 列名为
value = 第一位*26^2+第二位*26*1+第三位
A=0 B=1 ... Z=25
然后一看 AA = 26 这是什么东东? 00 这个是没有的。
思路不对
如果个位的A=0 B=1...Z=25
非个位的 A=1 B=2 ... Z=26 是否对呢?
验证一下
AA= 1 * 26+0=26
AAA = 1*26*26+1*26+0 = 702
AAAA = 1*26*26*26+1*26*26+1*26+0 = 18278
果然正确
那么这个时候就急急忙忙编程了。(时间不多了)
#include <stdio.h>
#include <string>
#include <math.h>
#include <iostream>
#include <conio.h>
#include <vector>
using namespace std;
#define OUT
//
// getExcelColumnNumber: 获得excel 的列标题
// alphaNum - A-Z AA-ZZ AAA-ZZZ ...
// 返回列标题的代表的序号
int getExcelColumnNumber(string &alphaNum)
{
int result = 0;
int count = alphaNum.size();
for(int i=0;i<count;i++)
{
int c = alphaNum[i];
int value = 0;
if(i==count-1)
{
value = c-'A';
}
else
{
value = (c-'A'+1)*_Pow_int(26,count-i-1);
}
result+=value;
}
return result;
}
//
// 获得输入,可以多行输入,
// 最后一行必须两个回车才能执行
//
void input(OUT vector<string> &vec)
{
string tmp;
int state = 0;
while(1)
{
char c = getch();
putchar(c);
if(state == 0)
{
if(c=='\r')
{
state = 1;
if(tmp.size())
{
vec.push_back(tmp);
}
tmp.clear();
putchar('\n');
}
else
{
tmp+=c;
}
}
else
{
if(c=='\r')
{
putchar('\n');
break;
}
else
{
state = 0;
tmp+=c;
}
}
}
}
void main()
{
vector<string> inVec;
input(inVec);
//string alphaNum = "AA";
//cin >> alphaNum;
for(int i=0;i<inVec.size();i++)
{
string &alphaNum = inVec[i];
cout << alphaNum << " "<< getExcelColumnNumber(alphaNum) << endl;
}
}
回来的路上想:
这个是感觉,还有就是进行了一下推理。至于原理当时没有想那么多。
A-Z 有 26 个数
AA-ZZ 有 26*26个数
AAA-ZZZ 有26*26*26 个数
如果我们这个数是4位 (first)(second)(third)(fourth)
因为是四位数所以前面就是:
26*26*26+26*26+26
要计算的这个四位数就是:
(first-'A')*26*26*26+(second-'A')*26*26+(third-'A')*26+(fourth-'A')+26*26*26+26*26+26
=(first-'A'+1)*26*26*26+(second-'A'+1)*26*26+(third-'A'+1)*26+(fourth-'A')
这就是我把个位的数 A = 0 其他位置上的A = 1 的原因。
(如果first=A 则 first-'A'+1=1 second 等同理)