Search code examples
c++stackprime-factoring

Prime factors with stack implementation in C++


Greetings stack overflow, recently run into a problem where my code isn't doing exactly what I intend it to do. My intentions are for the user to input a number and then the program will check for its prime factors, when it finds a prime factor I want it to push the number into a stack. I've tried putting cout statements throughout the program to see if any specific spot isn't working but I haven't found anything yet. I believe I am very close to figuring this out, but I am not sure how to advance from here.

Here is my code:

#include <iostream>
#include <cmath>
using namespace std;

class stack
{
    public:
        static const int MAX = 100;
        stack() { used = 0; } // constructor

        void push(int entry);
        int pop();
        int size() { return used; }
        bool empty() { return used == 0;}

    private:
        int data[MAX];
        int used; // how many elements are used in the stack, top element is used - 1
};

void stack::push(int entry)
{
    data[used] = entry;
    ++used;
}

int stack::pop()
{
    --used;
    return data[used];
}

void primeFactors(stack, int);

int main()
{
    stack primeValues;
    int entry = 0;

    cout << "Enter a positive integer (0 to stop): ";
        cin >> entry;

    if (entry != 0)
    {
        cout << "Prime factors: " << entry << " = ";
    }
    primeFactors(primeValues, entry);

    while(primeValues.pop() != 0) // hopefully continues to pop the prime factors until it reaches zero?
    {
        cout << primeValues.pop() << " ";
    }

    return 0;
}

void primeFactors(stack primeValues, int entry)
{
    if (entry == 0)
    {
        return; // terminate when zero is reached
    }
    if (entry == 1)
    {
        cout << entry; // if 1 is reached display one
    }

    while (entry % 2 == 0) // while there is no remainder do the following
    {
        primeValues.push(2); // push two into stack 
        entry = entry/2;
    }

    for (int i = 3; i <= sqrt(entry); i = i+2) // start looping through numbers to find more prime factors
    {
        while (entry % i == 0)
        {
            primeValues.push(i);
            entry = entry/i;
        }
    }

    if (entry > 2) // if the number is greater than two and doesnt have prime factors push the number
    {
        primeValues.push(entry);
    }
}

I've tried all sorts of different numbers and nothing seems to work. I've tried just popping a few times to see if anything was pushed, but it only displayed zero. What am I missing here?


Solution

  • You've made a very simple error. In passing your stack by value to primeFactors the stack is copied and the copy worked on. When primeFactors finishes, that copy is discarded, and your original empty stack is left.

    Taking advantage of C++ templates:

    #include <iostream>
    #include <cmath>
    
    template <typename T, unsigned int MAX>
    class stack {
        private:
        T data[MAX] = { 0 };
        unsigned int used = 0;
    
        public:
        stack() : used(0) {}
    
        void push(T entry) {
            if (used <= MAX - 1) {
                data[used] = entry;
                used += 1;
            }
        }
    
        T pop() {
            used -= 1;
            return data[used];
        }
    
        unsigned int size() const {
            return used;
        }
    
        bool empty() const {
            return used == 0;
        }
    };
    
    template <typename T, unsigned int MAX>
    void primeFactors(stack<T, MAX>&, int);
    
    int main() {
        stack<int, 100> primeValues;
        int entry = 0;
    
        std::cout << "Enter a positive integer (0 to stop): ";
        std::cin >> entry;
    
        if (entry == 0) {
            return 0;
        }
    
        primeFactors(primeValues, entry);
    
        while (!primeValues.empty()) {
            std::cout << primeValues.pop() << " ";
        }
    
        std::cout << std::endl;
    }
    
    template <typename T, unsigned int MAX>
    void primeFactors(stack<T, MAX>& primeValues, int entry) {
        if (entry == 0) {
            return;
        }
    
        if (entry == 1) {
            std::cout << entry << std::endl;
        }
    
        while (entry % 2 == 0) {
            primeValues.push(2);
            entry /= 2;
        }
    
        for (int i = 3; i <= std::sqrt(entry); i += 2) {
            while (entry % i == 0) {
                primeValues.push(i);
                entry /= i;
            }
        }
    }