C ++从数组中分离正值和负值

时间:2016-11-06 01:25:22

标签: c++ arrays

这里的C ++初学者和学习数组。下面的程序应该将数组中的正数和负数分开。但是,它在splitPos和splitNeg函数中返回随机数。

有人可以如此友好地建议并告诉我函数中的错误是什么以及可以做些什么来省略这些随机数字,以便每个函数/循环的程序分别只返回正数和负数?我显然没有看到和/或理解什么是不正确的。

非常感谢你的帮助和提前的时间!!!

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

}

6 个答案:

答案 0 :(得分:2)

如果你改变你的for循环:

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

你会得到你想要的结果。

如果找到的值与小于(或大于)的标准相匹配,则目标数组的计数器变量只会增加。

说实话,我真的不明白你试图通过......嗯...“合并”增加像i++ && j++那样,这就是短路评估。

答案 1 :(得分:2)

将正确的值复制到jk时,

posArraynegArray必须递增 ,顾名思义。

如果值是错误的符号,jk显然应该保持不变,因为在相应的输出数组中具有正确符号的值的数量不会改变迭代。

这不是代码正在做的事情。除了i为0的那个迭代之外,它在循环的每次迭代中递增它们。

答案 2 :(得分:1)

这篇文章中的所有答案都很好,但我很失望,他们都没有谈论STL算法!

一个优秀的c ++程序员必须知道这门语言,但他也必须知道C ++库。

查看以下代码:

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

更一般地说,您希望使用谓词对集合进行分区。

在我的代码中找到任何iffor?以这种方式犯错是不可能的!

整个代码中唯一重要的是auto it = partition(begin(originalArray), end(originalArray), [](int n) { return n >= 0; });,可以理解为:partition from start to finish of originalArray elements that are positive

答案 3 :(得分:1)

有一种标准算法就是为此而制作的。它名为std::partition

使用该算法的代码如下所示:

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

然后,使用它:

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

该程序将输出:

  

7 30 8 17 6 31 6 3 19 15 12 12 4

     

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

以下是Coliru的实例。

答案 4 :(得分:-1)

本文中给出的答案已正确识别您的问题,因此您可以查看它们以了解有关您所犯错误的更多信息。然而,这个答案的目的是为您提供一种使用std :: vector和基于范围的for循环编写相同代码的现代方法(因为您处于学习过程的开始阶段,尽可能多地尝试避免使用C风格的数组并了解有关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";
   }
}

如果您需要更多说明,请与我们联系:)

答案 5 :(得分:-2)

@Injectable()
export class AuthenticationService {    
    private base_url: string;
    public logged_in: Subject<boolean> = new Subject();
     
    constructor(private http: Http) {
        this.base_url = 'http://localhost:3000/';
    }

    login(username: string, password: string): Observable<Response> {
        let query_url = `${this.base_url}login`;
        let payload = JSON.stringify({username: username, password: password});
        return this.http.post(query_url, payload)
        .map(res => res.json())
        .catch((error:any) => Observable.throw(error.json()));
    }

    logout(): Observable<Response>{
        let query_url = `${this.base_url}logout`;
        return this.http.post(query_url, null);
    }
}

时间复杂度:O(n)