Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Изменение кода


Автор: LeD4eG 20.10.2010, 21:01
добрый вечер!
помогите, плиз, сделать код лучше. задача, которую я решал, состоит в следующем: в одномерном вещественном массиве найти максимальный по модулю элемент, сумму элементов массива между первым и вторым положительным элементом, упорядочить массив таким образом, чтобы элементы равные 0 располагались после всех остальных.
в ходе решения задачи мной был получен следующий код:
Код

#include<iostream>
#include<windows.h>
#include<cmath>
using namespace std;
char* Rus(const char* text);
int main(){
    short i, imax, n;
    cout<<Rus("Введите размерность массива: ");
    cin>>n;
    float* a = new float [n];
    cout<<Rus("Введите элементы массива: ");
    for(i=0;i<n;i++) cin>>*(a+i);
    cout<<Rus("Вами было введено: ");
    for(i=0;i<n;i++) cout<<*(a+i)<<' ';
    cout<<"\n";
    cout<<"------------------------"<<endl;
    //находим максимальный по модулю элемент
    for(i=imax=0;i<n;i++) if(abs(a[i])>abs(a[imax])) imax=i;
    cout<<Rus("Максимальный элемент находится на ")<<imax;
    cout<<Rus(" месте.")<<endl;
    cout<<Rus("Он равен ")<<a[imax];
    cout<<"\n";
    cout<<"------------------------"<<endl;
    //находим сумму элементов расположенных между первым и вторым положительным элементом
    bool pol1=false, pol2=false, flag_pol=true;
    short i_p1,i_p2;
    float sum=0;
    for(i=0;i<n;i++){
        if(a[i]>0){
            i_p1=i;
            pol1=true;
            break;
        }
    }
    for(i=i_p1+1;i<n;i++){
        if(a[i]>0){
            i_p2=i;
            pol2=true;
            break;
        }
    }
    if(pol1&&pol2){
        for(i=i_p1+1;i<i_p2;i++) sum+=a[i];
        cout<<Rus("Сумма равна ")<<sum<<endl;
        cout<<Rus("Первый положительный элемент находится на ")<<i_p1;
        cout<<Rus(" месте.")<<endl;
        cout<<Rus("Второй положительный элемент находится на ")<<i_p2;
        cout<<Rus(" месте.")<<endl;
        flag_pol=false;
    }
    if(flag_pol){
        if(pol1) cout<<Rus("В массиве только один положительный элемент.")<<endl;
        else cout<<Rus("В массиве нет положительных элементов.")<<endl;
    }
    cout<<"-----------------------"<<endl;
    //упорядочиваем массив
    short i_z;
    for(i=0;i<n;i++){
        i_z=i;
        for(int j=i+1;j<n-1;j++) if(a[j]!=0) i_z=j;
        float temp;
        temp=a[i];
        a[i]=a[i_z];
        a[i_z]=temp;
    }
    cout<<Rus("В результате упорядочивания был получен массив: ");
    for(i=0;i<n;i++) cout<<a[i]<<' ';
    cout<<"\n";
    return 0;
}
char bufRus[256];
char* Rus(const char* text){
    CharToOem(text, bufRus);
    return bufRus;
}

помогите сократить код, особенно часть поиска первого и второго положительного элемента в массиве.
спасибо!

Автор: azesmcar 20.10.2010, 22:12
держи
Код

#include <iostream>
#include <cmath>
#include <functional>
#include <algorithm>
#include <numeric>
#include <iterator>

bool abs_compare(int m, int i)
{
    return abs(m) < abs(i);
}

bool sort_pred(int l, int r)
{
    return (l != 0) && (r == 0 || l < r);
}

int main()
{
    int arr[] = {-7, 5, 0, -3, -1, 9, 0, 13, -9, 0, -31, 8, 0, -4, 25};

    int *begin = arr;
    int *end = arr + sizeof(arr) / sizeof(int);

    int *fp = std::find_if(begin, end, std::bind2nd(std::greater<int>(), 0));
    int *sp = std::find_if(++fp, end, std::bind2nd(std::greater<int>(), 0));

    std::cout << "max absolute element: " << *std::max_element(begin, end, abs_compare) << std::endl;
    std::cout << "sum between first two positive elements: " << std::accumulate(fp, sp, 0) << std::endl;

    std::sort(begin, end, sort_pred);

    std::cout << "sorted array output" << std::endl;
    std::copy(begin, end, std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;
}

если есть boost можно убрать функцию abs_compare и генерировать ее с помощью boost::bind
Код

int abs_max = *std::max_element(begin, end, boost::bind(std::less<int>(),
    boost::bind<int>(abs, _1),
    boost::bind<int>(abs, _2)
));

Автор: LeD4eG 21.10.2010, 18:40
ясно....спасибо smile 

Автор: borisbn 21.10.2010, 23:51
sorry за  smile 
Цитата(azesmcar @  20.10.2010,  22:12 Найти цитируемый пост)
если есть boost можно убрать функцию abs_compare и генерировать ее с помощью boost::bind

azesmcar, IMHO boost - великая ( не побоюсь этого слова ) библиотека, но в данном случае
Код

bool abs_compare(int m, int i) {
    return abs(m) < abs(i);
}
*std::max_element(begin, end, abs_compare)

попроще выглядет, чем
Код

int abs_max = *std::max_element(begin, end, boost::bind(std::less<int>(),
    boost::bind<int>(abs, _1),
    boost::bind<int>(abs, _2)
));

тем более, что в стандарте 0x00 это будет ещё проще
smile

Автор: azesmcar 22.10.2010, 05:30
borisbn

Наверное вопрос привычки. Я читаю без затруднений и то и другое.

Цитата(borisbn @  21.10.2010,  23:51 Найти цитируемый пост)
тем более, что в стандарте 0x00 это будет ещё проще

Ну так он же еще не вышел.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)