函数式编程在 C++1z 中每三分之一递增整数序列?
Functional programming incrementing integer sequence on every third one in C++1z?
我可以编写一个 C++ 程序来使用 for 循环生成此输出:
(200, 150)
(199, 150)
(198, 150)
(197, 149)
(196, 149)
(195, 149)
(194, 148)
(193, 148)
(192, 148)
(191, 147)
使用函数式编程技术(特别是 C++ Streams C++14 库)我可以做到这一点。
#include <iostream>
#include "../Streams-master/source/Stream.h"
using namespace stream;
using namespace stream::op;
int main(){
MakeStream::counter(200,-1)
| zip_with(MakeStream::counter(150,-1))
| limit(10)
| for_each([](std::tuple<int, int>&& tup) {
std::cout << tup << std::endl;
});
}
生产:
(200, 150)
(199, 149)
(198, 148)
(197, 147)
(196, 146)
(195, 145)
(194, 144)
(193, 143)
(192, 142)
(191, 141)
在 C++1z 中,每三列递增第二列的函数式编程技术是什么?
我不懂 C++,但也许在 Haskell 中草拟一个解决方案会有帮助?您可以在 Haskell:
中以这种方式编写递减整数列表
list1, list2 :: [Integer]
list1 = [200, 199..]
list2 = [150, 149..]
这些列表中的第一个评估为您正在构建的对的第一个元素。例如使用take
函数提取前15个元素:
>> take 15 list1
[200,199,198,197,196,195,194,193,192,191,190,189,188,187,186]
但是,第二个没有您想要的"skip":
>> take 15 list2
[150,149,148,147,146,145,144,143,142,141,140,139,138,137,136]
但是,我们可以在该列表的基础上更进一步:
list3 :: [Integer]
list3 = concatMap triplicate list2
where triplicate n = [n, n, n]
或者使用标准库中的replicate
函数:
list4 :: [Integer]
list4 = concatMap (\n -> replicate 3 n) list2
concatMap
/replicate
这一步似乎是您所缺少的。示例输出:
>>> take 15 list4
[150,150,150,149,149,149,148,148,148,147,147,147,146,146,146]
现在,将它们与 zip
函数放在一起:
solution :: [Integer]
solution = zip [200, 199..] (concatMap (\n -> replicate 3 n) [150, 149..])
使用示例:
>>> mapM_ print (take 10 solution)
(200,150)
(199,150)
(198,150)
(197,149)
(196,149)
(195,149)
(194,148)
(193,148)
(192,148)
(191,147)
请注意,C++ Streams API 具有此 Haskell 代码中的大部分(如果不是全部的话)操作(模数细节差异),因此解决方案应该翻译得很好:
- Haskell
concatMap
= C++ flat_map
- Haskell
replicate
= C++ repeat
根据 Luis Casillas Haskel 的回答和注释,添加 | flat_map([](int x){return MakeStream::repeat(x,3);}))
:
#include <iostream>
#include "../Streams-master/source/Stream.h"
using namespace stream;
using namespace stream::op;
int main(){
MakeStream::counter(200,-1)
| zip_with(MakeStream::counter(150,-1)
| flat_map([](int x){return MakeStream::repeat(x,3);}))
| limit(10)
| for_each([](auto tup) {std::cout << tup << std::endl;});
}
我可以编写一个 C++ 程序来使用 for 循环生成此输出:
(200, 150)
(199, 150)
(198, 150)
(197, 149)
(196, 149)
(195, 149)
(194, 148)
(193, 148)
(192, 148)
(191, 147)
使用函数式编程技术(特别是 C++ Streams C++14 库)我可以做到这一点。
#include <iostream>
#include "../Streams-master/source/Stream.h"
using namespace stream;
using namespace stream::op;
int main(){
MakeStream::counter(200,-1)
| zip_with(MakeStream::counter(150,-1))
| limit(10)
| for_each([](std::tuple<int, int>&& tup) {
std::cout << tup << std::endl;
});
}
生产:
(200, 150)
(199, 149)
(198, 148)
(197, 147)
(196, 146)
(195, 145)
(194, 144)
(193, 143)
(192, 142)
(191, 141)
在 C++1z 中,每三列递增第二列的函数式编程技术是什么?
我不懂 C++,但也许在 Haskell 中草拟一个解决方案会有帮助?您可以在 Haskell:
中以这种方式编写递减整数列表list1, list2 :: [Integer]
list1 = [200, 199..]
list2 = [150, 149..]
这些列表中的第一个评估为您正在构建的对的第一个元素。例如使用take
函数提取前15个元素:
>> take 15 list1
[200,199,198,197,196,195,194,193,192,191,190,189,188,187,186]
但是,第二个没有您想要的"skip":
>> take 15 list2
[150,149,148,147,146,145,144,143,142,141,140,139,138,137,136]
但是,我们可以在该列表的基础上更进一步:
list3 :: [Integer]
list3 = concatMap triplicate list2
where triplicate n = [n, n, n]
或者使用标准库中的replicate
函数:
list4 :: [Integer]
list4 = concatMap (\n -> replicate 3 n) list2
concatMap
/replicate
这一步似乎是您所缺少的。示例输出:
>>> take 15 list4
[150,150,150,149,149,149,148,148,148,147,147,147,146,146,146]
现在,将它们与 zip
函数放在一起:
solution :: [Integer]
solution = zip [200, 199..] (concatMap (\n -> replicate 3 n) [150, 149..])
使用示例:
>>> mapM_ print (take 10 solution)
(200,150)
(199,150)
(198,150)
(197,149)
(196,149)
(195,149)
(194,148)
(193,148)
(192,148)
(191,147)
请注意,C++ Streams API 具有此 Haskell 代码中的大部分(如果不是全部的话)操作(模数细节差异),因此解决方案应该翻译得很好:
- Haskell
concatMap
= C++flat_map
- Haskell
replicate
= C++repeat
根据 Luis Casillas Haskel 的回答和注释,添加 | flat_map([](int x){return MakeStream::repeat(x,3);}))
:
#include <iostream>
#include "../Streams-master/source/Stream.h"
using namespace stream;
using namespace stream::op;
int main(){
MakeStream::counter(200,-1)
| zip_with(MakeStream::counter(150,-1)
| flat_map([](int x){return MakeStream::repeat(x,3);}))
| limit(10)
| for_each([](auto tup) {std::cout << tup << std::endl;});
}