2017-10-05 3 views
0

J'ai un vecteur d'entiers et je veux continuer à comparer chaque paire jusqu'à ce que tous les entiers aient été comparés. Je veux trouver la différence absolue entre les deux. Par exemple:Comparer un ensemble de deux entiers à l'intérieur d'un vecteur à plusieurs reprises tout en itérant

30 
25 
65 
183 
83 
22 

30 et 25 sont comparés, puis 65 et 183 sont comparés, puis 83 et 22, et ainsi de suite. Je veux trouver la différence absolue de chaque comparaison. Les nombres sont tous aléatoires, il faudra donc trouver le plus grand nombre entier dans la paire et le soustraire du plus petit. Comment ferais-je cela?

Répondre

1

Essayez d'utiliser itérateurs sur l'indexation de tableau - pour les grands ensembles que vous aurez voir une différence.

#include <algorithm> 
#include <iostream> 
#include <iterator> 
#include <numeric> 
#include <vector> 

int main() 
{ 
    std::vector <int> xs = { 30, 25, 65, 183, 83, 22, -3 }; 
    std::vector <int> ds; 

    auto print = [&]() 
    { 
    for (int d : ds) 
     std::cout << d << " "; 
    std::cout << "\n"; 
    }; 

    // method one (two-pass using standard algorithms) 
    { 
    std::adjacent_difference(begin(xs), end(xs), std::back_inserter(ds), 
     [](int a, int b) { return std::abs(b - a); } 
    ); 
    bool b = false; 
    ds.erase(std::remove_if(begin(ds), end(ds), [&b](auto foo) { return b = !b; }), end(ds)); 
    } 
    print(); 

    // method two (one-pass for random access iterators, two-pass for sequential iterators) 
    ds.clear(); 
    { 
    auto a = begin(xs); 
    auto b = next(a); 
    auto n = std::distance(begin(xs), end(xs))/2; 
    while (n--) 
    { 
     ds.emplace_back(std::abs(*b - *a)); 
     a = next(b); 
     b = next(a); 
    } 
    } 
    print(); 

    // method three (one-pass for sequential iterators) 
    ds.clear(); 
    { 
    auto a = begin(xs); 
    auto b = next(a); 
    while (a != end(xs) and b != end(xs)) 
    { 
     ds.emplace_back(std::abs(*b - *a)); 
     a = next(b); 
     b = next(a); 
    } 
    } 
    print(); 
} 

La première méthode utilise simplement des algorithmes standard, fonctionne bien et est facile à lire. Il fait toujours deux passes et a une double exigence de mémoire par rapport aux deux autres algorithmes.

La deuxième méthode est la plus efficace étant donné que vous avez des itérateurs à accès aléatoire. Il fait un passage et utilise seulement autant de mémoire que nécessaire. Vous pouvez modifier cette exigence de mémoire avec un simple ds.reserve(n) et une affectation simple, en supposant que ds est également accessible via l'itérateur à accès aléatoire.

La troisième méthode est une variante qui ne tient aucun compte de vos itérateurs d'entrée et utilise toujours un seul passage. (Il peut encore échouer sur les itérateurs de flux à moins que vous ne mémorisiez certaines données ... LOL, merci C++.)

1
std::vector<int> numbers; 
// init... 

std::vector<int> diffs(numbers.size()/2); 

for (int i = 0, j = 0; i < numbers.size() - 1; ++j, i += 2) { 
    diffs[j] = abs(numbers[i] - numbers[i + 1]); 
} 
+0

parfait suffit d'ajouter std :: vector nombres {30,25,65,183,83,22}; std :: vecteur diffs (numbers.size()/2); –

+0

Je reçois "indice de vecteur hors de portée" lors de l'exécution de cette. Voici le code que j'utilise: https://pastebin.com/x628T5hz avec les numéros. Je ne sais pas pourquoi ça me donne cette erreur. – Zezima

+0

peut-être n'est-il pas dans la branche 'if (file.is_open())'? – Grigory