gpt4 book ai didi

c++ - 将罗马数字转换为 Int - 得到错误的输出 - 为什么?

转载 作者:行者123 更新时间:2023-11-30 05:00:50 26 4
gpt4 key购买 nike

这是我的代码。首先,我想说,我一直在试验,所以如果你在这里和那里看到不必要的变量,那就是原因。但是我的代码的主要部分在我的类 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;

}

最佳答案

当我完成评论中的内容并稍微调整您的代码时,我得到了这个:

//---------------------------------------------------------------------------
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;
}
//---------------------------------------------------------------------------

因为我摆脱了你的 temproman1,roman2 以及 switch if/else 条件和代码从第一次编译开始工作......我假设你正在对他们做一些可疑的事情(在 if/else 组合中迷失了一些边缘情况)。

关于c++ - 将罗马数字转换为 Int - 得到错误的输出 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50540265/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com