首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在计算函数中不重复代码?

如何在计算函数中不重复代码?
EN

Stack Overflow用户
提问于 2022-09-07 15:29:40
回答 3查看 67关注 0票数 1

我做了一个简单的程序,对给定数组的所有元素执行基本算术操作。但是问题是,代码是非常重复的,编写重复的代码并不是一个好的实践,我无法想出解决这个问题的方法。我们如何尽量减少这个程序中的代码重复?

代码语言:javascript
复制
int add(int numcount, int numarr[]){
    int total = numarr[0];

    // add all the numbers in a array
    for (int i = 1; i < numcount; i++){
        total += numarr[i];
    }

    return total;
}

int sub(int numcount, int numarr[]) {
    int total = numarr[0];

    // subtract all the numbers in array
    for (int i = 1; i < numcount; i++){
        total -= numarr[i];
    }

    return total;
}

int mul(int numcount, int numarr[]) {
    int total = numarr[0];

    // multiply all the numbers in array
    for (int i = 1; i < numcount; i++){
        total *= numarr[i];
    }

    return total;
}

int main(int argc, char* argv[]){
    const int n = 5;
    int arr[n] = {1, 2, 3, 4, 5};
    
    cout << "Addition: " << add(n, arr) << endl;
    cout << "Subtraction: " << sub(n, arr) << endl;
    cout << "Multiplication: " << mul(n, arr) << endl;
}
EN

回答 3

Stack Overflow用户

发布于 2022-09-07 15:53:10

我们如何尽量减少这个程序中的代码重复?

一般说来,通过识别重复的结构,看看我们是否可以把它抽象出来,或者为它找到一个现有的名称。

  1. 重复结构只是将运行结果设置为容器的第一个元素,并使用二进制函数依次将其与每个后续元素组合。
  2. 查看一下标准算法库,看看是否有任何现有的函数看起来类似
  3. std::accumulate可以做我们需要的事情,不需要为add添加任何额外的参数,只需要为其他的运算符函数对象提供适当的运算符函数对象

所以,你可以随便写

代码语言:javascript
复制
int add(int numcount, int numarr[]){
    return std::accumulate(numarr, numarr+numcount, 0);
}

// OK, your sub isn't actually trivial
int sub(int numcount, int numarr[]){
    return std::accumulate(numarr+1, numarr+numcount, numarr[0],
                           std::minus<int>{});
}

// could also be this - honestly it's a little hairy
// and making it behave well with an empty array
// requires an extra check. Yuck.
int sub2(int numcount, int numarr[]){
    return numarr[0] - add(numcount-1, numarr+1);
}

等。

如果允许使用std::array (在所有容器上抽象迭代器对),则切换到使用C++20或使用范围会稍微好一些。

如果必须使用C数组(而且它们在通过另一个函数的过程中不会衰减到指针),则可以编写

代码语言:javascript
复制
template <std::size_t N>
int add(int (&numarr)[N]){
    return std::accumulate(numarr, numarr+N, 0);
}

为了节省一些样板(到处传递numcount只是一个错误的机会)。

注意:正如链接的文档中所提到的,std::accumulate是我们从原始代码中抽象出来的事物“(特殊的”高阶函数“)的实现,您可以使用相同的std::plusstd::minus等操作符函数编写自己的foldl模板函数。

票数 2
EN

Stack Overflow用户

发布于 2022-09-07 15:52:57

您可以使用std::accumulate

代码语言:javascript
复制
 auto adder = [](auto accu,auto elem) { return accu + elem; };
 auto multiplier = [](auto accu, auto elem) { return accu * elem; };


 auto sum = std::accumulate(std::begin(arr),std::end(arr),0,adder);
 auto prod = std::accumulate(std::begin(arr),std::end(arr),0,multiplier);

sub的结果就是2*arr[0] - sum

请注意std::accumulate的初始值。它决定了返回类型,并乘以很多int很容易溢出,可能使用0LL而不是0

std::accumulate或任何其他标准算法都适合的情况下,您发现自己编写的函数非常类似,只有通过一个特定的操作才不同,您可以重构将函子传递给一个函数,该函数允许调用方专门指定要应用的操作:

代码语言:javascript
复制
template <typename F>
void foo(F f) {
    std::cout << f(42);
}
int identity(int x) { return x;}

int main() {
    foo([](int x) { return x;});
    foo(identity);    
}

在这里,foo将调用参数42调用的结果打印到控制台。main用lambda表达式调用它一次,用空闲函数调用一次。

票数 1
EN

Stack Overflow用户

发布于 2022-09-07 16:07:55

我们如何尽量减少这个程序中的代码重复?

这样做的一种方法是有一个char类型的参数,表示需要执行的操作,如下所示:

代码语言:javascript
复制
//second parameter denotes the operator which can be +, - or *
int calc(int numcount, char oper, int numarr[])
{
    //do check here that we don't go out of bounds 
    assert(numcount > 0);
    
    int total = numarr[0]; 

    // do the operatations for all the numbers in the array
    for (int i = 1; i < numcount; i++){
        total = (oper == '-') * (total - numarr[i]) + 
                (oper == '+') * (total + numarr[i]) + 
                (oper == '*') * (total * numarr[i]); 
                 
    }
    return total;
           
}
int main()
{
    int arr[] = {1,2,3,4,5,6};
    std::cout << calc(6, '+', arr) << std::endl; //prints 21 
    std::cout << calc(6, '-', arr) << std::endl; //prints -19
    std::cout << calc(6, '*', arr) << std::endl; //prints 720
  
}

工作演示

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73638098

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档