返回信息流问题陈述:给数组,打印出所有偶数的平方
程序一(值返回):
// 每一步,结果用返回值传出函数。然后传入下一步。
void printAllEvenSquares(vector<int>& numbers) {
vector<int> evens = findEvens(numbers);
vector<int> squares = findSquares(evens);
for(int i=0;i<squares.size();i++) {
cout<<squares[i]<<endl;
}
}
vector<int> findEvens(vector<int>& numbers) {
vector<int> results;
for(int i=0;i<numbers.size();i++) {
if(numbers[i]%2==0) {
results.push_back(numbers[i]);
}
}
return results;
}
vector<int> findSquares(vector<int>& numbers) {
vector<int> results;
for(int i=0;i<numbers.size();i++) {
results.push_back(numbers[i]*numbers[i]);
}
return results;
}
程序2:(值传入)
// 不返回。每一步把符合条件的数直接作为参数传入下一个函数
void printAllEvenSquares(vector<int>& numbers) {
for(int i=0;i<numbers.size();i++) {
if(numbers[i]%2==0) {
findSquare(numbers[i]);
}
}
}
void findSquare(int num) {
printNumber(num*num);
}
void printNumber(int num) {
cout<<num<<endl;
}
程序3(函数传入):
// 每一步不返回,把符合条件的数字传入下一个函数。但是这个“下一个函数”是由参数确定的,而不是硬编码的。
// 这样每个函数都不会与“下一步做什么”耦合了。
// 也许不明显。但是这个程序结果正确。
#include<vector>
#include<iostream>
using namespace std;
typedef void (*ChainingFunction)(int,void*);
void findEvens(vector<int>&,void*);
void findSquare(int,void*);
void printNumber(int,void*);
void printAllEvenSquares(vector<int>& numbers) {
findEvens(numbers,(void*)findSquare);
}
void findEvens(vector<int>& numbers, void *nextFunctionToCall) {
for(int i=0;i<numbers.size();i++) {
if(numbers[i]%2==0) {
((ChainingFunction)nextFunctionToCall)(numbers[i],(void*)printNumber);
}
}
}
void findSquare(int num, void *nextFunctionToCall) {
((ChainingFunction)nextFunctionToCall)(num*num,NULL);
}
void printNumber(int num, void *nextFunctionToCall_aDummyParamThatMustBeNull) {
cout<<num<<endl;
}
测试用例:
int main() {
int a[] = {1,2,3,4,5,6,7};
vector<int> b(a,a+7);
printAllEvenSquares(b);
return 0;
}
这是一条镜像帖。来源:北邮人论坛 / cpp / #18675同步于 2009/1/14
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
[代码美化向]返回值美,传入值美,传入函数美,熟美?
wks
2009/1/14镜像同步7 回复
订阅后,新回复会通过你的通知中心匿名送达。
7 条回复
面向对象的方法:
#include<iostream>
#include<vector>
using namespace std;
class NoMoreNumberException {
} theOnlyNoMoreNumberExceptionInstance;
class Reader {
public:
virtual int read()=0;
};
class VectorReader : public Reader {
vector<int>* pv;
vector<int>::iterator it;
public:
VectorReader (vector<int>*vp) :pv(vp),it(vp->begin()) {}
virtual int read() {
if(it==pv->end()) throw theOnlyNoMoreNumberExceptionInstance;
else return *(it++);
}
};
class EvenFinder : public Reader {
Reader *pr;
public:
EvenFinder(Reader* rp) : pr(rp) {}
virtual int read() {
int n;
do {
n=pr->read();
} while (n%2!=0);
return n;
}
};
class SquareFinder : public Reader {
Reader *pr;
public:
SquareFinder(Reader* rp) : pr(rp) {}
virtual int read() {
int n=pr->read();
return n*n;
}
};
class NumberPrinter {
Reader *rp;
public:
NumberPrinter(Reader *pr) : rp(pr) {}
void printAll() {
int n;
try {
while(true) {
n=rp->read();
cout<<n<<endl;
}
} catch (NoMoreNumberException err) {
}
}
};
int main() {
int a[] = {1,2,3,4,5,6,7};
vector<int> b(a,a+7);
VectorReader vr(&b);
EvenFinder ef(&vr);
SquareFinder sf(&ef);
NumberPrinter np(&sf);
np.printAll();
return 0;
}
就这种需求的代码,直接写在一个函数里就行了。适当注释。没必要想这么多,因为重用的可能几乎没有吧。。。
面向对象那个版本......................滥用语法啊。
所以标准应该是KISS
应用才没那么简单呢。举个简单的粒子好说话嘛。
需求是一个编译器。这分别是词法分析器和语法分析器。都不简单吧。语法分析器还需要储存状态,还要一个自动机,这可不是简单嵌套两个循环能做到的吧。
第一个方法相当于“Two-pass”法,第二个是逐个符号输入上层。第三个方法倒是我滥用cps的结果。
面向对象的方法,对于储存状态相对容易一点。
比较喜欢 N pass 的方法,比较清楚直接。
不太习惯在main里面加入对于具体过程的控制。
每个函数中都有希望操作的集合,以及希望进行的操作,这样比较容易理解。
针对这个特定的例子来说,能用STL完成的,还是比较喜欢STL的做法。
std::for_each(aVec.begin(), aVec.end(), Printer());
class Printer
{
public:
void operator(int n)
{
if (n%2==0) cout<<n*n<<" ";
}
};