麻烦的C++格式化输出 - 数值操作的期望计算问题 题目解析 | 豆包MarsCode AI刷题

72 阅读4分钟

1. 问题回顾

问题描述

小R有两个正整数aa和bb,她将随机选择其中一个数并将其乘以22。这个操作会进行两次,操作后的两个数之和会有所变化。小R想知道,操作结束后,两个数之和的期望值是多少?

例如:如果 a=3a=3 和 b=3b=3,那么有 1/21/2 的概率两数之和为 1212,1/21/2 的概率两数之和为 1515。因此,期望值为 13.513.5。


测试样例

样例1:

输入:a = 3 ,b = 3
输出:'13.50'

样例2:

输入:a = 5 ,b = 7
输出:'27.00'

样例3:

输入:a = 1 ,b = 1
输出:'4.50'

2. 个人代码

using namespace std;

string solution(int a, int b) {
    double result = 0;
    result = (9.0 * a + 9.0 * b) / 4.0;
    ostringstream oss; 
    oss << fixed << setprecision(2) << result;
    return oss.str();
}


问题分析

  1. 操作定义

    • 每次操作随机选择 a 或 b 并将其乘以2。
    • 操作进行两次。
  2. 可能的结果

    • 选择 a 两次:a 被乘以4,b 保持不变,和为 4a + b
    • 选择 a 一次,选择 b 一次:a 和 b 都被乘以2,和为 2a + 2b
    • 选择 b 两次:b 被乘以4,a 保持不变,和为 a + 4b
  3. 概率计算

    • 每种情况的概率均为 1/4
  4. 期望值计算

    • 期望值公式:E = (1/4)*(4a + b) + (1/2)*(2a + 2b) + (1/4)*(a + 4b)
    • 合并同类项:E = 9(a + b)/4

时间复杂度

该函数的时间复杂度是 O(1) ,即常数时间复杂度。具体分析如下:

  1. 数学运算

    • 计算 (9.0 * a + 9.0 * b) / 4.0 包含两个乘法和一个加法,以及一个除法。这些操作都是常数时间操作,与输入规模无关。
  2. 字符串格式化

    • 使用 ostringstream 进行格式化输出,设置 fixed 和 setprecision(2) 也是常数时间操作。
    • 将双精度浮点数转换为字符串的时间复杂度也是常数级别的,因为双精度浮点数的位数是固定的。

综上所述,函数的所有操作都是常数时间操作,因此时间复杂度为 O(1)。

空间复杂度

该函数的空间复杂度是 O(1) ,即常数空间复杂度。具体分析如下:

  1. 变量空间

    • 变量 result 是一个双精度浮点数,占用固定空间。
    • ostringstream 对象 oss 内部的缓冲区空间是固定的,不随输入规模增长而变化。
  2. 输出字符串

    • 返回的字符串长度是固定的,因为总是保留两位小数,因此占用的空间是常数级别的。

综上所述,函数使用的空间不随输入规模增长而变化,因此空间复杂度为 O(1)。

3. 问题之外 - C++中的格式化输出

一、基本输出方式

在 C++ 里,通过iostream库中的cout对象结合插入操作符<<来实现基本的输出到控制台操作。比如要输出一个字符串或者一个变量的值,就可以依次将它们通过<<插入到输出流中,最后可能还会加上endl来实现换行并刷新输出缓冲区,确保输出能及时显示出来。

二、整数格式化输出

  1. 指定宽度
    可以利用setw()函数(需包含<iomanip>头文件)设定输出字段的宽度。如果输出的值宽度小于设定宽度,会在前面填充空格以达到设定宽度。
  2. 对齐方式
    默认是右对齐,若要设置左对齐或保持右对齐,可借助setiosflags()函数(同样要包含<iomanip>头文件)结合ios::leftios::right来实现。
  3. 进制输出
    使用hexoctdec操作符能分别输出十六进制、八进制和十进制的整数。并且在输出其他进制后,若要恢复十进制输出,需再次使用dec操作符。

三、浮点数格式化输出

  1. 指定小数位数
    通过setprecision()函数(来自<iomanip>头文件)可设置浮点数的小数位数。要注意它对后续所有浮点数输出都起作用,直至重新设置新的精度。
  2. 固定格式输出
    利用fixed操作符(<iomanip>头文件)能以固定小数位数的格式输出浮点数,而不是科学计数法形式。
  3. 科学计数法输出
    使用scientific操作符(<iomanip>头文件)则可让浮点数以科学计数法输出。

四、字符串格式化输出

对于字符串输出,同样能使用setw()函数设置输出宽度,其遵循和整数、浮点数输出时关于宽度和对齐方式的类似规则。

五、自定义格式化输出

除了运用标准库提供的格式化工具外,还可以自行定义格式化输出函数。比如根据特定需求,像按照某种特定格式输出日期等,通过合理组合如setfill()setw()等函数来实现想要的输出格式效果。