2016-11-06 1 views
2

Débutant en C++ ici et tableaux d'apprentissage. Le programme ci-dessous est censé séparer les nombres positifs et négatifs dans un tableau. Cependant, il renvoie des nombres aléatoires dans les fonctions splitPos et splitNeg.C++ Séparer les valeurs positives et négatives d'un tableau

Quelqu'un pourrait-il si gentiment conseiller et me montrer ce qui est incorrect dans les fonctions et que peut-on faire pour omettre ces chiffres aléatoires afin que seuls les chiffres positifs et négatifs soient retournés par le programme pour chaque fonction/boucle? Je ne vois évidemment pas et/ou ne comprends pas ce qui est incorrect.

Merci beaucoup pour votre aide et votre temps à l'avance !!!

#include <iostream> 

using namespace std; 

//function prototypes 
int splitNeg(int[], int[], int); 
int splitPos(int[], int[], int); 
void displayArr(int[], int); 

int main() 
{ 
    const int SIZE = 20; 
    int usedPos, usedNeg; 
    int origArr[SIZE] = { 4, -7, 12, 6, 8, -3, 30, 7, -20, -13, 17, 6, 31, -4, 3, 19, 15, -9, 12, -18 }; 
    int posArray[SIZE]; 
    int negArray[SIZE]; 


    usedPos = splitPos(origArr, posArray, SIZE); 
    usedNeg = splitNeg(origArr, negArray, SIZE); 


    cout << "Positive Values: " << endl; 
    displayArr(posArray, usedPos); 
    cout << endl; 
    cout << "Negative Values: " << endl; 
    displayArr(negArray, usedNeg); 

    return 0; 
} 

int splitPos(int origArr[], int posArray[], int SIZE) 
{ 
    int j = 0; 

     for (int i = 0; i < SIZE; i++ && j++) 
     { 

      if (origArr[i] >= 0) 
       posArray[j] = origArr[i]; 

     } 


      return j; 

} 

int splitNeg(int origArr[], int negArray[], int SIZE) 
{ 
    int k = 0; 

    for (int i = 0; i < SIZE; i++ && k++) 
    { 
     if (origArr[i] < 0) 
      negArray[k] = origArr[i]; 

    } 

    return k; 
} 

void displayArr(int newArray[], int used) 
{ 
    for (int i = 0; i < used; i++) 
     cout << newArray[i] << endl; 
    return; 

} 
+0

'i ++ && j ++' est mauvais parce que '' && les courts-circuits. Dans ce cas, vous devriez utiliser un opérateur virgule à la place: 'i ++, j ++' – Pubby

+0

Question bien posée. – user4581301

+0

[Regardez, pas de boucles!] (Http://ideone.com/lKycNF) – PaulMcKenzie

Répondre

2

Si vous changez pour boucles un peu:

int splitPos(int origArr[], int posArray[], int SIZE) 
{ 
    int j = 0; 

     for (int i = 0; i < SIZE; i++) 
     { 

      if (origArr[i] >= 0) 
       posArray[j++] = origArr[i]; 

     } 


      return j; 

} 

int splitNeg(int origArr[], int negArray[], int SIZE) 
{ 
    int k = 0; 

    for (int i = 0; i < SIZE; i++) 
    { 
     if (origArr[i] < 0) 
      negArray[k++] = origArr[i]; 

    } 

    return k; 
} 

vous obtiendrez le résultat que vous désirez.

Le compteur des variables de vos tableaux cibles s'augmenté que si vous trouvez une valeur qui correspond au critère d'être moins (ou plus) à 0.

Honnêtement, je ne comprends pas ce que vous avez essayé d'obtenir un. .. hmmm .. "combiné" augmenter comme i++ && j++, cela va dans l'évaluation de court-circuit.

2

j et k doit être incrémentée ne lorsque la valeur correcte est copiée dans posArray et negArray, par définition.

Si la valeur est le mauvais signe, j et k, de toute évidence, devrait rester inchangé, puisque le nombre de valeurs avec le bon signe, dans le tableau de sortie correspondant, ne change pas sur cette itération.

Ce n'est pas ce que fait le code. Il les incrémente à chaque itération de la boucle, à l'exception de celui où i est 0.

-1

Les réponses données dans cet article ont correctement identifié votre problème, vous pouvez donc les consulter pour en savoir plus sur les erreurs Tu l'as fait. Cependant, le but de cette réponse est de vous donner une approche moderne pour écrire le même code en utilisant le std :: vector et la boucle for based (puisque vous êtes au début de votre processus d'apprentissage, essayez autant que possible pour éviter des tableaux de style C et en savoir plus sur les conteneurs STL)

#include <iostream> 
#include <vector> 

using namespace std; 

void splitArr(const vector<int>& origArr, vector<int>& posArr, vector<int>& negArr); 
void displayArr(const vector<int>& Arr); 

int main() 
{ 
vector<int> origArr = { 4, -7, 12, 6, 8, -3, 30, 7, -20, -13, 
         17, 6, 31, -4, 3, 19, 15, -9, 12, -18}; 
vector<int> posArr, negArr; 

splitArr(origArr,posArr,negArr); 

cout << "Positive Values: \n" ; 
displayArr(posArr); 

cout << "\nNegative Values: \n"; 
displayArr(negArr); 

return 0; 
} 

/*________________________________________________________________________________ 
| splitArr function 
| 
| This function adds the postive elements of the origArr vector into the posArr vector, 
| and the negative ones into the negArr vector 
|________________________________________________________________________________ 
*/ 
void splitArr(const vector<int>& origArr, vector<int>& posArr, vector<int>& negArr) 
{ 
           // Using range-based for loop 
for (auto& number : origArr) 
    { 
    if (number >=0) 
           // if the number is positive, then add it to 
           // the posArr vector 
     posArr.emplace_back(number); 
    else 
           // otherwise (the number is negative), then 
           // add it to the negArr vector 
     negArr.emplace_back(number); 
    } 
} 

/*________________________________________________________________________________ 
| displayArr function 
| 
| This function prints to the standard output (cout), all the elements of the 
| vector given as argument using the range-based for loop 
|________________________________________________________________________________ 
*/ 
void displayArr(const vector<int>& Arr) 
{ 
for (auto& number: Arr) 
    { 
    cout << number << "\n"; 
    } 
} 

Laissez-moi savoir si vous avez besoin plus de précisions :)

+3

Je pense que ça peut aller encore plus loin. L'algorithme permettant de regrouper les éléments d'un tableau avec un prédicat est [std :: partition] (http://en.cppreference.com/w/cpp/algorithm/partition). Avec C++ 11, [std :: begin()] (http://en.cppreference.com/w/cpp/iterator/begin) et [std :: end()] (http://en.cppreference.com/w/cpp/iterator/end) peut être utilisé avec le tableau de style c et un [lambda] (http://en.cppreference.com/w/cpp/language/lambda) ('' '[] (int el) {return el <= 0;} '' ') pour séparer les valeurs négatives et positives dans le tableau. – ghlecl

+0

ce code n'a rien de "moderne". Moderne ne signifie pas utiliser un vecteur ou une gamme basée sur des boucles. Le code moderne signifie éviter les boucles d'utilisation, éviter autant que possible si, passer, utiliser le stl et en particulier les algorithmes –

+0

Paramètres de sortie ... ugh. Vous devriez retourner une paire de vecteurs dans votre fonction 'splitArr' –

1

Toutes les réponses à ce poste sont bons, mais je suis déçu que aucun d'entre eux ne parle d'algorithmes STL!

Un bon programmeur C++ doit connaître le langage mais il doit aussi connaître la bibliothèque C++.

regarder le code suivant:

#include <iostream> 
#include <array> 
#include <algorithm> 
#include <string> 

using namespace std; 

template<typename T> 
void print(const string& desc, T first, T last) 
{ 
    cout << desc; 
    for_each(first, last, 
     [](const auto& i) { cout << i << ' ';}); 
    cout << endl; 
} 

int main() 
{ 
    array<int, 20> originalArray = { 4, -7, 12, 6, 8, -3, 30, 7, -20, -13, 17, 6, 31, -4, 3, 19, 15, -9, 12, -18 }; 

    print("original array is ", begin(originalArray), end(originalArray)); 

    auto it = partition(begin(originalArray), end(originalArray), 
    [](int n) { return n >= 0; }); 

    print("now original array is ", begin(originalArray), end(originalArray)); 
    print("positives are: ", begin(originalArray), it);  
    print("negatives are: ", it, end(originalArray)); 

    return 0; 
} 

Plus généralement vous voulez partitionner votre jeu avec un prédicat.

Regardez à mon code trouvez-vous if ou for?C'est impossible de faire des erreurs de cette façon!

La seule chose qui compte dans le code entier est auto it = partition(begin(originalArray), end(originalArray), [](int n) { return n >= 0; }); qui peut être lu comme: partition from start to finish of originalArray elements that are positive.

1

Il existe un algorithme standard conçu pour cela. Il est nommé std::partition.

Votre code avec cet algorithme ressemblera à ceci:

struct SplitPosAndNegResult { 
    std::vector<int> negatives; 
    std::vector<int> positives; 
}; 

auto splitPosAndNeg(std::array<int, SIZE> orig) { 
    // Here `it` is the first element of the second partition (positives) 
    auto it = std::partition(orig.begin(), orig.end(), [](int i){ return i < 0; }); 

    return SplitPosAndNegResult{ 
     std::vector<int>(orig.begin(), it), // negative numbers 
     std::vector<int>(it, orig.end()) // positive numbers 
    }; 
} 

Ensuite, utilisez comme ça:

int main() { 
    auto result = splitPosAndNeg({ 4, -7, 12, 6, 8, -3, 30, 7, -20, -13, 
            17, 6, 31, -4, 3, 19, 15, -9, 12, -18}); 

    for (int n : result.positives) { 
     std::cout << n << ' '; 
    } 
    std::cout << std::endl; 

    for (int n : result.negatives) { 
     std::cout << n << ' '; 
    } 
    std::cout << std::endl; 
} 

Ce programme affichera ceci:

-18 -7 -9 -4 -13 -3 -20

Voici un exemple en direct au Coliru.

-2
#include<iostream> 
using namespace std; 
int main(){ 
    int a[10]={9,4,-3,-2,1,-1,5,7,-9,-5}; 
    int low=0; 
    int high=10-1; 
    while(low<high){ 
     while(a[low]>=0){ 
      low++; 
     } 
     while(a[high]<=0){ 
      high--; 
     } 
     if(low<high){ 
      int temp=a[low]; 
     a[low]=a[high]; 
     a[high]=temp; 
     } 

    } 
    for(int i=0;i<10;i++){ 
     cout<<a[i]<<" "; 
    } 
} 

Complexité: O (n)

+0

Bienvenue dans Stack Overflow! Cette question est à la recherche d'une * explication *, pas simplement pour le code de travail. Votre réponse ne fournit aucun point de vue à l'auteur de la question et peut être supprimée. S'il vous plaît [modifier] pour expliquer ce qui provoque les symptômes observés. –