这是我的代码。首先,我想说,我一直在尝试,所以如果你在这里和那里看到不必要的变量,那就是原因。但是我的代码的主要部分是我的类romanType中的函数decimal。当我输入某些罗马数字时,我没有得到我想要的确切数字,它可能在我的if / else语句中的某个地方。
顺便说一下,为了说明我如何遍历字符串 - 我是通过反向遍历来完成的。我从字符串的最后到字符串的最开头,我觉得罗马数字更容易。顺便说一句,我也做了一个枚举类型,所以我可以比较罗马数字,看哪一个更小,哪一个更大等等。然后我用地图来比较枚举值和char值。
所以问题:例如,当我输入CCC时,我得到290而不是300.如果你知道我的逻辑有什么问题,我将非常感激!谢谢。
此外,我对编程很陌生,非常感谢任何风格提示或任何我可以学习的关于编写此代码时遗漏的课程等的内容?请告诉我什么是最好的。谢谢。
#include <iostream>
#include <string>
#include <map>
using namespace std;
class romanType {
string numeral;
int k;
public:
romanType();
void rnumeral (string b) {numeral = b;}
int decimal(string num, char b, int temp) {
num = "";
enum RomanNumerals {I, V, X, L, C, D, M };
map<char, RomanNumerals> m;
m['I'] = I;
m['V'] = V;
m['X'] = X;
m['L'] = L;
m['C'] = C;
m['D'] = D;
m['M'] = M;
RomanNumerals roman1;
RomanNumerals roman2;
cout << "Please type in your roman numeral:" ;
cin >> num;
for (int i =0; i <num.length()-1; i++){
}
for(long i = num.length()-1; i>=0; i--)
{
b = num[i];
if (islower(b)) b=toupper(b);
roman1 = m[num[i]];
roman2 = m[num[i-1]];
switch(b){
case 'I':
if(num[i] == num.length()-1){
temp += 1;
}
break;
case 'V':
if(roman1 > roman2){
temp += 4;
continue;
}
else {
temp += 5;
}
break;
case 'X':
if(roman1 > roman2){
temp += 9;
continue;
}
else {
temp += 10;
}
break;
case 'L' :
if(roman1 > roman2){
temp += 40;
continue;
}
else {
temp += 50;
}
break;
case 'C':
if(roman1 > roman2){
temp += 90;
continue;
}
else {
temp += 100;
}
break;
case 'D' :
if(roman1 > roman2){
temp += 400;
continue;
}
else {
temp += 500;
}
break;
case 'M':
if(roman1 > roman2){
temp += 900;
continue;
}
else {
temp += 1000;
}
break;
}
}
return temp;
}
};
romanType::romanType () {
numeral = "";
}
int main() {
string k = "";
char b = ' ';
int temp = 0;
romanType type;
type.rnumeral(k);
int c = type.decimal(k, b, temp);
cout << c;
return 0;
}
编辑:_____________________________________________________________________________
我找到了解决问题的方法。这是我的新代码:
#include <iostream>
#include <string>
#include <map>
using namespace std;
string acceptRN();
class romanType {
string numeral;
int temp2;
int l;
// VARIABLES
public:
romanType();
//DEFAULT CONSTRUCTOR
void getRnumeral (string b)
{
numeral = b;
}
//SETTER
void decimal(string num, int temp, char b) {
num = numeral;
enum RomanNumerals {I, V, X, L, C, D, M };
map<char, RomanNumerals> m;
m['I'] = I;
m['V'] = V;
m['X'] = X;
m['L'] = L;
m['C'] = C;
m['D'] = D;
m['M'] = M;
RomanNumerals roman1;
RomanNumerals roman2;
RomanNumerals roman3;
for(long i = num.length()-1; i>=0; i--)
{
b = num[i];
if (islower(b)) b=toupper(b);
roman1 = m[num[i]];
roman2 = m[num[i-1]];
roman3 = m[num[i+1]];
switch(b){
case 'I':
if( roman3 > roman1 && i != num.length()-1){
continue;
}
else {
temp += 1;
break;
}
case 'V':
if(roman1 > roman2 && i != 0){
temp += 4;
continue;
}
else {
temp += 5;
}
break;
case 'X':
if( roman3 > roman1 && i != num.length()-1)
continue;
if(roman1 > roman2 && i!= 0){
temp += 9;
continue;
}
else {
temp += 10;
}
break;
case 'L' :
if(roman1 > roman2 && i!= 0){
temp += 40;
continue;
}
else {
temp += 50;
}
break;
case 'C':
if( roman3 > roman1 && i != num.length()-1)
continue;
if(roman2 == X && i!= 0){
temp += 90;
continue;
}
else {
temp += 100;
}
break;
case 'D' :
if(roman2 == C && i!= 0){
temp += 400;
continue;
}
else {
temp += 500;
}
break;
case 'M':
if(roman2 == C && i!= 0){
temp += 900;
continue;
}
else {
temp += 1000;
}
break;
}
}
temp2 = temp;
}
void showDecimal() {
cout << "Here is your roman numeral in decimal format:";
cout << temp2 << " \n \n \n";
}
};
romanType::romanType () {
numeral = "";
}
int main() {
string k = acceptRN();
int m = 0;
char l= ' ';
romanType type;
type.getRnumeral(k);
type.decimal(k, m, l);
type.showDecimal();
return 0;
}
string acceptRN(){
string num = "";
cout << "Please type in your roman numeral:" ;
cin >> num;
return num;
}
答案 0 :(得分:1)
当我完成评论中的内容并稍微调整一下代码时,我得到了这个:
//---------------------------------------------------------------------------
int roman_ix[256]={-1};
const int roman_val[]={ 1 , 5 ,10 ,50 ,100,500,1000,0};
const char roman_chr[]={'I','V','X','L','C','D', 'M',0};
//---------------------------------------------------------------------------
int roman2int(char *s)
{
int i,x=0,v=0,v0;
// init table (just once)
if (roman_ix[0]<0)
{
for (i=0;i<256;i++) roman_ix[i]=0;
for (i=0;roman_chr[i];i++) roman_ix[roman_chr[i]]=i;
}
// find end of string
for (i=0;s[i];i++);
// proccess string in reverse
for (i--;i>=0;i--)
{
v0=v; // remember last digit
v=roman_val[roman_ix[s[i]]]; // new digit
if (!v) break; // stop on non supported character
if (v0>v) x-=v; else x+=v; // add or sub
}
return x;
}
//---------------------------------------------------------------------------
我测试了这些:
1776 1776 MDCCLXXVI
1954 1954 MCMLIV
1990 1990 MCMXC
2014 2014 MMXIV
300 300 CCC
第一个数字是从字符串转换的,第二个是它应该是什么,最后一个是罗马字符串。
如果256条目表太大,您可以将其缩小到范围A-Z
,这个范围要小得多,但在代码中需要多一个减法。它也可以用硬编码来摆脱初始化:
//---------------------------------------------------------------------------
int roman2int(char *s)
{
// init
int i,x=0,v=0,v0; // A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
const int val['Z'-'A'+1]={ 0, 0, 100, 500, 0, 0, 0, 0, 1, 0, 0, 50, 1000, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 10, 0, 0 };
// find end of string
for (i=0;s[i];i++);
// process string in reverse
for (i--;i>=0;i--)
{
if ((s[i]<'A')||(s[i]>'Z')) break; // stop on non supported character
v0=v; v=val[s[i]-'A'];
if (v0>v) x-=v; else x+=v;
}
return x;
}
//---------------------------------------------------------------------------
当我摆脱你的temp
和roman1,roman2
以及switch if/else
条件并且代码在第一次编译时起作用...我假设你正在做一些与它们有关的事情(在if / else组合中迷失了一些边缘情况)。