将ruby解决方案移植到c++
Port ruby solution to C++
在c++中是否有办法做到这一点,特别是在range部分
answer = (0..999).select { |a| a%3 ==0 || a%5==0 }
puts answer.inject { |sum, n| sum+n }
我已经创建了自己的c++解决方案,但使用更标准的for循环,想知道是否有更酷的方法来做到这一点?
模板元编程解决方案:
下面假设范围的下界为0。
template <int N>
struct sum
{
static const int value = sum<N-1>::value + (N % 3 == 0 || N % 5 == 0 ? N : 0);
};
template <>
struct sum<0>
{
static const int value = 0;
};
int main(int argc, char** argv)
{
int n = sum<999>::value;
return 0;
}
下面将允许您指定一个数字范围(例如0-999,20-400)。我不是模板元编程的大师,所以我想不出一个更简洁的解决方案(我这样做是为了我自己的利益和实践)。
template <int N, int Upper, bool IsLast>
struct sum_range_helper
{
static const int value = (N % 3 == 0 || N % 5 == 0 ? N : 0) + sum_range_helper<N + 1, Upper, N + 1 == Upper>::value;
};
template <int N, int Upper>
struct sum_range_helper<N, Upper, true>
{
static const int value = (N % 3 == 0 || N % 5 == 0 ? N : 0);
};
template <int Lower, int Upper>
struct sum_range
{
static const int value = sum_range_helper<Lower, Upper, Lower == Upper>::value;
};
int main(int argc, char** argv)
{
int n = sum_range<0, 999>::value;
return 0;
}
未经测试的代码。使用c++ 0x特性(lambda函数和iota)
vector<int> v(1000);
//fill the vector
iota(v.begin(),v.end(),0);
v.erase(remove_if(v.begin(),v.end(),[](int a) { return !(a%3 && a%5); }),v.end());
int sum = accumulate(v.begin(),v.end(),0);
等效的c++程序为:
#include <iostream>
using namespace std;
int main() {
int sum = 0;
for (int i=0; i <= 999; i++) {
if (i%3 == 0 || i%5 == 0)
sum += i;
}
cout << sum;
return 0;
}
这是一个很酷的C版本:
#include <stdio.h>
#define LAMBDA(body, ...) ({ int _(__VA_ARGS__) { return (body); }; _; })
int range(int* arr, int start, int end) {
(*arr = start) < end && range(arr + 1, start + 1, end);
}
void select(int* arr, int count, int(*fn)(int)) {
int i;
for(i = 0; i < count; i++)
if(!fn(arr[i]))
arr[i] = 0;
}
int inject(int* arr, int count, int(*fn)(int,int)) {
int acc = arr[0], i;
for(i = 1; i < count; i++)
acc = fn(acc, arr[i]);
return acc;
}
int main()
{
int numbers[1000];
range(numbers, 1, 1000);
select(numbers, 1000, LAMBDA(a % 3 == 0 || a % 5 == 0, a));
printf("%dn", inject(numbers, 1000, LAMBDA(a + b, a, b)));
}
http://codepad.org/eUKFAvkc 相关文章:
- 递归列出所有目录中的C++与Python与Ruby的性能
- 按原样保存用户输入 - Ruby on Rails
- 与其他语言相比的 Ruby 和指针
- 它可能的 C++ 正则表达式评估器与 Lambda 像 Ruby 一样?
- 在C 程序上嵌入Ruby源的错误
- 用 rice/ruby 包裹的纯虚拟 C++ 类在运行时引发 TypeError ( "is not a class (Module)" )
- 如何在 Ruby-C++ 扩展C++类中编写非静态方法
- 如何使用 Ruby 的 Enumerable .map 方法在 C++ 中执行类似于 map 的操作
- 访问用 OCaml 编写的库,并从 Ruby 代码C++
- 通过Swig从Ruby调用C 功能
- Ruby中的多维阵列,例如C
- 在 C++ 和 Ruby 中的进程之间交换信息
- 如果用户在Ruby with Rice中重新定义initialize(),则避免C++代码中的Segfault
- 在 Ruby 和 C++ 之间交换数据
- 有没有一个很好的通用方法来用ruby包装swig生成的类
- 使用Swig将std::set转换为ruby
- 在C中创建Ruby扩展时出错
- Ruby和C++中的左移16位
- make在swig-create-ruby包装器上失败
- C++可以被包装在一个Ruby C扩展中吗