2466. 统计构造好字符串的方案数

中等

相关标签

相关企业

提示

给你整数 zero ,one ,low 和 high ,我们从空字符串开始构造一个字符串,每一步执行下面操作中的一种:

  • 将 '0' 在字符串末尾添加 zero  次。
  • 将 '1' 在字符串末尾添加 one 次。

以上操作可以执行任意次。

如果通过以上过程得到一个 长度 在 low 和 high 之间(包含上下边界)的字符串,那么这个字符串我们称为  字符串。

请你返回满足以上要求的 不同 好字符串数目。由于答案可能很大,请将结果对 109 + 7 取余 后返回。

示例 1:

输入:low = 3, high = 3, zero = 1, one = 1
输出:8
解释:
一个可能的好字符串是 "011" 。
可以这样构造得到:"" -> "0" -> "01" -> "011" 。
从 "000" 到 "111" 之间所有的二进制字符串都是好字符串。

示例 2:

输入:low = 2, high = 3, zero = 1, one = 2
输出:5
解释:好字符串为 "00" ,"11" ,"000" ,"110" 和 "011" 。

提示:

  • 1 <= low <= high <= 105
  • 1 <= zero, one <= low

代码:
 

class Solution {
public:
    int countGoodStrings(int low, int high, int zero, int one) {
        vector<int> dp(high + 1);
        dp[0] = 1;
        int res = 0;
        int mod = 1000000007;
        for (int i = 1; i <= high; i++) {
            if (i >= zero) {
                dp[i] = (dp[i - zero] + dp[i]) % mod;
            }
            if (i >= one) {
                dp[i] = (dp[i] + dp[i - one]) % mod; 
            }
            if (i >= low) {
                res = (res + dp[i]) % mod;
            }
        }
        return res;
    }
};

<think>好的,我现在需要解决如何在C++中将包含空格分隔数字的字符串转换为整数数组,并且不能使用vector库。首先,我应该回忆一下C++中处理字符串数组的基本方法。 用户的问题明确要求不使用vector,所以必须使用传统数组。可能需要动态分配内存或者预先确定数组的大小。首先,我需要解析输入的字符串,提取其中的每个数字,然后将它们转换为整数存入数组。 第一步,分割字符串。C++中没有内置的split函数,所以需要手动处理。可以遍历字符串,遇到空格就分割。或者使用istringstream配合提取运算符,这样可以自动处理空格分隔的数据。这可能是一个有效的方法,因为istringstream可以逐个读取数字。 然后,如何处理动态数组的大小?因为输入字符串中的数字数量不确定,可能需要先统计数字的数量,然后分配足够大的数组。或者,用户可能希望预定义一个足够大的静态数组,但这可能有容量限制。但通常动态分配更灵活。 所以步骤可能是这样的: 1. 使用istringstream读取字符串中的每个数字,并统计数量。 2. 根据数量动态分配int数组。 3. 再次遍历字符串,将每个数字存入数组。 但这样需要两次遍历:第一次统计数量,第二次存储数值。这可能效率不高,但对于小数据量来说是可接受的。 或者,可以一次性读取所有数字到一个临时存储结构中,比如动态增长的数组。但用户不允许使用vector,所以必须手动处理。例如,使用指针realloc,但在C++中更常用newdelete,但需要注意内存管理。 例如,可以先分配一个初始大小的数组,比如10个元素,然后当数量超过时,扩展数组的大小。但这个过程需要手动管理,比较麻烦,容易出错。 不过,可能更简单的方法是先统计数字的数量。例如,遍历字符串统计空格的数量,从而确定数字的数量。但要注意多个连续空格的情况,或者开头、结尾的空格。 或者,使用istringstream逐个读取数字,并在读取时计数。这可以更准确,因为istringstream会自动跳过空格,不管有多少个空格,或者开头结尾的空格。 所以具体步骤可能是: - 将输入字符串包装成istringstream对象。 - 使用循环逐个读取数字,同时计数,直到读取失败。 - 得到数字的总数count。 - 使用new分配一个大小为count的int数组。 - 重新遍历字符串,将每个数字存入数组。 或者,在第一次遍历时,可以将数字保存到临时数组中,但需要动态调整数组的大小。例如,初始分配一个较大的数组,或者在每次超过容量时扩展。 或者,是否可以同时统计数量存储数值?比如,先分配一个较大的数组(比如100个元素),然后逐个读取数字,直到读完为止,记录实际数量。这样可能不需要两次遍历,但需要假设数组足够大,否则会溢出。 不过,用户的问题中没有说明输入字符串的最大长度,所以可能需要动态调整数组大小。但手动实现动态数组比较复杂。 因此,可能更可靠的方法是先统计数字的数量,然后分配数组,再读取数字。虽然需要两次遍历,但较为安全。 现在,具体实现: 例如,输入字符串是"1 2 3 4 5",那么: 1. 创建istringstream对象,读取每个数字,每读取一个,计数器加一。 统计到5个数字。 2. 分配int* arr = new int[5]; 3. 再次创建istringstream,逐个读取数字到数组中。 或者,是否可以在第一次读取时同时存储到一个临时数组中?例如,使用足够大的临时数组,或者动态调整数组的大小。但如果不使用vector,手动处理动态数组扩展会比较麻烦。比如,初始分配一个容量,当不够时,扩展容量,这需要复制数据到新的数组,释放旧的数组,容易出错。 因此,可能两次遍历的方法更可行,尤其是当输入的字符串不是特别长的时候。 现在,如何统计数字的数量? 代码如下: #include <sstream> #include <string> using namespace std; int countNumbers(const string& s) { istringstream iss(s); int num; int count = 0; while (iss >> num) { count++; } return count; } 然后,根据count分配数组: int* arr = new int[count]; 再重新读取: istringstream iss(s); for (int i = 0; i < count; i++) { iss >> arr[i]; } 这样应该可以正确填充数组。但需要注意,两次使用istringstream,每次都会从头开始读取,所以是正确的。 这样整个流程就完成了。需要注意内存管理,用户需要记得用delete[]释放数组。 此外,用户可能需要返回数组及其大小,因此可能需要将数组指针大小作为参数传出,或者使用结构体。但在C++中,通常通过引用参数来传递大小。 例如,函数可能是这样的: void convertStringToIntArray(const string& str, int*& arr, int& size) { // 统计数量 size = countNumbers(str); // 分配数组 arr = new int[size]; // 填充数组 istringstream iss(str); for (int i=0; i<size; i++) { iss >> arr[i]; } } 用户调用这个函数后,得到arrsize,使用完毕后必须delete[] arr。 这样就能满足需求,并且不需要使用vector。 现在,关于可能的错误处理,比如字符串中包含非数字字符。例如,如果输入是"1 a 3",那么istringstream在读取到a时会失败,此时countNumbers可能返回1,而不是正确的数值。这会导致后续数组填充时出现问题。因此,需要考虑输入的有效性。 但用户的问题可能假设输入是有效的,所有空格分隔的部分都是整数。如果需要处理无效输入,可能需要进行错误检查。但根据问题描述,可能用户不需要处理这种情况,所以可以假设输入正确。 综上,解决方案的大致步骤是: 1. 使用istringstream统计数字的数量。 2. 动态分配数组。 3. 再次使用istringstream读取数字到数组中。 4. 返回数组指针大小。 这样就能实现将字符串转换为整数数组,而不使用vector库。 现在,编写完整的代码示例: #include <iostream> #include <sstream> #include <string> using namespace std; int countNumbers(const string& s) { istringstream iss(s); int num; int count = 0; while (iss >> num) { count++; } return count; } void convertStringToIntArray(const string& str, int*& arr, int& size) { size = countNumbers(str); arr = new int[size]; istringstream iss(str); for (int i = 0; i < size; i++) { iss >> arr[i]; } } int main() { string input = "10 20 30 40 50"; int* arr = nullptr; int size = 0; convertStringToIntArray(input, arr, size); cout << "Converted array: "; for (int i = 0; i < size; i++) { cout << arr[i] << " "; } cout << endl; delete[] arr; return 0; } 这样应该可以正确运行。用户输入字符串,输出整数数组。 另外,用户提到的引用[^1]中提到了ostringstream,但在这里使用的是istringstream,这是正确的,因为需要从字符串中读取输入。 引用[^2]中的cv::Mat相关的拷贝构造可能不相关,但问题中的解决方法未涉及这部分。 综上,这个方案符合用户的需求,没有使用vector,而是手动管理动态数组,使用istringstream处理字符串分割转换。</think>在C++中,将包含空格分隔数字的字符串转换为整数数组且不使用`vector`库,可以通过以下步骤实现: 1. **统计数字数量**:使用`std::istringstream`遍历字符串统计数字的总数。 2. **动态分配数组**:根据统计的数量,通过`new`动态分配整数数组内存。 3. **填充数组**:再次使用`std::istringstream`将字符串中的数字存入数组。 示例代码如下: ```cpp #include <iostream> #include <sstream> #include <string> int countNumbers(const std::string& s) { std::istringstream iss(s); int num, count = 0; while (iss >> num) count++; return count; } void convertStringToIntArray(const std::string& str, int*& arr, int& size) { size = countNumbers(str); arr = new int[size]; std::istringstream iss(str); for (int i = 0; i < size; i++) iss >> arr[i]; } int main() { std::string input = "10 20 30 40 50"; int* arr = nullptr; int size = 0; convertStringToIntArray(input, arr, size); std::cout << "数组内容:"; for (int i = 0; i < size; i++) std::cout << arr[i] << " "; std::cout << "\n"; delete[] arr; return 0; } ``` ### 关键点说明 - **统计数量**:通过`std::istringstream`逐个读取数字并计数,确保动态分配内存的准确性。 - **动态数组管理**:使用`new``delete[]`手动管理内存,避免依赖`vector`。 - **输入有效性**:假设输入字符串仅包含有效数字空格,未处理异常字符(需额外逻辑完善)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值