2016-11-06 3 views
2

Anfänger in C++ hier und lernen Arrays. Das folgende Programm soll positive und negative Zahlen in einem Array trennen. Es gibt jedoch Zufallszahlen in den Funktionen splitPos und splitNeg zurück.C++ Separate positive und negative Werte von einem Array

Könnte jemand jemals so freundlich beraten und mir zeigen, was in den Funktionen falsch ist und was getan werden kann, um diese zufälligen Ziffern wegzulassen, so dass nur positive und negative Ziffern vom Programm für jede Funktion/Schleife zurückgegeben werden? Ich sehe und/oder verstehe offensichtlich nicht, was falsch ist.

Vielen Dank für Ihre Hilfe und Zeit im Voraus !!!

#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 ++' ist schlecht, weil '&&' Kurzschluss. In solchen Fällen sollten Sie stattdessen einen Komma-Operator verwenden: 'i ++, j ++' – Pubby

+0

Gut gestellte Frage. – user4581301

+0

[Schau, keine Schleifen!] (Http://ideone.com/lKycNF) – PaulMcKenzie

Antwort

2

Wenn Sie ändern Ihre ein bisschen für Schleifen:

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; 
} 

Sie werden das Ergebnis, das Sie wünschen, erhalten.

Die Zählervariablen Ihrer Zielarrays nur erhöht erhalten, wenn Sie einen Wert finden, die das Kriterium entspricht weniger zu sein (oder höher) als 0

ich ehrlich gesagt nicht verstehen, was Sie mit einem zu erreichen versucht. .. hmmm .. "combined" erhöhen wie i++ && j++, dies geht in die Kurzschlussauswertung.

2

j und k muss nur erhöht werden, wenn der korrekte Wert auf posArray kopiert und negArray, per Definition.

Wenn der Wert das falsche Vorzeichen ist, sollten j und k natürlich unverändert bleiben, da sich die Anzahl der Werte mit dem richtigen Vorzeichen im entsprechenden Ausgabearray bei dieser Iteration nicht ändert.

Dies ist nicht, was der Code tut. Sie werden bei jeder Iteration der Schleife inkrementiert, mit Ausnahme der, bei der i 0 ist.

-1

Die Antworten in diesem Beitrag haben Ihr Problem korrekt identifiziert, so dass Sie sie sich ansehen können, um mehr über die Fehler zu erfahren du machtest. Das Ziel dieser Antwort ist jedoch, Ihnen einen modernen Ansatz zu geben, um den gleichen Code mit dem std :: vector und der range-basierten for-Schleife zu schreiben (da Sie am Anfang Ihres Lernprozesses sind, versuchen Sie so viel wie möglich C-Stil-Arrays und erfahren Sie mehr über die STL-Container)

#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"; 
    } 
} 

Lassen Sie mich wissen, wenn Sie mehr Klärungsbedarf :)

+3

Ich denke, es kann noch weiter gehen. Der Algorithmus zum Gruppieren von Elementen in einem Array mit einem Prädikat ist [std :: partition] (http://en.cppreference.com/w/cpp/algorithm/partition). Mit C++ 11, [std :: begin()] (http://en.cppreference.com/w/cpp/iterator/begin) und [std :: end()] (http://en.cppreference.com/w/cpp/iterator/end) könnte mit dem c style array und einem [lambda] (http://en.cppreference.com/w/cpp/language/lambda) ('' '[] (int el) {return el <= 0;} '' ') um die negativen und positiven Werte im Array zu trennen. – ghlecl

+0

Dieser Code hat nichts von "modern". Modern bedeutet nicht, dass Vektor oder Bereich für Schleifen verwendet wird. Moderner Code bedeutet vermeiden, verwenden Sie Schleifen, vermeiden Sie so weit wie möglich, wenn, wechseln, verwenden Sie die STL und insbesondere Algorithmen –

+0

Ausgabeparameter ... ugh. Du solltest ein Paar Vektoren in deiner Funktion 'splitArr' zurückgeben. –

1

alle Antworten in diesem Beitrag sind gut, aber ich bin enttäuscht, zu vermeiden, dass keiner von ihnen spricht über die STL-Algorithmen!

Ein guter C++ - Programmierer muss die Sprache kennen, aber er muss auch die C++ - Bibliothek kennen.

sehen Sie den folgenden Code:

#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; 
} 

Allgemeiner wollen Sie Ihr Gerät mit einem Prädikat partitionieren.

Suchen Sie nach meinem Code finden Sie if oder for?Es ist unmöglich, auf diese Weise Fehler zu machen!

Die einzige Sache, die im gesamten Code von Bedeutung ist, ist auto it = partition(begin(originalArray), end(originalArray), [](int n) { return n >= 0; });, die gelesen werden kann als: .

1

Es gibt einen Standardalgorithmus, der nur dafür gemacht wird. Es heißt std::partition.

Ihr Code mit diesem Algorithmus wird wie folgt aussehen:

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 
    }; 
} 

Dann es so verwenden:

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; 
} 

Dieses Programm wird ausgegeben dies:

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

Hier ist ein Live-Beispiel unter 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]<<" "; 
    } 
} 

Zeitkomplexität: O (n)

+0

Willkommen bei Stack Overflow! Diese Frage sucht nach einer * Erklärung *, nicht nur nach funktionierendem Code. Ihre Antwort bietet keinen Einblick für den Fragesteller und kann gelöscht werden. Bitte [bearbeiten] um zu erklären, was die beobachteten Symptome verursacht. –

Verwandte Themen