r***e 发帖数: 29 | 1 题目如下。
Roman Numerals
The purpose of this exercise is not simply to solve the problem, instead, we
are interested in how you approach the problem.
Please complete the coding exercise and then submit the code listing to your
email contact at the BBC. Please explain your approach, assumptions made,
or caveats to your solution and add these to the email.
You should spend no more than 30mins on your solution.
The problem
In whatever language you prefer, write a class that implements the following
interface (example given in Java):
public interface RomanNumeralGenerator {
public String generate(int number);
}
For example, see the following sample inputs and outputs:
1 = “I”
5 = “V”
10 = “X”
20 = “XX”
3999 = “MMMCMXCIX”
Caveat: Only support numbers between 1 and 3999
For an in-depth description of Roman Numerals, see http://en.wikipedia.org/wiki/Roman_numerals | r***e 发帖数: 29 | 2 我的答案(C++):
#pragma once
#ifndef _ROMON_HEADER_
#define _ROMON_HEADER_
#include
#include
using namespace std;
const string ROMON_DIGIT[] = {"","I","II","III","IV","V","VI","VII","VIII","
IV"};
//ROMON 0-9
const int ROMON_SCALE[] = {10, 50, 100, 500, 1000};
const char ROMON_SCALE_REP[] = {'X', 'L', 'C', 'D', 'M'};
//ROMON scale
const int ROMON_MAX = 3999;
const int ROMON_MIN = 1;
// rewrite the interface
class RomanNumeralGenerator
{
public:
virtual string generator(int num) = 0;
};
// transformation class
class CRoman : public RomanNumeralGenerator
{
public:
CRoman(void);
~CRoman(void);
string generator(int num)
{
if((numROMON_MAX))
{
return "";
}
stringstream ss;
for(int i = _scale - 1; i >= 0; i--)
{
int n = (int)(num / ROMON_SCALE[i]);
num = num % ROMON_SCALE[i];
ss<
}
ss<
return ss.str();
};
bool romanTest() //unit test
{
if(generator(1).compare("I")!=0)
{
return false;
}
if(generator(3).compare("III")!=0)
{
return false;
}
if(generator(4).compare("IV")!=0)
{
return false;
}
if(generator(5).compare("V")!=0)
{
return false;
}
if(generator(8).compare("VIII")!=0)
{
return false;
}
if(generator(11).compare("XI")!=0)
{
return false;
}
if(generator(55).compare("LV")!=0)
{
return false;
}
if(generator(111).compare("CXI")!=0)
{
return false;
}
if(generator(511).compare("DXI")!=0)
{
return false;
}
if(generator(3999).compare("MMMCMXCIX")!=0)
{
return false;
}
return true;
}
private:
static const int _scale = sizeof(ROMON_SCALE)/sizeof(int*);
}; | r***e 发帖数: 29 | 3 面人认为程序有严重的风格问题,但我一直没有想明白。求高人指点迷津。 | l*********8 发帖数: 4642 | 4 my two cents:
1. 把前面的const变量放到class里作为static const
2. 把romanTest放到class 外
3. string generator(int num) 改成
static string generate(int num)
【在 r***e 的大作中提到】 : 面人认为程序有严重的风格问题,但我一直没有想明白。求高人指点迷津。
| r***e 发帖数: 29 | 5 谢谢。但是这两点有一定的问题
1. 常量放类里可以提高封装性,但是,修改常量会引起整个类的重编译,我觉得在大
的项目里应避免。
2. romanTest是单元测试,一般和functional code在一起,如JUnit,CppUnit中的规定
。当然,如果逻辑太复杂,可以单独设置一个测试类。
3. 这是接口定义的,不能改。
【在 l*********8 的大作中提到】 : my two cents: : 1. 把前面的const变量放到class里作为static const : 2. 把romanTest放到class 外 : 3. string generator(int num) 改成 : static string generate(int num)
| r***e 发帖数: 29 | | r***e 发帖数: 29 | | t*****h 发帖数: 137 | 8 I haven't finished reading your code. But from the very beginning, you're
using namespace std.
My understanding is never using namespace std in the header, any other
classes use your class will have the namespace contamination.
#pragma once is also non standard.
修改
最后一行
static const int _scale = sizeof(ROMON_SCALE)/sizeof(int);
我们一般都把测试分开,这样可以用flag关掉测试,最后release的时候会比较小点。 | n****i 发帖数: 9 | 9 public String intToRoman(int num) {
String[] roman = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX",
"V", "IV", "I"};
int[] albo = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
String res = "";
for (int i = 0; i < roman.length; i++) {
while (num >= albo[i]) {
res += roman[i];
num -= albo[i];
}
}
return res;
} | r***e 发帖数: 29 | 10 谢谢
【在 t*****h 的大作中提到】 : I haven't finished reading your code. But from the very beginning, you're : using namespace std. : My understanding is never using namespace std in the header, any other : classes use your class will have the namespace contamination. : #pragma once is also non standard. : 修改 : 最后一行 : static const int _scale = sizeof(ROMON_SCALE)/sizeof(int); : 我们一般都把测试分开,这样可以用flag关掉测试,最后release的时候会比较小点。
| r***e 发帖数: 29 | 11 最后个人标准答案
#ifndef _ROMON_HEADER_
#define _ROMON_HEADER_
#define _DEBUG_
#include
#include
//ROMON digits
const std::string ROMON_DIGITS[] = {"I","IV","V","IX", "X","XL","L","XC","C"
,"CD","D","CM","M" };
//ROMON scale
const int ROMON_SCALE[] = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900,
1000};
const int ROMON_MAX = 3999;
const int ROMON_MIN = 1;
class RomanNumeralGenerator
{
public:
virtual std::string generator(int num) = 0;
};
class CRoman : public RomanNumeralGenerator
{
public:
CRoman(void);
~CRoman(void);
std::string generator(int num)
{
if((numROMON_MAX))
{
return "";
}
std::stringstream ss;
for(int i = _scale - 1; i >= 0; i--)
{
while(num>=ROMON_SCALE[i])
{
num -= ROMON_SCALE[i];
ss<
}
}
return ss.str();
};
#ifdef _DEBUG_
bool test() //unit test
{
unsigned int test[] = {4, 9, 11, 40, 49, 55, 90, 99,
111, 499, 511, 2111, };
std::string ans[] = {"IV","IX", "XI", "XL", "XLIX", "LV", "XC", "
XCIX", "CXI", "CDXCIX", "DXI", "MMCXI" };
bool t = true;
for(int i=0; i
{
if(generator(test[i]).compare(ans[i])!=0)
{
std::cerr<<"test fails at "<
[i])<<" :: "<
t = false;
}
}
return t;
}
void foo()
{
std::cout<<"boundary test 0: "<
std::cout<<"boundary test 4000: "<
for(int i = ROMON_MIN; i <= ROMON_MAX; i++)
{
std::cout<<"test "<
}
}
#endif
private:
static const int _scale = sizeof(ROMON_SCALE)/sizeof(int);
};
#endif |
|