I am working on a project which requires me to accept a string written in reverse polish notation and evaluate it using a stack. I am supposed to go through the string and if the element is a number, I keep going through the string until I reach a space, and I convert that section of the string to an integer using atoi. I then push that integer onto the stack. My code for this works, however, I am not sure how to continue to the next number after the space. This is the for loop I have so far:
for (unsigned int i = 0; i < a.size(); i++)
{
int b;
char c[a.size()];
while (isdigit(a[i]))
{
cout << a[i] << endl;
c[i] = a[i];
b = atoi(c);
i++;
}
cout << b << endl;
stack.push(b);
}
This always pushes the first integer onto the stack, even if there are more after a space. What would I need to add to continue pushing integers onto the stack after a space? Thanks for your help.
Your problem is here:
c[i] = a[i];
When reading the second integer you will use the current i and not write the digits at the start of your array c. The call to atoi(c) will see the first integer which was not overwriten and return that value.
You should use a second index to put digits in the c array and reset this second index after you pushed an integer on the stack.
Here is an example (not tested):
unsigned j = 0;
char c[a.size()+1];
for (unsigned int i = 0; i < a.size(); i++)
{
int b;
while (isdigit(a[i]))
{
cout << a[i] << endl;
c[j] = a[i];
j++;
i++;
}
c[i] = '\0';
b = atoi(c);
cout << b << endl;
stack.push(b);
j = 0;
}
I assume this is some homework and you must work the way you do. In idiomatic C++ one would use a stringstream for this work.
#include <sstream>
int b;
std::stringstream buffer(a);
while(buffer >> b) {
stack.push(b);
}
Related
c++
When printing to console, if function execution is sequential it would seem logical the ordered array would be printed after calling insertionSort, however order list does not print until next loop. Any help would be appreciated.
#include <stdio.h>
#include <iostream>
#include <array>
using namespace std;
void insertionSort(int* array, int size) {
for (int i = 1; i < size; i++) {
int key = i - 1;
while (i > 0 && array[key] > array[i] ) {
int tmp = array[i];
array[i] = array[key];
array[key] = tmp;
i -= 1;
key -= 1;
}
}
}
const int ARRAY_MAXSIZE = 5;
int main(void) {
int *array = (int*)calloc(ARRAY_MAXSIZE, sizeof(int));
int input;
cout << "Enter 5 digits\n";
for (int size=0; size < ARRAY_MAXSIZE; size++) {
cout << size << " index ";
cin >> input;
array[size] = input;
insertionSort(array, size);
for (int j=0; j <= size; j++) {
cout << array[j];
}
cout << '\n';
}
}
Console Entry
This is a classic off-by-one error. Your insertionSort expects you to pass the number of elements to sort via the parameter size. But your main loop is always holding a value that is one less than the size immediately after adding an element.
I want to say that bugs like this are easily discovered by stepping through your program's execution with a debugger. If you don't know how to use a debugger, start learning now. It is one of the most important tools used by developers.
Anyway, the quick fix is to change your function call to:
insertionSort(array, size + 1);
However, as Paul McKenzie pointed out in comments, it's a bit crazy to do this every time you add a new element because your function sorts an entire unsorted array. Your array is always nearly sorted except for the last element. You only need to call that function once after your input loop is done:
// Read unsorted data
for (int size = 0; size < ARRAY_MAXSIZE; size++) {
cout << size << " index ";
cin >> input;
array[size] = input;
}
// Sort everything
insertionSort(array, ARRAY_MAXSIZE);
// Output
for (int j = 0; j < ARRAY_MAXSIZE; j++) {
cout << array[j];
}
cout << '\n';
But if you want every insertion to result in a sorted array, you can "slide" each new value into place after inserting it. It's similar to a single iteration of your insertion-sort:
// Sort the last element into the correct position
for (int i = size; i >= 1 && array[i] > array[i - 1]; i--)
{
std::swap(array[i], array[i - 1]);
}
Even better, you don't need to swap all those values. You simply read the value, then shuffle the array contents over to make room, then stick it in the right spot:
// Read next value
cin >> input;
// Shuffle elements to make room for new value
int newPos = size;
while (newPos > 0 && array[newPos - 1] > input) {
array[newPos] - array[newPos - 1];
newPos--;
}
// Add the new value
array[newPos] = input;
I have an array that reads data from a file, the data is binary digits such as 010011001001 and many others so the data are strings which I read in to my 2d array but I am stuck on comparing each value of the array to 0. Any help would be appreciated.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string myArr[5000][12];
int i = 0, zeroCount = 0, oneCount = 0;
ifstream inFile;
inFile.open("Day3.txt");
while(!inFile.eof())
{
for(int i = 0; i < 5000; i++)
{
for(int j = 0; j < 12; j++)
{
inFile >> myArr[i][j];
j++;
}
i++;
}
}
for(int j = 0; j < 12; j++)
{
for(int i = 0; i < 5000; i++)
{
if(myArr[i][j].compare("0") == 0)
{
zeroCount++;
}
else
{
oneCount++;
}
i++;
}
if(zeroCount > oneCount)
{
cout << "Gamma is zero for column " << i << endl;
}
else
{
cout << "Gamma is One for column " << i << endl;
}
j++;
}
}
some input from the text file:
010110011101
101100111000
100100000011
111000010001
001100010011
010000111100
Thank you for editing you question and providing more information. Now, we can help you. You have 2 major misunderstandings.
How does a for loop work?
What is a std::string in C++
Let us start with the for loop. You find an explanation in the CPP reference here. Or, you could look also at the tutorial shown here.
The for loop has basically 3 parts: for (part1; part2; part3). All are optional, you can use them, but no need to use them.
part1 is the init-statement. Here you can declare/define/initialize a variable. In your case it is int i = 0. You define a variable of data type int and initialize it with a value of 0
part2 is the condition. The loop will run, until the condition becomes false. The condition will be check at the beginning of the loop.
part3 is the so called iteration-expression. The term is a little bit misguiding. It is basically a statement that is executed at the end of the loop, before the next loop run will be executed and before the condition is checked again.
In Pseudo code it is something like this:
{
init-statement
while ( condition ) {
statement
iteration-expression ;
}
}
which means for the part of your code for(int j = 0; j < 12; j++)
{
int j = 0; // init-statement
while ( j < 12 ) { // while ( condition ) {
inFile >> myArr[i][j]; // Your loop statements
j++; // Your loop statements PROBLEM
j++; // iteration-expression from the for loop
}
}
And now you see the problem. You unfortunately increment 'j' twice. You do not need to do that. The last part3 of the for loop does this for you already.
So please delete the duplicated increment statements.
Next, the std::string
A string is, as its names says, a string of characters, or in the context of programming languages, an array of characters.
In C we used to write actually char[42] = "abc";. So using really a array of characters. The problem was always the fixed length of such a string. Here for example 42. In such an array you could store only 41 characters. If the string would be longer, then it could not work.
The inventors of C++ solved this problem. They created a dynamic character array, an array that can grow, if needed. They called this thing std::string. It does not have a predefined length. It will grow as needed.
Therefore, writing string myArr[5000][12]; shows that you did not fully understand this concept. You do not need [12], becuase the string can hold the 12 characters already. So, you can delete it. They characters will implicitely be there. And if you write inFile >> myString then the extractor operator >> will read characters from the stream until the next space and then store it in your myString variable, regardless how long the string is.
Please read this tutorial about strings.
That is a big advantage over the C-Style strings.
Then your code could look like:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string myArr[5000];
int zeroCount = 0, oneCount = 0;
ifstream inFile;
inFile.open("Day3.txt");
while (!inFile.eof())
{
for (int i = 0; i < 5000; i++)
{
inFile >> myArr[i];
}
}
for (int i = 0; i < 5000; i++)
{
zeroCount = 0; oneCount = 0;
for (int j = 0; j < 12; j++)
{
if (myArr[i][j]== '0')
{
zeroCount++;
}
else
{
oneCount++;
}
}
if (zeroCount > oneCount)
{
cout << "Gamma is zero for column " << i << endl;
}
else
{
cout << "Gamma is One for column " << i << endl;
}
}
}
But there is more. You use the magic number 5000 for your array of strings. This you do, because you think that 5000 is always big enough to hold all strings. But what, if not? If you have more than 5000 strings in your source file, then your code will crash.
Similar to the string problem for character arrays, we have also a array for any kind of data in C++, that can dynamically grow as needed. It is called std::vector and you can read about it here. A tutorial can be found here.
With that you can get rid of any C-Style array at all. But please continue to study the language C++ further and you will understand more and more.
Ther are more subtle problems in your code like while(!inFile.eof()), but this should be solved later.
I hope I could help
I have a program I am writing that prints out a Fibonacci Sequence up to 30 numbers. I must do this by traversing the array using pointers, but I don't know how to.
There is not a lot of easy to follow information that I can understand.
When I see the code for c++ answers to this, all I see is this...
I'm a noob and I am having a hard time looking at all of the 'std::' conventions when I have to look at code. I know it's probably good convention, but I am not good with it yet. So I would like a straightforward example, assuming I am using the using namespace std; line of code within my project.
I have tried setting the for..loop up with the pointer variable but I am not sure how to do this.
void fibonacciSequence(){
//initialize the array and users input
const int ARRAY_SIZE = 30;
int numbers[ARRAY_SIZE];
int *pointer;
pointer = numbers;
//Traverse the array and generate the Fibonacci Sequence
for(int i = 0; i < ARRAY_SIZE; i++){
//Set first element to 0
if(i == 0){
numbers[i] = 0;
}
//Set second element to 1
else if (i == 1){
numbers[i] = 1;
}
//Start calculating the sequence after the first 2 elements
//have been established.
else{
numbers[i] = numbers[(i - 1)] + numbers[(i - 2)];
}
}
// Output the Fibonacci Sequence after calculations.
for(int i = 0; i < ARRAY_SIZE; i++){
cout << numbers[i] << endl;
}
}
This code I have works perfectly. But instead of traversing the array using 'i' in the for...loop, i need to use 'pointer.'
It's actually very simple change this
for(int i = 0; i < ARRAY_SIZE; i++){
cout << numbers[i] << endl;
}
to this
for(int* p = numbers; p < numbers + ARRAY_SIZE; p++){
cout << *p << endl;
}
Explanation
int* p = numbers - set p to point to the beginning of the array
p < numbers + ARRAY_SIZE - check p hasn't reached the end of the array
p++ - move p on to the next element of the array
*p - access the element that p is pointing to
Similar changes to your first loop.
This whole topic is pointer arithmetic, maybe you could do some research.
This probably isn't a good project for learning pointers, since indexing is the most natural way of computing a fibanocci sequence. But here goes. Replace that generator loop with this:
int *current = numbers;
*current++ = 0;
*current++ = 1;
while (current != numbers + ARRAY_SIZE) {
*current = *(current - 1) + *(current - 2);
++current;
}
And then for the output:
for (current = numbers; current != numbers + ARRAY_SIZE; ++current)
std::cout << *current << '\n';
as the title says I'm attempting to compare elements in an array. My intent is to have the user enter 3 integers into the program, thereafter it should increment through this array comparing the the 1st number to the 2nd, and so forth and swapping the element's from order of lowest to highest.
My issue currently is that it will swap the first and second elements but the third causes an integer overflow due to me comparing and assigning an integer in an index higher than the initialized array can hold.
I'm currently drawing a blank as to how I could still compare these numbers in this manner without causing it to overflow.
A hint or perhaps a whole different perspective would be appreciated.
#include "E:/My Documents/Visual Studio 2017/std_lib_facilities.h"
int main()
{
cout << "Enter three integers: \n";
int numbersArray[3];
int temp = 0; //This lets us hold our integers temporarily so we can swap them around in the array
//This enters integers as elements in the array
for (int i = 0; i < 3; i++)
{
cin >> numbersArray[i];
}
//This should swap the elements from smallest to greatest
for (int i = 0; i = 3; i++)
{
if (numbersArray[i] > numbersArray[i+1])
temp = numbersArray[i];
numbersArray[i] = numbersArray[i+1];
numbersArray[i+1] = temp;
//swap(numbersArray[i], numbersArray[++i]);
}
//This prints the index's containing the elements in the array
for (int i = 0; i < 3; i++)
{
cout << numbersArray[i] << ' ';
}
cout << endl;
keep_window_open();
return 0;
}
You will need to modify this to suit your needs, but this should get you on the right track. One important thing to investigate is how you decided to sort the elements. Your sorting needs to be looped, otherwise, you won't necessarily sort the entire array (depending on your inputs).
#include <iostream>
using namespace std;
int main()
{
cout << "Enter three integers: \n";
int numbersArray[3];
int temp = 0; //This lets us hold our integers temporarily so we can swap them around in the array
//This enters integers as elements in the array
for (int i = 0; i < 3; i++)
{
cin >> numbersArray[i];
}
for(int loop = 0; loop <3; loop++){
//This should swap the elements from smallest to greatest
for (int i = 0; i < 2; i++)
{
if (numbersArray[i] > numbersArray[i+1]){
temp = numbersArray[i];
numbersArray[i] = numbersArray[i+1];
numbersArray[i+1] = temp;
}
//swap(numbersArray[i], numbersArray[++i]);
}
}
//This prints the index's containing the elements in the array
for (int i = 0; i < 3; i++)
{
cout << numbersArray[i] << ' ';
}
cout << endl;
return 0;
}
I want to make a program that lets the user insert some numbers to the array and the print it out afterwards. Problem is when I try to do that (lets say the size of my array is 100) then:
What it should do: Inserted- 1,2,3,4,5 -> should print 1,2,3,4,5
But instead it prints -> 1,2,3,4,5,0,0,0,0,0,0, .... up to the size of my array.
Is there any way I can get rid of those zeros?
Code:
int SIZE = 100;
int main()
{
int *numbers;
numbers = new int[SIZE];
int numOfElements = 0;
int i = 0;
cout << "Insert some numbers (! to end): ";
while((numbers[i] != '!') && (i < SIZE)){
cin >> numbers[i];
numOfElements++;
i++;
}
for(int i = 0; i < numOfElements; i++){
cout << numbers[i] << " ";
}
delete [] numbers;
return 0;
}
You increase numOfElements no matter what the user types. Simply do this instead:
if(isdigit(numbers[i]))
{
numOfElements++;
}
This will count digits, not characters. It may of course still be too crude if you want the user to input numbers with multiple digits.
Get numOfElements entered from user beforehand. For example
int main() {
int n;
cin >> n;
int * a = new int[n];
for (int i = 0; i < n; ++i)
cin >> a[i];
for (int i = 0; i < n; ++i)
cout << a[i] << endl;
delete[] a;
}
Input
4
10 20 30 40
Output
10 20 30 40
Since you declared array size, all indices will be zeros.
User input changes only the first x indices from zero to the value entered (left to right).
All other indices remains 0.
If you want to output only integers different from 0 (user input) you can do something like that:
for(auto x : numbers){
if(x!=0)cout<<x<<" ";
}
You can use vector and push_back the values from user input to get exactly the
size you need without zeros, then you can use this simple code:
for(auto x : vectorName)cout<<x<<" ";
Previous solutions using a counter is fine.
otherwise you can (in a while... or similar)
read values in a "temp" var
add if temp non zero
exit loop if counter >= SIZE-1 (you reach max slots)
increment counter
when You will print, form 0 to counter, you will get only non zero values.