我试图将罗马数字转换为c ++中的小数。
所以我的代码应该将罗马字节转换为小数,但它并不完全正常。
例如,VI为4,IV为6 MCMXLVI应该会产生1946年,但如果我从左到右,我会得到-998,如果我从右到左,我会得到0。
我主要想知道我的思维过程是否正确。
伪代码:
total = 0
max_value_so_far = 0
for each character in the input string, going from right to left:
if character converted to decimal >= max_value_so_far
add character converted to decimal to total
update max_value_so_far
otherwise subtract character converted to decimal from total
代码:
#include "std_lib_facilities_5.h"
string convert_string( string input){
for(int i=0; i < input.length(); i++){
input[i] = toupper(input[i]);
}
return input;
}
int roman_to_int(string RomanChars){
RomanChars = convert_string(RomanChars);
int total = 0;
int max_value= 0;
int M,D,C,L,X,V,I;
M = 1000;
D = 500;
C = 100;
L = 50;
X = 10;
V = 5;
I = 1;
double StringLength =RomanChars.length();
for( int i = 0; i < StringLength; i++){
if(RomanChars[i] == 'M') {
if (M >= max_value) {
total += M;
max_value = M;
} else {
total -= M;
}
}
if(RomanChars[i] == 'D') {
if (D >= max_value) {
total += D;
max_value = D;
} else {
total -= D;
}
}
if(RomanChars[i] == 'C') {
if (C >= max_value) {
total += C;
max_value = C;
} else {
total -= C;
}
}
if(RomanChars[i] == 'L') {
if (L >= max_value) {
total += L;
max_value = L;
} else {
total -= L;
}
}
if(RomanChars[i] == 'X') {
if (X >= max_value) {
total += X;
max_value = X;
} else {
total -= X;
}
}
if(RomanChars[i] == 'V') {
if (V >= max_value) {
total += V;
max_value = V;
} else {
total -= V;
}
}
if(RomanChars[i] == 'I') {
if (I >= max_value) {
total += I;
max_value = I;
} else {
total -= I;
}
}
}
return total;
}
int main() {
string character;
int conversion = 0;
while(cin >> character){
conversion = roman_to_int(character);
cout << conversion <<endl;
}
return 0;
}
答案 0 :(得分:3)
你教授提供的算法是正确的。
一些提示:
for( double i = 0; i < RomanChars.length(); i++){
double
?作为循环变量?不要那样做。 (不是问题的原因,但是baaad)另一个答案已经指出你的别人是错的。如果我是你,我会考虑找到优雅的东西来取代这个副本并粘贴狂欢。
如果您愿意 - 只是为了灵感 - 将您的罗马数字文字值存储在std :: map中,您的转换循环看起来与此类似(我的示例中的std :: map是std::map<char, int> conversion
):
int roman_to_int(std::string RomanChars){
RomanChars = convert_string(RomanChars);
int total = 0;
int max_value= 0;
for( size_t i = RomanChars.length()-1; i != std::string::npos; --i){
auto val = conversion.find(RomanChars[i]);
if(val != conversion.end())
{
if(val->second >= max_value)
{
total += val->second;
max_value = val->second;
} else {
total -= val->second;
}
}
}
return total;
}
答案 1 :(得分:1)
对于您的每个if
测试,由于您认为else
块没有被执行,您会收到错误。
if(RomanChars[i] == 'M' && M >= max_value){
total += M;
max_value = M;
} else {
total -= M; // this got executed for each character
// in the input sequence which is *not* M!
}
应该是
if (RomanChars[i] == 'M') {
if (M >= max_value) {
total += M;
max_value = M;
} else {
total -= M;
}
}
更好的是:
switch (RomanChars[i])
{
case 'M':
if (M >= max_value) {
max_value = M;
total += M;
} else {
total -= M;
}
break;
// ...
更好的是,用
重构代码#include<map>
const std::map<char, unsigned> romans_definition = {
{ 'I', 1 },
{ 'V', 5 },
{ 'X', 10 },
{ 'L', 50 },
// ...
};