You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按权重反比将1-100整数分配至多100项的加权列表?

问题描述

我有一个元素带权重的列表,示例如下:

std::vector<float> weights{0.5, 2, 5};

列表长度最少为2项,最多为100项。需要将整数1-100(包含两端)按权重反比分配至该列表,使得权重最低的项获得最大的数值范围。

此处的“权重反比”具体规则示例:

  • 输入weights{2, 1},输出应为类似:
    2: 1-33
    1: 34-100
    
  • 输入weights{3,1},输出应为类似:
    3: 1-25
    1: 26-100
    
  • 输入weights{2,1,1},输出应为类似:
    2: 1-25
    1: 26-63
    1: 64-100
    

现有代码无法实现上述反比效果,代码如下:

#include <iostream>
#include <vector>
#include <iomanip>

void distributeNumbers(const std::vector<float>& numbers) {
    float total = 0;
    for (float num : numbers) {
        total += num;
    }

    int start = 1;
    int end = 100;
    std::cout << "Distributing numbers from 1 to 100 based on proportions:" << std::endl;

    for (int i = 0; i < numbers.size(); ++i) {
        float number = numbers[i];
        
        // Calculate the range length for this number
        double proportion = static_cast<double>(total-number) / total;
        int rangeLength = static_cast<int>(proportion * 100);

        // Ensure we don't assign a range of zero length
        if (i == numbers.size() - 1) {
            rangeLength = end - start + 1;
        }

        int currentEnd = start + rangeLength - 1;
        std::cout << number << ": " << start << "-" << currentEnd << std::endl;

        // Update the start for the next number
        start = currentEnd + 1;
    }
}

int main() {
    std::vector<float> numbers = {9, 4, 3, 11, 7, 19, 3};  // Example input: numbers = {6, 2, 2}
    
    distributeNumbers(numbers);
    return 0;
}
问题分析与修正

原代码的核心错误在于比例计算逻辑:(total-number)/total完全不符合“权重反比”的要求。正确的反比逻辑应该是:

  1. 计算每个权重的反比值:1/weight_i,权重越小,反比值越大,对应分配的范围越长
  2. 计算所有反比值的总和totalInverse
  3. 每个项的分配比例为:(1/weight_i) / totalInverse,用该比例乘以100得到大致的范围长度
  4. 处理整数取整的误差,最后一项直接取剩余的所有数值,确保总范围覆盖1-100

修正后的代码如下:

#include <iostream>
#include <vector>
#include <iomanip>
#include <cmath>

void distributeNumbers(const std::vector<float>& weights) {
    double totalInverse = 0.0;
    // 计算所有权重的反比值总和
    for (float w : weights) {
        totalInverse += 1.0 / w;
    }

    int start = 1;
    const int end = 100;
    std::cout << "Distributing numbers from 1 to 100 based on inverse weight proportions:" << std::endl;

    for (size_t i = 0; i < weights.size(); ++i) {
        float w = weights[i];
        // 计算当前项的分配比例
        double proportion = (1.0 / w) / totalInverse;
        // 用round处理取整误差,让结果更贴合比例
        int rangeLength = static_cast<int>(std::round(proportion * 100));

        // 最后一项直接取剩余所有数值,避免累加误差
        if (i == weights.size() - 1) {
            rangeLength = end - start + 1;
        } else {
            // 确保范围长度至少为1,避免极端权重下出现0长度
            rangeLength = std::max(rangeLength, 1);
            // 同时避免超过剩余可用数值
            rangeLength = std::min(rangeLength, end - start + 1);
        }

        int currentEnd = start + rangeLength - 1;
        std::cout << w << ": " << start << "-" << currentEnd << std::endl;

        start = currentEnd + 1;
    }
}

int main() {
    // 测试示例1:weights{2,1}
    std::vector<float> test1 = {2, 1};
    std::cout << "Test 1 input: {2, 1}" << std::endl;
    distributeNumbers(test1);
    std::cout << std::endl;

    // 测试示例2:weights{3,1}
    std::vector<float> test2 = {3, 1};
    std::cout << "Test 2 input: {3, 1}" << std::endl;
    distributeNumbers(test2);
    std::cout << std::endl;

    // 测试示例3:weights{2,1,1}
    std::vector<float> test3 = {2, 1, 1};
    std::cout << "Test 3 input: {2, 1, 1}" << std::endl;
    distributeNumbers(test3);
    std::cout << std::endl;

    // 原示例输入
    std::vector<float> numbers = {9, 4, 3, 11, 7, 19, 3};
    std::cout << "Original input: {9, 4, 3, 11, 7, 19, 3}" << std::endl;
    distributeNumbers(numbers);

    return 0;
}
代码说明
  • 核心逻辑:通过1/weight转换为反比权重,再计算比例,确保权重越小的项分配到越长的数值范围
  • 使用std::round处理取整,比直接截断更符合比例分配的预期
  • 增加了范围长度的边界检查,避免出现0长度或超出剩余数值的情况
  • 最后一项强制取剩余所有数值,确保总范围刚好覆盖1-100

内容的提问来源于stack exchange,提问作者D.G. Redd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 22:53:17