c++ 将罗马数字转换为小数

2023-12-27

该程序是我刚刚参加的考试的一部分,我必须编写它。我只走到了这一步,却哪儿也去不了。提示如下:“编写一个测试函数 toDecimal(),将罗马数字(例如 MMLXVII)转换为其十进制数字表示形式。使用 Main() 测试该函数。toDecimal() 函数应该有 2 个参数,即字符串数组罗马数字和辅助函数。该辅助函数将返回罗马数字中使用的每个字母的数值。然后按如下方式转换字符串参数:查看前两个字符,如果第一个较大,则转换第一个和将其添加到求和中,然后使用第二个值再次调用转换函数并将两者相加。如果第一个字符小于第二个字符,则从第二个字符中减去第一个字符,并将结果添加到字符串的转换中。无需验证也会转换像“IC”这样的字符串。验证字符串争论,如果有错误,调用错误处理函数。提供至少两个错误处理函数,并分别测试 toDecimal()。其中一个可能会建议用户更正,另一个可能会纠正它。”

I、X、C、M 不能连续重复超过 3 次,D、L、V 不能连续重复。I 只能从 V 中减去,X、X 只能从 L 和 C 中减去, C 只能从 D 和 M 中减去。V、L 和 D 永远不能相减。

我为此失眠了大约两天,尝试使用和打破规则以数百种不同的方式编写它。这是我所得到的最接近的。

#include <iostream>
#include <string>
#include <map>
#include <algorithm>
#include <cstring>
using namespace std;

bool checker(string roman);
// Adds each value of the roman numeral together
int toDecimal(string, bool* (*function)(string));
int convert(string roman, int i);

int main(){
    string roman;
    cout << "This program takes a roman numeral the user enters then converts it to decimal notation." << endl;
    cout << "Enter a roman numeral: ";
    cin >> roman;
    transform(roman.begin(), roman.end(), roman.begin(), toupper);
    cout << roman << " is equal to " << toDecimal(roman,  *checker(roman)) << endl;
}

bool checker(string roman){
    int length = roman.length();
    for (int count = 0; count < length; count++){
        string sub = roman.substr(count, count);
        if(sub != "I" || sub != "V" || sub != "X" || sub != "L" || sub != "C" || sub != "D" || sub != "M"){
            cout << "Error. Try Again"<< endl;
            return false;
        }
        else if(convert(roman, count) == convert(roman, count-1) && convert(roman, count) == convert(roman, count+1)){
            if (convert(roman,count) == 1 || convert(roman,count) == 10 || convert(roman,count) == 100 || convert(roman,count) == 1000)
                if(convert(roman, count-1) == convert(roman, count-2) || convert(roman, count+1) == convert(roman, count+2)){
                    cout << "Error Try again" << endl;
                    return false;
                }
            else if (convert(roman,count) == 5 || convert(roman,count) == 50 || convert(roman,count) == 500){
                cout << "Error Try again" << endl;
                    return false;
            }
            else return true;

        }           
    }
    return true;
}

int toDecimal(string s, bool*(checker) (string roman)){
    /**map<char, int> roman;
    roman['M'] = 1000;
    roman['D'] = 500;
    roman['C'] = 100;
    roman['L'] = 50;
    roman['X'] = 10;
    roman['V'] = 5;
    roman['I'] = 1;*/
    checker(s);
    int res = 0;
    for (int i = 0; i < s.length() - 1; ++i){
        int num = convert(s,i);
        res += num;
        /**if (roman[s[i]] < roman[s[i+1]])
            res -= roman[s[i]];
        else
            res += roman[s[i]];
    }
    res += roman[s[s.size()-1]];*/}
    return res;
}

int convert(string roman, int i){
    enum romans {I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000};
    int num = 0;
    char c = roman[0]; 
    switch(c){
        case 'M': 
            num = M; break;
        case 'D':   
            if(i + 1 != roman.size() && roman[i+1] == 'M'){
                num = M - D;break;
            }
            else
                num = D; break;
        case 'C': 
            if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D'){
                if(roman[i+1] == 'M') num = M - C; break;
                if(roman[i+1] == 'D') num = D - C; break;
            }
            else
                num = C; break;
        case 'L':
            if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D' || roman[i+1] == 'C'){
                if(roman[i+1] == 'M') num = M - L; break;
                if(roman[i+1] == 'D') num = D - L; break;
                if(roman[i+1] == 'C') num = C - L; break;
                }
            else
                num = L; break;
        case 'X': 
            if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D' || roman[i+1] == 'C'|| roman[i+1] == 'L'){
                if(roman[i+1] == 'M') num = M - X; break;
                if(roman[i+1] == 'D') num = D - X; break;
                if(roman[i+1] == 'C') num = C - X; break;
                if(roman[i+1] == 'L') num = C - X; break;
            }
                num = X; break;
        case 'V':
            if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D' || roman[i+1] == 'C'|| roman[i+1] == 'L' || roman[i+1] == 'X'){
                if(roman[i+1] == 'M') num = M - V; break;
                if(roman[i+1] == 'D') num = D - V; break;
                if(roman[i+1] == 'C') num = C - V; break;
                if(roman[i+1] == 'L') num = L - V; break;
                if(roman[i+1] == 'X') num = X - V; break;
            }
                num = V; break;
        case 'I':
            if ( i + 1 != roman.size() && roman[i + 1] != 'I'){
                if(roman[i+1] == 'M') num = M - I; break;
                if(roman[i+1] == 'D') num = D - I; break;
                if(roman[i+1] == 'C') num = C - I; break;
                if(roman[i+1] == 'L') num = L - I; break;
                if(roman[i+1] == 'X') num = X - I; break;
            }
                num =1; break;
    }
    return num;
}

** 我在这里添加了人们的帮助。这是一个显示进度/会议的编辑。


这是我用来将罗马数字(小于 3999)转换为整数的代码。您可以检查它是否适用于更大的数字。

int romanToInt(string s) {
    map<char, int> roman;
    roman['M'] = 1000;
    roman['D'] = 500;
    roman['C'] = 100;
    roman['L'] = 50;
    roman['X'] = 10;
    roman['V'] = 5;
    roman['I'] = 1;

    int res = 0;
    for (int i = 0; i < s.size() - 1; ++i)
    {
        if (roman[s[i]] < roman[s[i+1]])
            res -= roman[s[i]];
        else
            res += roman[s[i]];
    }
    res += roman[s[s.size()-1]];
    return res;
}

希望这可以帮助你。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++ 将罗马数字转换为小数 的相关文章

  • HttpResponseMessage 的内容为 JSON

    我有一个 ASP NET MVC WEB API 由于多种原因 由于没有授权而重定向 我不能只使用一个简单的对象并在我的控制器方法中返回它 因此我需要 HttpResponseMessage 类来允许我重定向 目前我正在这样做 var re
  • 对相当大的整数的大集合的操作的快速实现

    描述 我实现了以下类 LabSetInt64 参见下面的代码 这里的目标是尽可能快地操作大量大整数 最多 10M 的值 我的主要要求集中在 至关重要 尽快获取集合的大小 基数 重要 能够非常快速地迭代一组集合 所以 从下面的实现开始 我还有
  • 函数原型和数组参数

    我正在学习 C 语法 并且已经开始研究数组了 我想问你一个问题 但首先让我回顾一下 这样我就知道我已经弄清楚了 我知道您可以使用以下语法将变量定义为数组 name
  • 将内核链接到 PTX 函数

    我可以使用 PTX 文件中包含的 PTX 函数作为外部设备函数 将其链接到另一个应调用该函数的 cu 文件吗 这是另一个问题CUDA 将内核链接在一起 https stackoverflow com questions 20636800 c
  • 优化对绑定到 DataGridView 的 DataTable 的更新

    我的应用程序中有一个显示一些数据的表单 当我第一次显示表单时 我将一些数据加载到 DataTable 中 然后将 DataTable 绑定到 DataGridView 我还启动了一个异步方法来执行一些较慢的数据库查询 当这些慢查询完成时 我
  • 在 C 中声明和初始化数组

    C 有没有办法先声明然后初始化数组 到目前为止 我一直在初始化一个这样的数组 int myArray SIZE 1 2 3 4 但我需要做这样的事情 int myArray SIZE myArray 1 2 3 4 在 C99 中 您可以使
  • CMake - 未定义参考

    我正在尝试将 gtest 包含到我的项目中 问题是我在 GTest 中收到未定义的引用错误 我正在尝试在 Gtest 中测试 Node 类 在节点的构造函数中 我使用类记录器 尽管我已将库记录器添加到 gtest target 中 但我仍然
  • F# 内联如何工作?

    对于 F 我的理解是您可以使用 inline 关键字在调用站点执行类型专门化 那是 val inline a gt b gt c when a or b static member a b gt c 约束条件是 a or b必须有一个静态成
  • 整数与双精度算术性能?

    我正在编写一个 C 类来使用整数执行 2D 可分离卷积 以获得比双对应更好的性能 问题是我没有获得真正的性能提升 这是 X 过滤器代码 对于 int 和 double 情况都有效 foreach pixel int value 0 for
  • 为什么Boost在“程序选项”中使用全局函数覆盖来实现自定义验证器

    这个例子 http www boost org doc libs 1 55 0 doc html program options howto html idp163429032显示一个名为validate在全局范围内定义重载函数boost
  • 让 GCC/Clang 使用 CMOV

    我有一个简单的标记值联合 这些值可以是int64 ts or doubles 我正在对这些联合进行加法 但需要注意的是 如果两个参数都代表int64 t值 那么结果也应该有一个int64 t value 这是代码 include
  • 锁定文件的一个块

    我有一个大小为 192k 的文件 我想锁定文件的中间部分 例如 我想用 c 锁定文件的 64k 128k 知道如何锁定文件的那部分吗 你需要使用锁定文件Ex http msdn microsoft com en us library win
  • 一些涉及类析构函数和删除运算符的内存管理问题?

    在阅读了一些教程后 我仍然不清楚 C 中内存管理的一些观点 1 当使用 new 运算符声明的类超出范围时 是否会调用其析构函数并释放内存 是否有必要调用删除运算符来释放类的内存并调用其析构函数 class Test void newTest
  • DLL 中的 XP 风格组合框

    我需要使用 C 和 WIN32 API 无 MFC 在 DLL 中创建 XP 风格的组合框 我设法在 DLL 中创建控件 不是以 XP 风格 我设法在带有清单的 exe 中创建 XP 样式组合框 但它在 DLL 中不起作用 为了让您的 DL
  • MPI_Gatherv:根数组中收到的垃圾值

    我正在尝试实施MPI Gatherv函数于C 根据我的程序 包括 root 在内的每个进程都应该创建一个大小等于 进程的等级 1 这将在所有单元格中保持进程的等级 然后这个本地数组被收集到根的 rcv array 中 不知何故 我得到了垃圾
  • 如何从句柄确定进程是 32 位还是 64 位?

    如何从使用 OpenProcess 获取的进程句柄中获取信息 无论进程是 32 位还是 64 位 是的 IsWow64Process 毫无用处 令人烦恼 它的真正意思是 启用了 32 位模拟 如果您在 32 位操作系统上运行 则返回 fal
  • 检测用户是否正在滚动 dataGridView 滚动条

    我正在更新一个dataGridView与一个新的数据表使用 dataGridView1 DataSource table 但是 我不想在用户滚动 dataGridView 时执行此操作 如何检查滚动条是否正在滚动或已完成滚动 即拖动而不是单
  • 序列化时如何跳过 xml 声明?

    我正在尝试输出一个没有 xml 头的 xml 文件 例如 我试过 Type t obj GetType XmlSerializer xs new XmlSerializer t XmlWriter xw XmlWriter Create c
  • Azure Function App Azure 服务总线触发器触发两次

    我使用带有服务总线触发器的 Azure Function Apps 来读取服务总线并对服务总线消息的内容执行操作 服务总线接收 JSON 序列化对象 然后将 JSON 消息反序列化回 Function App 中的对象 然而 由于某种原因
  • 即使对于新上下文,OnModelCreating 也仅调用一次

    我有多个相同但内容不同的 SQL Server 表 在编写代码优先 EF6 程序时 我尝试为每个程序重用相同的数据库上下文 并将表名称传递给上下文构造函数 然而 虽然每次都会调用构造函数 但尽管每次都是从 new 创建数据库上下文 但 On

随机推荐