当 return 类型是向量容器时,在 C++ 中是否有 returning Null 的解决方法?
Is there a workaround for returning Null in c++ when the return type is a vector container?
问题是我正在实现一个递归,其中我必须使用NULL
值来指定正在遍历的递归分支是无效的。
但是在 C++ 中我们不能 return NULL
当 return 类型是一个容器(在我的例子中是向量容器)。
那么这个问题是否有任何解决方法,或者我是否必须使用其他逻辑?
代码:
#include<iostream>
#include<vector>
std::vector<int> howSum(int target,std::vector<int> in){
if(target < 0 ) return {-1};
if(target == 0) return {};
for(int num : in){
int remainder = target - num ;
std::vector<int> remResult = howSum(remainder,in);
if(remResult[0] != -1 || remResult.empty()){
remResult.push_back(num);
return remResult;
}
}
return {-1};
}
int main(){
std::vector<int> v = {2,4,3};
int targetSum = 8;
std::vector<int> r = howSum(targetSum,v);
for(int o : r)
std::cout<<o<<" ";
return 0;
}
编辑:
我非常感谢所有的建议和解决方案,但我想要的是一个不使用更新的 c++ 编译(即 c++17 和 c++20)的原始解决方案。
另外,如果可能,请查看我实现的原始解决方案,如果可以改进,请提出一些建议。
我自己找到的替代解决方案(原始解决方案)
我写这篇文章是为了让访问这个问题的人参考。
解决方法:
#include<iostream>
#include<vector>
#include<string>
std::string howSum(int target,std::vector<int> v){
if(target == 0) return "";
if(target < 0) return "null";
for(int num : v){
int rem = target - num;
std::string remRes = howSum(rem,v);
if(remRes != "null"){
remRes += std::to_string(num);
remRes += " ";
return remRes;
}
}
return "null";
}
int main()
{
std::vector<int> v = {2,3,4};
int targetSum = 8;
std::cout<<howSum(targetSum,v);
return 0;
}
我的动态问题解决方案
#include<iostream>
#include<vector>
#include<string>
#include<unordered_map>
std::unordered_map<int,std::string> mem;
std::string howSum(int target, std::vector<int> v){
if(mem.find(target) != mem.end())
return mem[target];
if(target == 0) return "";
if(target < 0) return "null";
for(int num : v){
int rem = target - num;
std::string remRes = howSum(rem,v);
if(remRes != "null"){
remRes += std::to_string(num);
remRes += " ";
mem[target] = remRes;
return mem[target];
}
}
mem[target] = "null";
return mem[target];
}
int main()
{
std::vector<int> v = {7,14};
int targetSum = 300;
std::cout<<howSum(targetSum,v);
return 0;
}
您有以下选择:
Return 结果 + bool
Return std::pair<std::vector<int>, bool>
,或者像这样的结构更好
struct Result {
std::vector<int> result;
bool is_valid;
};
Result howSum(int target, const std::vector<int>& in);
其中 bool
表示结果向量是否实际可用。
输出参数
Return a bool
指示操作是否成功并使用输出参数(请注意,非常量引用用于输出参数,以便可以在功能,后来在它之外使用):
bool howSum(int target, const std::vector<int>& in, std::vector<int>& result);
optional
将 std::optional
与 C++17 或 boost
库中的类似 boost::optional
一起使用:
std::optional<std::vector<int>> howSum(int target, const std::vector<int>& in);
将 std::optional
转换为 bool
或使用 has_value
方法检查您是否返回了实际结果。
请注意,在每种情况下,最好通过 const &
传递输入向量以避免不必要的复制。
使用可选的 (c++17),你可以做这样的事情
#include<iostream>
#include<vector>
#include<optional>
std::optional<std::vector<int>> howSum(int target,std::vector<int> in){
if(target <= 0 ) return {}; // returns "empty" optional
auto num = in.back();
in.pop_back();
int remainder = target - num ;
auto maybe_r = howSum(remainder, in);
if (!maybe_r.has_value())
return howSum(target, in);
else {
auto r = maybe_r.value();
r.push_back(num);
return r;
}
}
int main(){
std::vector<int> v = {2,4,3,1};
int targetSum = 8;
auto maybe_r = howSum(targetSum,v);
if (!maybe_r.has_value()) {
std::cout << "no result\n";
} else {
auto r = maybe_r.value();
for(int o : r)
std::cout<<o<<" ";
}
return 0;
}
问题是我正在实现一个递归,其中我必须使用NULL
值来指定正在遍历的递归分支是无效的。
但是在 C++ 中我们不能 return NULL
当 return 类型是一个容器(在我的例子中是向量容器)。
那么这个问题是否有任何解决方法,或者我是否必须使用其他逻辑?
代码:
#include<iostream>
#include<vector>
std::vector<int> howSum(int target,std::vector<int> in){
if(target < 0 ) return {-1};
if(target == 0) return {};
for(int num : in){
int remainder = target - num ;
std::vector<int> remResult = howSum(remainder,in);
if(remResult[0] != -1 || remResult.empty()){
remResult.push_back(num);
return remResult;
}
}
return {-1};
}
int main(){
std::vector<int> v = {2,4,3};
int targetSum = 8;
std::vector<int> r = howSum(targetSum,v);
for(int o : r)
std::cout<<o<<" ";
return 0;
}
编辑:
我非常感谢所有的建议和解决方案,但我想要的是一个不使用更新的 c++ 编译(即 c++17 和 c++20)的原始解决方案。 另外,如果可能,请查看我实现的原始解决方案,如果可以改进,请提出一些建议。
我自己找到的替代解决方案(原始解决方案)
我写这篇文章是为了让访问这个问题的人参考。
解决方法:
#include<iostream>
#include<vector>
#include<string>
std::string howSum(int target,std::vector<int> v){
if(target == 0) return "";
if(target < 0) return "null";
for(int num : v){
int rem = target - num;
std::string remRes = howSum(rem,v);
if(remRes != "null"){
remRes += std::to_string(num);
remRes += " ";
return remRes;
}
}
return "null";
}
int main()
{
std::vector<int> v = {2,3,4};
int targetSum = 8;
std::cout<<howSum(targetSum,v);
return 0;
}
我的动态问题解决方案
#include<iostream>
#include<vector>
#include<string>
#include<unordered_map>
std::unordered_map<int,std::string> mem;
std::string howSum(int target, std::vector<int> v){
if(mem.find(target) != mem.end())
return mem[target];
if(target == 0) return "";
if(target < 0) return "null";
for(int num : v){
int rem = target - num;
std::string remRes = howSum(rem,v);
if(remRes != "null"){
remRes += std::to_string(num);
remRes += " ";
mem[target] = remRes;
return mem[target];
}
}
mem[target] = "null";
return mem[target];
}
int main()
{
std::vector<int> v = {7,14};
int targetSum = 300;
std::cout<<howSum(targetSum,v);
return 0;
}
您有以下选择:
Return 结果 + bool
Return std::pair<std::vector<int>, bool>
,或者像这样的结构更好
struct Result {
std::vector<int> result;
bool is_valid;
};
Result howSum(int target, const std::vector<int>& in);
其中 bool
表示结果向量是否实际可用。
输出参数
Return a bool
指示操作是否成功并使用输出参数(请注意,非常量引用用于输出参数,以便可以在功能,后来在它之外使用):
bool howSum(int target, const std::vector<int>& in, std::vector<int>& result);
optional
将 std::optional
与 C++17 或 boost
库中的类似 boost::optional
一起使用:
std::optional<std::vector<int>> howSum(int target, const std::vector<int>& in);
将 std::optional
转换为 bool
或使用 has_value
方法检查您是否返回了实际结果。
请注意,在每种情况下,最好通过 const &
传递输入向量以避免不必要的复制。
使用可选的 (c++17),你可以做这样的事情
#include<iostream>
#include<vector>
#include<optional>
std::optional<std::vector<int>> howSum(int target,std::vector<int> in){
if(target <= 0 ) return {}; // returns "empty" optional
auto num = in.back();
in.pop_back();
int remainder = target - num ;
auto maybe_r = howSum(remainder, in);
if (!maybe_r.has_value())
return howSum(target, in);
else {
auto r = maybe_r.value();
r.push_back(num);
return r;
}
}
int main(){
std::vector<int> v = {2,4,3,1};
int targetSum = 8;
auto maybe_r = howSum(targetSum,v);
if (!maybe_r.has_value()) {
std::cout << "no result\n";
} else {
auto r = maybe_r.value();
for(int o : r)
std::cout<<o<<" ";
}
return 0;
}