Я новичок в C++, хотя у меня есть базовые знания Java, я пытаюсь создать программу, которая преобразует римский цифровой ввод, а затем находит эквивалентное арабское число и выводит его. Однако у меня возникает проблема поиска конкретных префиксов в римских цифрах. Я пытаюсь использовать функцию str.find, а затем используя str.substr для проверки, существует ли префикс и если да, то он дает арабское значение и затем перейдет к следующему префиксу. Однако мой код, кажется, не работает или распечатывает «0». Мне интересно, неправильно ли я использую str-функции или будет ли более простой способ найти префиксы в строке?Проблема с поиском символов в строке
Вот мой текущий код:
#include <cstdlib>
#include <iostream>
#include <cctype>
using namespace std;
/*
*
*/
int main() {
string roman_digits [] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
string roman_tens [] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
string roman_hundreds [] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
string roman_thousands [] = {"", "M", "MM", "MMM"};
string line, substr;
int arabic = 0;
// MCCCXXXVII
cout << "Type in a Roman numeral: ";
// Loops through inputted Roman Numerals.
while (cin >> line) {
if (!cin.eof()) {
int i = 0;
// Loops through a Roman numeral and changes it to uppercase.
while (line[i]) {
char c;
c = line[i];
c = (toupper(c));
line[i] = c;
i++;
}
// Loops through checking roman numeral with the thousands array and if there is a match prints out the equivalent arabic number.
for (int i = 0; i < 4; i++) {
if (line.find("MMM") != string::npos) {
unsigned pos = line.find("MMM");
substr = line.substr(pos, 3);
line.erase(pos, 3);
} else if (line.find("MM") != string::npos) {
unsigned pos = line.find("MM");
substr = line.substr(pos, 2);
line.erase(pos, 2);
} else if (line.find("M") != string::npos) {
unsigned pos = line.find("M");
substr = line.substr(pos, 1);
line.erase(pos, 1);
}
if (roman_thousands[i] == substr){
arabic = arabic + (i * 1000);
}
}
// Loops through checking roman numeral with the hundreds array and if there is a match prints out the equivalent arabic number.
for (int i = 0; i < 10; i++) {
if (line.find("CM") != string::npos){
unsigned pos = line.find("CM");
substr = line.substr(pos, 2);
line.erase(pos, 2);
} else if (line.find("DCCC") != string::npos){
unsigned pos = line.find("DCCC");
substr = line.substr(pos, 4);
line.erase(pos, 4);
} else if (line.find("DCC") != string::npos){
unsigned pos = line.find("DCC");
substr = line.substr(pos, 3);
line.erase(pos, 3);
} else if (line.find("DC") != string::npos){
unsigned pos = line.find("DC");
substr = line.substr(pos, 2);
line.erase(pos, 2);
} else if (line.find("D") != string::npos){
unsigned pos = line.find("D");
substr = line.substr(pos, 1);
line.erase(pos, 1);
} else if (line.find("CD") != string::npos){
unsigned pos = line.find("CD");
substr = line.substr(pos, 2);
line.erase(pos, 2);
} else if (line.find("CCC") != string::npos){
unsigned pos = line.find("CCC");
substr = line.substr(pos, 3);
line.erase(pos, 3);
}else if (line.find("CC") != string::npos){
unsigned pos = line.find("CC");
substr = line.substr(pos, 2);
line.erase(pos, 2);
} else if (line.find("C") != string::npos){
unsigned pos = line.find("C");
substr = line.substr(pos, 1);
line.erase(pos, 1);
}
if (roman_hundreds[i] == substr) {
arabic = arabic + (i * 100);
}
}
// Loops through checking roman numeral with the tens array and if there is a match prints out the equivalent arabic number.
for (int i = 0; i < 10; i++) {
if (line.find("XC") != string::npos){
unsigned pos = line.find("XC");
substr = line.substr(pos, 2);
line.erase(pos, 2);
} else if (line.find("LXXX") != string::npos){
unsigned pos = line.find("LXXX");
substr = line.substr(pos, 4);
line.erase(pos, 4);
}else if (line.find("LXX") != string::npos){
unsigned pos = line.find("LXX");
substr = line.substr(pos, 3);
line.erase(pos, 3);
} else if (line.find("LX") != string::npos){
unsigned pos = line.find("LX");
substr = line.substr(pos, 2);
line.erase(pos, 2);
}else if (line.find("L") != string::npos){
unsigned pos = line.find("L");
substr = line.substr(pos, 1);
line.erase(pos, 1);
}else if (line.find("XL") != string::npos){
unsigned pos = line.find("XL");
substr = line.substr(pos, 2);
line.erase(pos, 2);
}else if (line.find("XXX") != string::npos){
unsigned pos = line.find("XXX");
substr = line.substr(pos, 3);
line.erase(pos, 3);
}else if (line.find("XX") != string::npos){
unsigned pos = line.find("XX");
substr = line.substr(pos, 2);
line.erase(pos, 2);
}else if (line.find("X") != string::npos){
unsigned pos = line.find("X");
substr = line.substr(pos, 1);
line.erase(pos, 1);
}
if (roman_tens[i] == substr) {
arabic = arabic + (i * 10);
}
}
// Loops through checking roman numeral with the digits array and if there is a match prints out the equivalent arabic number.
for (int i = 0; i < 10; i++) {
if (line.find("IX") != string::npos){
unsigned pos = line.find("IX");
substr = line.substr(pos, 2);
line.erase(pos, 2);
} else if (line.find("VIII") != string::npos){
unsigned pos = line.find("VIII");
substr = line.substr(pos, 4);
line.erase(pos, 4);
} else if (line.find("VII") != string::npos){
unsigned pos = line.find("VII");
substr = line.substr(pos, 3);
line.erase(pos, 3);
} else if (line.find("VI") != string::npos){
unsigned pos = line.find("VI");
substr = line.substr(pos, 2);
line.erase(pos, 2);
} else if (line.find("V") != string::npos){
unsigned pos = line.find("V");
substr = line.substr(pos, 1);
line.erase(pos, 1);
} else if (line.find("IV") != string::npos){
unsigned pos = line.find("IV");
substr = line.substr(pos, 2);
line.erase(pos, 2);
} else if (line.find("III") != string::npos){
unsigned pos = line.find("III");
substr = line.substr(pos, 3);
line.erase(pos, 3);
} else if (line.find("II") != string::npos){
unsigned pos = line.find("II");
substr = line.substr(pos, 2);
line.erase(pos, 2);
}else if (line.find("I") != string::npos){
unsigned pos = line.find("I");
substr = line.substr(pos, 1);
}
if (roman_digits[i] == substr) {
arabic = arabic + i;
}
}
cout << "The Arabic equivalent of " << line << " is: " << arabic << endl;
arabic = 0;
} else {
cout << "Invalid Roman numeral." << endl;
}
}
return 0;
}
Любая помощь будет принята с благодарностью спасибо.
EDIT: Итак, я принял совет, и все это работает нормально (Код был отредактирован), поэтому большое спасибо за это. ^^
Однако, поскольку он проверяет «X» отдельно и удаляет его, моя программа переводит вход «IX» как 11, когда это на самом деле 9. Я знаю, что это связано с тем, что моя программа находит префиксы в строках, однако я не уверен, как это исправить, поэтому любая помощь в этом будет замечательной.
Еще раз спасибо
Проверка на 'станд :: cin.eof () 'на самом деле не имеет большого смысла. Поскольку вы уже проверяете, что вход был успешным, он не наносит большого вреда, но он предотвратит последнее значение, если за ним не будет пробел, например, отсутствующая строка новой строки в конце файла. Просто удалите его! BTW, 'std :: cin >> строка' не читает строку, а слово. Если вы действительно хотите прочитать строку, используйте вместо нее 'std :: getline (std :: cin, line)'. –
Предлагаю вам взглянуть на 'std :: map'. Вы можете использовать строку Roman Numeral в качестве ключа и десятичное значение в качестве значения в паре [ключ, значение]. –