将未知类型的元素输入向量

2023-11-26

我正在开发一个程序,该程序从用户那里获取元素并对它们进行排序。对于这个程序,我必须使用向量,因为元素列表的大小在用户输入之前是未知的。我们的指示是:

用C++编写一个程序来实现元素列表的排序。 元素可以是任何类型,但都属于相同类型,就像所有元素一样 整数或所有浮点数或所有字符或所有字符串(字符串应为 像字典一样排序)。您可以实现任何排序算法 你的选择。

  1. 询问用户有多少个元素
  2. 要求用户输入元素
  3. 要求用户选择排序顺序:升序或降序或两者兼而有之
  4. 打印输入和输出列表
  5. 用户不会提供有关元素类型的任何信息

我对向量不太熟悉(老师基本上在课堂上略读了主题),而且我的书没有给我提供有关该主题的大量信息。我遇到的问题是,在用户开始输入之前我不知道元素列表的类型。到目前为止,我已经尝试过:

  • 创建一个 void 类型向量(显然不允许,因为我已经研究过它了,哎呀)
  • 重载一个名为的函数insertInVector通过将第一个元素发送到函数并让函数根据第一个元素的类型确定要创建的向量类型(当我想到它时,这似乎是我的最佳选择,除非我需要在函数终止后访问向量,所以这最终也是不行的)
  • #include <typeinfo>在程序中,找到第一个元素的类型,然后 使用创建向量vector<typeid(firstElement).name()>老实说我不是 确定为什么这不起作用,但事实并非如此。

就像我说的,我对矢量的经验极其有限,因为这是我第一次使用它们。我也是一个相当新的程序员,所以我对此所做的很多研究都超出了我的理解范围。对此提供的任何帮助将不胜感激!


C++是一种语言静态地键入。这意味着所有类型都应该在编译期间确定:运行程序时不能引入新类型。

  • 创建一个 void 类型向量(显然不允许,因为我已经研究过它了,哎呀)

void实际上是一个相当奇怪的类型,主要是当您期望一个类型(如函数返回类型)但没有提供任何类型时的占位符。void*用作指向未知类型的指针(主要在 C 中),但这完全是一个 hack,因为有关原始类型的信息被丢弃(就语言而言),因此这会导致实际使用该值执行操作时出现问题,因此获得。

  • 通过将第一个元素发送到函数并让函数根据第一个元素的类型确定要创建的向量类型来重载名为 insertInVector 的函数

  • #include <typeinfo>在程序中,找到第一个元素的类型,然后使用创建一个向量vector<typeid(firstElement).name()>老实说,我不知道为什么这不起作用,但它没有起作用。

不幸的是,这两种情况都不可能:因为你不能声明没有类型的变量,那么变量的类型是什么?firstElement首先?


你所描述的问题总体来说是比较困难的。基本上,这意味着您必须接受一串字符,然后编写一组规则来确定如何解释这些字符。这通常是通过使用grammar对这些规则进行编码;但对于可能很简单的任务来说,语法可能会变得复杂。

让我举一个小例子:

class Input {
public:
    enum Type {
        Int,
        Double,
        String
    };

    static Input Parse(std::string const& s);

    Input(): _type(Int), _int(0), _double(0.0) {} // need to define a default...

    Type type() const { return _type; }

    int asInt() const {
        assert(_type == Int && "not an int");
        return _int;
    }

    double asDouble() const {
        assert(_type == Double && "not a double");
        return _double;
    }

    std::string const& asString() const {
        assert(_type == String && "not a string");
        return _string; 
    }

private:
    Type _type;
    int _int;
    double _double;
    std::string _string;
};

显然,真正的挑战是正确地Parse输入。

这个想法是使用一组规则,例如:

  • an int仅由数字组成,可选地带有前缀-
  • a double完全由数字组成,最多有一个.并可选地加上前缀-
  • a string可以是任何东西,因此是我们的包罗万象

然后我们就可以写识别部分了Parse method:

static bool isInt(std::string const& s) {
    if (s.empty()) { return false; }
    
    // The first character may be among digits and '-'
    char const first = s.at(0);
    if (not isdigit(first) and first != '-') { return false; }

    // Subsequent characters may only be digits
    for (char c: s.substr(1)) {
        if (not isdigit(c)) { return false; }
    }

    // Looks like it is an int :)
    return true;
} // isInt

// Note: any int could be interpreted as a double too
static bool maybeDouble(std::string const& s) {
    if (s.empty()) { return false; }

    // The first character may be among digits, '.' and '-'
    char const first = s.at(0);
    if (not isdigit(first) and first != '.' and first != '-') { return false; }

    // There may only be one dot
    bool hasSeenDot = s.at(0) == '.';

    // Subsequent characters may only be digits and a dot now
    for (char c: s.substr(1)) {
        if (not isdigit(c) and c != '.') { return false; }

        if (c == '.') {
            if (hasSeenDot) { return false; } // no second dot allowed
            hasSeenDot = true;
        }
    }

    // Looks like it could be a double
    return true;
} // maybeDouble

static Input::Type guessType(std::string const& s) {
    if (isInt(s)) { return Input::Int; }

    // Test double after we ensured it was not an int
    if (maybeDouble(s)) { return Input::Double; }

    return Input::String;
} // guessType

加上猜测逻辑,最后解析出来了:

Input Input::Parse(std::string const& s) {
    Input result;

    result._type = guessType(s);

    switch(result._type) {
    case Input::Int: {
        std::istringstream stream(s);
        s >> result._int;
        return result;
    }
    case Input::Double: {
        std::istringstream stream(s);
        s >> result._double;
        return result;
    }
    case Input::String:
        result._string = s;
        return result;
    }

    // Unreachable (normally)
    abort();
} // Input::Parse

Phew!

所以 ?差不多了。现在我们需要确定如何比较两个输入。如果它们都具有相同的类型,则很容易,否则您将需要确定任意逻辑。您可以轻松地将输入 Int 转换为输入 Double,但对于字符串来说有点奇怪。

// define < for comparing two instance of "Input",
// assuming they both have the same type
bool operator<(Input const& left, Input const& right) {
    assert(left.type() == right.type() && "Different Types!");

    switch(left.type()) {
    case Input::Int: return left.asInt() < right.asInt();
    case Input::Double: return left.asDouble() < right.asDouble();
    case Input::String: return left.asString() < right.asString();
    }
} // operator<

最后,该程序:

int main(int argc, char* argv[]) {
    // parse command line
    std::vector<Input> inputs;

    // by convention argv[0] is the program name, it does not count!
    for (int i = 1; i != argc; ++i) {
        inputs.push_back(Input::Parse(argv[i]));

        // Detect that the type is the same as the first input
        if (inputs.size() >= 2) {
            if (inputs.back().type() != inputs.front().type()) {
                std::cerr << "Please only use one type among Int, Double and String\n";
                return 1; // non-0 is an error
            }
        }
    }

    // sort
    std::sort(inputs.begin(), inputs.end());

    // echo back to the user
    for (Input const& i: inputs) {
        switch(i.type()) {
        case Input::Int: std::cout << i.asInt() << "\n"; break;
        case Input::Double: std::cout << i.asDouble() << "\n"; break;
        case Input::String: std::cout << i.asString() << "\n"; break;
        }
    }

    // End of the program
    return 0;
}

当然,因为我不知道你想要处理的类型..我已经决定了一个任意的集合;)但这应该给你一个框架来作为自己的基础。

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

将未知类型的元素输入向量 的相关文章

  • 获取 TextBox 中的文本行数

    我试图通过标签显示文本框中的文本行数 但是 问题是如果最后一行为空 标签必须显示没有空行的行号 例如 如果它们有 5 行 最后一行为空 则标签应将行数显示为 4 Thanks private void txt CurrentVinFilte
  • C# 中直接从 URL 获取图像尺寸

    我正在尝试使用以下代码直接从网络上获取图片的尺寸 string image http www hephaestusproject com csharp3 png byte imageData new WebClient DownloadDa
  • 无需登录即可在 Intranet 上获取 Web 应用程序的域\用户名

    我的 Intranet 上有一个 Web 应用程序 VS 2005 有几个页面不需要用户登录应用程序 反馈和默认页面 我正在尝试获取要显示和 或发送反馈的域名和用户名 有没有一种方法可以在不需要用户登录的情况下执行此操作 我试过了this
  • C++0x 初始值设定项列表示例

    我想看看这个现有代码示例如何利用 C 0x 初始化列表功能 示例0 include
  • 在异步请求中使用超时回调

    我之前问过这个问题 但我将用提出的解决方案来完成这个问题 并提出另一个问题 我正在使用这个类来进行异步网络请求 http msdn microsoft com en us library system net webrequest aspx
  • 何时使用 C++ 私有继承而不是组合?

    你能给我一个具体的例子吗 什么时候使用私有继承优于组合 就我个人而言 我将使用组合而不是私有继承 但在某些情况下 使用私有继承可能是特定问题的最佳解决方案 正在阅读C faq http www parashift com c faq lit
  • 静态 OpenCV 库中未定义的引用

    我有一个使用 OpenCV 3 1 的 C 项目 并且使用共享库可以正常工作 但现在我想使用静态库 位于项目目录中的文件夹中 来编译它 因为我希望能够在未安装 OpenCV 的情况下导出它 如果需要还可以编辑和重新编译 这次我重新编译了 O
  • 从 Golang 调用 C 函数

    我想在 Golang 中编写控制器逻辑并处理 json 和数据库 同时在 C 中使用我的数学处理模型 在我看来 调用 C 函数的开销必须尽可能低 就像设置寄存器 rcx rdx rsi rdi 一样 执行一些操作fastcall 并获取 r
  • 原子的 C++ 内存屏障

    在这方面我是个新手 谁能提供以下内存屏障之间差异的简化解释 窗户MemoryBarrier 围栏 mm mfence 内联汇编asm volatile memory 内在的 ReadWriteBarrier 如果没有简单的解释 一些好文章或
  • 何时分离或加入 boost 线程?

    我有一个方法 大约每 30 秒触发一次 我需要在一个线程中包含它 我有一个可以从类外调用的方法 像 call Threaded Method 这样的东西会创建一个线程 该线程本身会调用最终的线程方法 这些是 MyClass 的方法 void
  • 确定相关词的编程方式?

    使用网络服务或软件库 我希望能够识别与词根相关的单词 例如 座位 和 安全带 共享词根 座位 但 西雅图 不会被视为匹配 简单的字符串比较对于这类事情似乎是不可行的 除了定义我自己的字典之外 是否有任何库或 Web 服务不仅可以返回单词定义
  • 如何解决文件被另一个进程使用的问题?

    我一直在 VS NET 2010 中调试 没有任何问题 但现在无法建造 我收到错误 Unable to copy file filename to bin Debug filename The process cannot access t
  • 这些工作队列标志意味着什么?

    在研究工作队列时 我遇到了内核中定义的工作队列标志和常量 我有以下我无法理解的疑问 这里的排水和救援到底是什么意思 WQ DRAINING 1 lt lt 6 internal workqueue is draining WQ RESCUE
  • 如何使用 C# 将表格粘贴到 Ms-Word 文档的末尾

    我有一个预制的 Word 模板 其中有一个表格 我想打开它 然后在文档末尾添加 粘贴 另一个表格 问题是它不会转到文档的末尾 而是将新表格粘贴到原始表格的第一个单元格中 任何帮助将不胜感激 previous code copied a ta
  • Code::Blocks 中的调试似乎不起作用 - 缺少调试符号

    我正在尝试在 Code Blocks 中调试程序 我跟着本指南 http wiki codeblocks org index php title Debugging with Code Blocks and 这个短视频 http www y
  • 文本框中“结束编辑”的事件

    我正在 winform c 中使用文本框 并使用文本在数据库中进行查询 但每次文本更改时 我都需要不断查阅文本框的文本 因此 对于这些 我使用 KeyUp 但这个活动太慢了 文本框编辑完成后是否会触发任何事件 我考虑完成2个条件 控制失去焦
  • 在 C# 窗口应用程序中运行 C/C++ 控制台应用程序?

    现在 我想开发一个简单的应用程序 因此我决定最快的编码方式是 C NET 但现在 我很难实现我需要的功能之一 我想做的是在 C 应用程序的窗口内运行 C C 控制台应用程序 就像在虚幻前端中一样 添加一点通信方式 以便我可以为控制台应用程序
  • C# 模式匹配

    我对 C 有点陌生 我正在寻找一个字符串匹配模式来执行以下操作 我有一个像这样的字符串 该书将在 唐宁街 11 号接待处 并将由主要医疗保健人员参加 我需要创建一个 span 标签来使用 startIndex 和 length 突出显示一些
  • 包含从代码隐藏 (ASP.NET C#) 到 ASPX 中的图像概述的图像列表 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Web API 2.0 使用 pascalcase 模型接收驼峰式命名的 JSON 数据

    我正在尝试对我的 Web API 进行 PUT 调用 我在 WebApiConfig cs 中设置了以下内容 以处理以驼峰形式将数据发送回我的 Web 项目 config Formatters JsonFormatter Serialize

随机推荐

  • TLD 可能有多长?

    我正在 PHP 中开发电子邮件验证正则表达式 我需要知道 TLD 可能持续多长时间并且仍然有效 我做了一些搜索 但找不到有关该主题的太多信息 那么 TLD 可能有多长 DNS 允许单个标签最多使用 63 个字符
  • QuickBooks QBFC 说明

    QBFC是什么 将第三方程序的发票和采购订单过帐到 QuickBooks 时如何运作 我应该将哪个 QBFC 版本与 QuickBooks 2008 一起使用 我只是想知道QBFC是什么 它是一个 COM 库 构建 QuickBooks 可
  • Electron v1.7:关闭、最大化和最大化

    我正在尝试构建一个具有关闭 最大化和最小化按钮的简单应用程序 该应用程序的问题是 关闭 最大化 和 最小化 无法正常工作 这console log 单击按钮时 它可以正常运行并显示正确的消息 但是 它不会执行实际的关闭 最大化和最小化操作
  • 跨平台 numpy.random.seed()

    The docs say 兼容性保证 固定的种子和固定的调用系列 使用相同参数的 RandomState 方法总是会产生 舍入误差的结果相同 除非这些值是 不正确 错误的值将被修复 NumPy 版本将在 进行了哪些修复将在相关文档字符串中注
  • django.db.utils.ProgrammingError:无法将类型 uuid 转换为整数

    我尝试将我的网站上传到 Heroku 服务器并陷入这个问题 当我尝试迁移数据库时出现错误 上述异常是导致以下异常的直接原因 return self cursor execute sql params File app heroku pyth
  • iframe Safari 中的跨域 cookie

    我在 iframe 从另一个域加载站点 中设置 cookie 时遇到问题 在我的网站 X COM 上我加载 Y COM 尝试设置 cookie 但 Safari 阻止了它们 因为之前没有访问过该网站 因此加载 Y COM 失败 因为没有 c
  • 谷歌地图API绘制带有编码点的折线

    我是 javascript 和 Google 地图 api 的新手 所以我编码了这样的点 yzocFzynhVq n o nzD 并尝试用它绘制折线 我还没有找到主题或文档来解决我的问题 关于如何解码它的主题很少 但我不需要这样做 我只需要
  • UIPageViewController 具有不同的 ViewController,正确的方法吗?

    基本上 我有一个表视图控制器和一个普通的视图控制器 我想这样做 以便我可以在视图控制器之间滑动 就像在应用程序的主屏幕上一样 显然是相同类型的视图控制器 但我发现的是UIpageviewcontroller通常当您有同一类型的多个视图时使用
  • 对于 DB2 和 Oracle,使用 java 插入 BLOB

    我目前正在验证在 Oracle 上为 DB2 开发的应用程序 由于我们不想维护两个单独的源 因此我需要一些查询来将 blob 插入到一个字段中 该查询在 oracle 和 db2 中都适用 我没有任何标识符来区分应用程序在哪个数据库下运行
  • 具有重复键的java映射[重复]

    这个问题在这里已经有答案了 我正在创建一个需要存储键值对的程序 程序需要接受键形式的请求 并返回相应的值 问题是有时每个键有多个值 并且映射类不允许重复的键 这些值是数字 因此我无法像使用字符串那样有意义地连接这些值 有没有一种优雅的方法来
  • 如何通过凭据使用 UrlFetchApp?谷歌脚本

    我正在尝试使用 Google Scripts UrlFetchApp 通过基本用户名和密码访问网站 一旦我连接到该站点 就会出现一个需要身份验证的弹出窗口 我知道登录名和密码 但我不知道如何在 UrlFetchApp 中传递它们 var r
  • 使用 dplyr 调用 R 中的 prop.test 函数

    我正在尝试计算几个二项式比例置信区间 我的数据位于数据框中 尽管我可以成功提取estimate从返回的对象prop test the conf int在数据帧上运行时变量似乎为空 library dplyr cases lt c 50000
  • 部署 vue js 应用程序并在路由中收到 404 错误

    我正在使用简单的 webpack 但是将我的应用程序部署到托管服务器后 我的索引页面工作正常 但其他页面给出 404 错误 请我不知道是否有人知道发生了什么 简单的 webpack 只生成构建 js 文件我就是这样 我的 dist 文件夹中
  • matplotlib 等高线图:关于“未找到等高线水平”的警告

    我正在研究博客上的一个例子post关于绘制动画matplotlib 一个例子涉及等高线图 代码如下 但是 当我运行这段代码时 我得到了UserWarning UserWarning No contour levels were found
  • CIL 中的普通操作码和短格式操作码有什么区别?

    我正在查看 CIL 中的各种操作码 发现很多类似的代码 例如 Beq Beq S Bge Bge S Bgt Bgt S 溴 溴 S 其中 S 被认为是 缩写形式 这意味着什么 指令的简短形式占用更少的空间 也就是说 CIL 指令的二进制编
  • 使用 java sdk 使用哈希范围架构从给定哈希键查询 DynamoDB 中的所有项目

    EDIT 其实我错了 当我想要查询解释我的错误的索引时 我正在查询表 不过 维克多的解决方案是有效的 原来的 我在 DynamoDB 中有一个带有哈希范围键架构的表 我需要能够获取与特定哈希键关联的所有项目 但它似乎需要范围键条件 我的问题
  • 实施二元交叉熵损失给出了与 Tensorflow 不同的答案

    我正在实施二元交叉熵Raw python 的损失函数 但它给了我一个与 Tensorflow 非常不同的答案 这是我从 Tensorflow 得到的答案 import numpy as np from tensorflow keras lo
  • 清除通知徽章而不删除通知

    在我的应用程序中 我收到徽章编号设置为 1 的推送通知 当应用程序启动时 它应该将徽章计数设置为 0 所以我使用 UIApplication sharedApplication setApplicationIconBadgeNumber 0
  • 如何检查某物是否是拉斐尔物品?

    给定一个 JavaScript 对象 我如何检查它是否是 Raphael 对象 不是纸张 而是圆 路径等 Raphael el代表通用元素原型 我想我想测试一下 x proto Raphael el 以跨浏览器的方式 但我不完全确定 详细说
  • 将未知类型的元素输入向量

    我正在开发一个程序 该程序从用户那里获取元素并对它们进行排序 对于这个程序 我必须使用向量 因为元素列表的大小在用户输入之前是未知的 我们的指示是 用C 编写一个程序来实现元素列表的排序 元素可以是任何类型 但都属于相同类型 就像所有元素一