给定两个数组,交换它们的元素,使得两数组元素之和的差绝对值最小

来源:互联网 发布:mac book pro 15寸 编辑:程序博客网 时间:2024/05/01 10:12


/* * ===================================================================================== * *       Filename:  arrydiff.cpp * *    Description:  test * *        Version:  1.0 *        Created:  2012年09月11日 22时34分30秒 *       Revision:  none *       Compiler:  gcc * *         Author:  (http://blog.csdn.net/njzhiyuan) *   Organization:   * * ===================================================================================== */#include <iostream>extern "C" {#include <stdlib.h>#include <math.h>#include <time.h>}#include <string>using namespace std;/***sum_a 第一个数组的和*a 第一个数组中一个元素*sum_b 第二个数组的和*b 第二个数组中一个元素×函数返回假如交换a、b元素后,两数组元素之和的差,原始试子应为(sum_a - a + b) - (sum_b - b + a)*/template<typename T>inline T get_swap_diff(const T &sum_a, const T &a,const T &sum_b, const T &b){    return abs(sum_a - sum_b - 2 * a + 2 * b);}//此处在std里已有,这里属重复定义,故注释/*template<typename T>void swap(T &a, T &b){    T temp = a;    a = b;    b = temp;}*///求数组元素之和template<typename T, size_t element_nums>T array_sum(const T(&array)[element_nums]){    T sum = 0;    for(size_t i = 0; i < element_nums; ++i)        sum += *(array + i);            return sum;}/***实现两个数组间元素的交换,使两数组元素之和的差最小,思想如下:*如果两数组元素之和的差已经最小,那么任意交换两数组的元素,都不能使差再减小,故这可以作为最外层循环的退出条件。*依次选取第一个数组的元素a,再从第二个数组中选出一元素b,使得a、b交换能使得两数组元素之和的差减小得最多。*交换a、b,重新计算两数组的两数组元素之和及它们的差。重复上述步骤,如果不能再使差减小了,就退出外层循环。*/template<typename T, size_t element_nums>void min_diff(T(&arr_a)[element_nums], T(&arr_b)[element_nums]){    bool flag;        do{        flag = false;                T sum_a = array_sum(arr_a);        T sum_b = array_sum(arr_b);                if(sum_a == sum_b) break;        T diff = abs(sum_a - sum_b);                for(size_t index_a = 0; index_a < element_nums; ++index_a){            size_t temp_index;            bool chang_flag = false;                        for(size_t index_b = 0; index_b < element_nums; ++index_b){                if(diff > get_swap_diff(sum_a, *(arr_a + index_a), sum_b, *(arr_b + index_b))){                    diff = get_swap_diff(sum_a, *(arr_a + index_a), sum_b, *(arr_b + index_b));                    temp_index = index_b;                                        chang_flag = true;                }            }                        if(chang_flag){                swap(*(arr_a + index_a),*(arr_b + temp_index));                                //已调用swap交换了元素,两数组的两数组元素之和时须注意。                sum_a = sum_a + *(arr_a + index_a) - *(arr_b + temp_index);                sum_b = sum_b + *(arr_b + temp_index) - *(arr_a + index_a);                                flag = true;            }        }    }while(flag);}//显示数组元素template<typename T, size_t element_nums>void array_display(const T (&array)[element_nums]){    for(size_t i=0; i < element_nums; ++i)    cout << *(array + i) << '\t';        cout << endl;}//给数组元素赋随机值template<typename T, size_t element_nums>void create_value(T (&array)[element_nums],int seed = 100){    size_t i = 0;    srand((unsigned) time(NULL) + seed);        while(i < element_nums){        *(array + i++) = static_cast<T>(rand() % 1000);    }}// 下面的几个函数参数中,数组名作为是指针传递参数,实现的功能与以上同名函数相同template<typename T>T array_sum(const T *array, size_t element_nums){    T sum = 0;    for(size_t i = 0; i < element_nums; ++i)        sum += *(array + i);            return sum;}template<typename T>void min_diff(T *arr_a,T *arr_b,size_t element_nums){    bool flag;        do{        flag = false;                T sum_a = array_sum(arr_a,element_nums);        T sum_b = array_sum(arr_b,element_nums);        if(sum_a == sum_b) break;        T diff = abs(sum_a - sum_b);                for(size_t index_a = 0; index_a < element_nums; ++index_a){            size_t temp_index;            bool chang_flag = false;                        for(size_t index_b = 0; index_b < element_nums; ++index_b){                if(diff > get_swap_diff(sum_a, *(arr_a + index_a), sum_b, *(arr_b + index_b))){                    diff = get_swap_diff(sum_a, *(arr_a + index_a), sum_b, *(arr_b + index_b));                    temp_index = index_b;                                        chang_flag = true;                }            }                        if(chang_flag){                swap(*(arr_a + index_a),*(arr_b + temp_index));                                sum_a = sum_a + *(arr_a + index_a) - *(arr_b + temp_index);                sum_b = sum_b + *(arr_b + temp_index) - *(arr_a + index_a);                                flag = true;            }        }    }while(flag);}template<typename T>void array_display(const T *array,size_t element_nums){    for(size_t i=0; i < element_nums; ++i)    cout << *(array + i) << '\t';        cout << endl;}template<typename T >void create_value(T *array,size_t element_nums,int seed = 100){    size_t i = 0;        srand((unsigned) time(NULL) + seed);    while(i < element_nums){        *(array + i++) = static_cast<T>(rand() % 1000);    }}//指针形式参数系列函数的测试void pt_test(){     while(true){        size_t array_size;                string size_temp; //避免直接cin>>array_size,因为输入非数值字符时,会导致意想不到的错误        cout << "Please input the size of array: ";        cin>>size_temp;                if((array_size = atol(size_temp.c_str())) < 1)            array_size = 10;                long *array_a;        long *array_b;                if((array_a = new long[array_size]) == NULL){            cout << "Apply space for the first array failed!"<<endl;            break;        }                if((array_b = new long[array_size]) == NULL){            cout << "Apply space for the second array failed!"<<endl;            delete[] array_a;            break;        }                create_value(array_a,array_size);        create_value(array_b,array_size,rand());                cout << "before the change:\n";            array_display(array_a,array_size);        array_display(array_b,array_size);        cout << "array_a sum " << array_sum(array_a,array_size) << endl;        cout << "array_b sum " << array_sum(array_b,array_size) << endl;                min_diff(array_a,array_b,array_size);                cout << "after the change:\n";            array_display(array_a,array_size);        array_display(array_b,array_size);        cout << "array_a sum " << array_sum(array_a,array_size) << endl;        cout << "array_b sum " << array_sum(array_b,array_size) << endl;                delete[] array_a;        delete[] array_b;                cout << "Do you want to continue with this program? Y/N : ";        char response;        cin>>response;        if(response != 'Y' && response != 'y')            break;    }}//引用形式参数系列函数的测试void ref_test(){    const size_t size =10;    int array_a[size];    int array_b[size];        create_value(array_a);    create_value(array_b,rand());        cout << "before the change:\n";        array_display(array_a);    array_display(array_b);    cout << "array_a sum " << array_sum(array_a) << endl;    cout << "array_b sum " << array_sum(array_b) << endl;        min_diff(array_a,array_b);        cout << "after the change:\n";        array_display(array_a);    array_display(array_b);    cout << "array_a sum " << array_sum(array_a) << endl;    cout << "array_b sum " << array_sum(array_b) << endl;}int main(int argc, char *argv[]){    ref_test();    pt_test();        return 0;}



 

 

原创粉丝点击