For my data structures course I have to create a queue that takes input from a .dat file, and organizes it based on high priority (ONLY if it's 1) and low priority (2 3 4 or 5). There must be two queues, * indicates how many to service (or remove). The .dat file looks like:
R 3
T 5
W 1
A 4
* 3
M 5
B 1
E 1
F 2
C 4
H 2
J 1
* 4
* 1
D 3
L 1
G 5
* 9
=
Here's the main.cpp
int main ()
{
arrayQueue myHigh; //creates object of arrayQueue
arrayQueue myLow; //creates another object of arrayQueue
while(previousLine != "=") //gets all the lines of file, ends program when it gets the line "="
{
getline(datfile, StringToChar);
if (StringToChar != previousLine)
{
previousLine=StringToChar; //sets previousline equal to a string
number = StringToChar[2]; //the number of the data is the third line in the string
istringstream ( number ) >> number1; //converts the string to int
character = StringToChar[0]; //the character is the first line in the string
}
if (number1 == 1) //if number is 1, sends to high priority queue
myHigh.addToQueue(number1);
else if (number1 == 2 || number1 == 3 || number1 == 4 || number1 == 5) //if number is 2 3 4 or 5 sends to low priority queue
myLow.addToQueue(number1);
}
datfile.close();
system ("pause");
}
And here's the array class:
void arrayQueue::addToQueue(int x)
{
if (full() == true)
cout << "Error, queue full \n";
else {
fill = (fill+1)%maxSize;
queueArray[fill] = x;
cout << x << endl; //testing that number is actually being passed through
count++;
size++;
}
}
However, the output that I get is just:
3
5
and then it crashes with no error.
I'm not sure where I should go, I haven't created two objects of a class OR used a file to read data before in C++. Did I do that correctly? I think it's just feeding 3 and 5 into the high priority queue, even though it's not supposed to do that.
Because output is typically buffered you may not be seeing all of the output before your program crashes. From my examination of your code, I would expect it to crash when it reaches the last line of the input file, because StringToChar is of length 1 and you are accessing the StringToChar[2]. Well, maybe not crash, but certainly get garbage. I'm not sure if string would raise an exception.
Your processing of the read lines is certainly not quite right. First of all, you don't check whether you could successfully read a line but input should always be checked after you attempted to read it. Also, if the input is = you actually treat the value as if it is a normal line. Your basic input should probably look something like this:
while (std::getline(datFile, StringToChar) && StringToChar != "=") {
...
}
Given that your "string" number actually contains exactly one character, it is a little bit of overkill to create an std::istringstream (creating these object is relatively expensive) and decode a char converted to an std::string. Also, you actually need to check whether this operation was successful (for your last line, for example, it fails).
Converting a single char representing a digit to a string can be done using something like this:
if (3 <= StringToChar.size()
&& std::isdigit(static_cast<unsigned char>(StringToChar[2])) {
number1 = StringToChar[2] - '0';
}
else {
std::cout << "the string '" << StringToChar << "' doesn't have a digit at position 2\n";
continue;
}
I think "adipy" is close, but...
getline(datfile, StringToChar);
First, you should check the return value to make sure a string was returned.
Second, if we assume that StringToChar equals =, then
(StringToChar != previousLine) is true.
Then StringToChar[2];, <<<<< access violation. array is only two characters long.
Also, you might be trying to enter the last previousLine twice.
Related
I want to write a program that get the numbers with this rule :
every number be greater or smaller than the numbers before and after itself. like : 3 1 4 2 6 0 8 3 5 16
Whenever this rule was violated, stop getting number.
int a, b, c;
bool flag = true;
cin >> a;
while (flag)
{
cin >> b;
cin >> c;
if ((b < a && b < c) || (b > a && b > c))
{
flag = true;
a = c;
}
else
{
break;
}
}
My code works for some inputs but for this inputs : 3 1 4 6
When i enter 6 the program must be stop, but it continue to input next number. What should i do to fix it?
The solution to this problems involves a lot of logical evaluations. So, we need many boolean expressions and if statements.
One key to the solution, is to keep track of 2 values:
The current read value
The preivously read, old value
We can always compare those values and then make descisions. Problem is that we do not have an "previous" value in the beginning. So, we need to do a special treatment and first read a value from the user, store this as prvious value, and then always read a current value in a loop.
At the end of the loop, we will assign the current value to the "previuosValue". Then in the next loop run, we always need to read only the current value from the user.
Ant those 2 values, we can compare in a while loop.
We compare the current value with the previous value, and, depending of the outcome, define a "direction" flag for further comparisons.
This we do after having read the 2nd number. After that the direction is always defined and will never change.
Example, if the current value is bigger than the previous value, then, in the next loop, the next value must be smaller. And vice versa.
Example:
First value: 2
2nd value: 6
The second value is bigger than the first value. So, for next values we expect
small --> big --> small --> big --> small --> big --> . . .
and so on. This will never change.
Same is valid vice versa.
First value: 9
2nd value: 1
The second value is smaller than the first value. So, for next values we expect
big --> small --> big --> small --> big --> small --> big --> . . .
The direction flag will always be inverted after having processed the "next" number.
We can then evaluate the stop condition in the next loop run. Does the comparision result to a value, to a direction, that we expect?
If not, or if the values are equal, then we stop the input.
Of course, we will not do this evaluation in the first loop, because then, we have always a valid pair and calculate the direction afterwards.
So, you see. We always need only 2 variables.
There are many possible implementations, as always. Please see the below as an example for a solution:
#include <iostream>
int main() {
// Read initial previous number (The first number)
if (int previousNumber{}; std::cin >> previousNumber) {
// Flag that indicates, if we should continue reading new numbers or not
bool continueToRead{ true };
// First number needs special treatment, there is no other number
bool firstCheck{ true };
// The "direction" of the comparison
bool nextNumberMustBeSmaller{false};
// Read numbers in a loop
while (continueToRead) {
// Read current (next) number
if (int currentNumber{}; std::cin >> currentNumber) {
// After heaving read the first value in the loop, we can detect the direction
if (firstCheck) {
// Get the "direction" of the comparison for the next numbers
// If the number is bigger than last number
if (currentNumber > previousNumber)
// Then next value muste be smaller
nextNumberMustBeSmaller = true;
// If this number is smaller
else if (currentNumber < previousNumber)
// then next number must be bigger
nextNumberMustBeSmaller = false;
else
continueToRead = false;
// First check has been done
firstCheck = false;
}
else {
// Find out the stop condition
if (
// Direction is smaller but number is bigger or
(nextNumberMustBeSmaller and (currentNumber > previousNumber)) ||
// Direction is bigger but number is smaller or
(not nextNumberMustBeSmaller and (currentNumber < previousNumber)) ||
// Or numbers are equal
(currentNumber == previousNumber)) {
// Then: Stop reading values
continueToRead = false;
}
nextNumberMustBeSmaller = not nextNumberMustBeSmaller;
}
// Remember the last value. So, for the next loop rund, the current value will become the previous one
previousNumber = currentNumber;
}
else {
std::cerr << "\n\nInvalid input\n\n";
continueToRead = false;
}
}
}
else std::cerr << "\n\nInvalid input\n\n";
return 0;
}
To be compiled with C++17 enabled.
Here are some observations if we take the task as given in your question, but I think you may have misunderstood the task in one way or another.
every number be greater or smaller than the numbers before and after itself
greater or smaller means not equal.
you can't check the next number. You don't even know if there is a next number, so you can only check against the previous number
The final condition then becomes "stop if current and last number are equal"
In code this could look like this:
int a, b;
cin >> a;
while (cin >> b && a != b)
{
a = b; // current number becomes the last number
}
Note that I removed flag, because it was never set to false. The break will be enough. And I moved the cin >> b into the loop condition to validate the input. Then it turned out that we can merge the if-block into the loop condition as well.
I have a assingment were I need to code and decode txt files, for example: hello how are you? has to be coded as hel2o how are you? and aaaaaaaaaajkle as a10jkle.
while ( ! invoer.eof ( ) ) {
if (kar >= '0' && kar <= '9') {
counter = kar-48;
while (counter > 1){
uitvoer.put(vorigeKar);
counter--;
}
}else if (kar == '/'){
kar = invoer.get();
uitvoer.put(kar);
}else{
uitvoer.put(kar);
}
vorigeKar = kar;
kar = invoer.get ( );
}
but the problem I have is if need to decode a12bhr, the answer is aaaaaaaaaaaabhr but I can't seem to get the 12 as number without problems, I also can't use any strings or array's.
c++
I believe that you are making following mistake: imagine you give a32, then you read the character a and save it as vorigeKar (previous character, I am , Flemish so I understand Dutch :-) ).
Then you read 3, you understand that it is a number and you repeat vorigeKar three times, which leads to aaa. Then you read 2 and repeat vorigeKar two times, leading to aaaaa (five times, five equals 3 + 2).
You need to learn how to keep on reading numeric characters, and translate them into complete numbers (like 32, or 12 in your case).
Like #Dominique said in his answers, You're doing it wrong.
Let me tell you my logic, you can try it.
Pesudo Code + Logic:
Store word as a char array or string, so that it'll be easy to print at last
Loop{
Read - a //check if it's number by subtracting from '0'
Read - 1 //check if number = true. Store it in int res[] = res*10 + 1
//Also store the previous index in an index array(ie) index of char 'a' if you encounter a number first time.
Read - 2 //check if number = true. Store it in res = res*10 + 2
Read - b , h and so on till "space" character
If you encounter another number, then store it's previous character's index in index array and then store the number in a res[] array.
Now using index array you can get the index of your repeating character to be printed and print it for it's corresponding times which we have stored in the result array.
This goes for the second, third...etc:- numbers in your word till the end of the word
}
First, even though you say you can't use strings, you still need to know the basic principle behind how to turn a stream of digit characters into an integer.
Assuming the number is positive, here is a simple function that turns a series of digits into a number:
#include <iostream>
#include <cctype>
int runningTotal(char ch, int lastNum)
{
return lastNum * 10 + (ch -'0');
}
int main()
{
// As a test
char s[] = "a123b23cd1/";
int totalNumber = 0;
for (size_t i = 0; s[i] != '/'; ++i)
{
char digit = s[i]; // This is the character "read from the file"
if ( isdigit( digit) )
totalNumber = runningTotal(digit, totalNumber);
else
{
if ( totalNumber > 0 )
std::cout << totalNumber << "\n";
totalNumber = 0;
}
}
std::cout << totalNumber;
}
Output:
123
23
1
So what was done? The character array is the "file". I then loop for each character, building up the number. The runningTotal is a function that builds the integer from each digit character encountered. When a non-digit is found, we output that number and start the total from 0 again.
The code does not save the letter to "multiply" -- I leave that to you as homework. But the code above illustrates how to take digits and create the number from them. For using a file, you would simply replace the for loop with the reading of each character from the file.
i'm going to learn C++ at the very beginning and struggling with some challenges from university.
The task was to calculate the cross sum and to use modulo and divided operators only.
I have the solution below, but do not understand the mechanism..
Maybe anyone could provide some advice, or help to understand, whats going on.
I tried to figure out how the modulo operator works, and go through the code step by step, but still dont understand why theres need of the while statement.
#include <iostream>
using namespace std;
int main()
{
int input;
int crossSum = 0;
cout << "Number please: " << endl;
cin >> input;
while (input != 0)
{
crossSum = crossSum + input % 10;
input = input / 10;
}
cout << crossSum << endl;
system ("pause");
return 0;
}
Lets say my input number is 27. cross sum is 9
frist step: crossSum = crossSum + (input'27' % 10 ) // 0 + (modulo10 of 27 = 7) = 7
next step: input = input '27' / 10 // (27 / 10) = 2.7; Integer=2 ?
how to bring them together, and what does the while loop do? Thanks for help.
Just in case you're not sure:
The modulo operator, or %, divides the number to its left by the number to its right (its operands), and gives the remainder. As an example, 49 % 5 = 4.
Anyway,
The while loop takes a conditional statement, and will do the code in the following brackets over and over until that statement becomes false. In your code, while the input is not equal to zero, do some stuff.
To bring all of this together, every loop, you modulo your input by 10 - this will always return the last digit of a given Base-10 number. You add this onto a running sum (crossSum), and then divide the number by 10, basically moving the digits over by one space. The while loop makes sure that you do this until the number is done - for example, if the input is 104323959134, it has to loop 12 times until it's got all of the digits.
It seems that you are adding the digits present in the input number. Let's go through it with the help of an example, let input = 154.
Iteration1
crossSum= 0 + 154%10 = 4
Input = 154/10= 15
Iteration2
crossSum = 4 + 15%10 = 9
Input = 15/10 = 1
Iteration3
crossSum = 9 + 1%10 = 10
Input = 1/10 = 0
Now the while loop will not be executed since input = 0. Keep a habit of dry running through your code.
#include <iostream>
using namespace std;
int main()
{
int input;
int crossSum = 0;
cout << "Number please: " << endl;
cin >> input;
while (input != 0) // while your input is not 0
{
// means that when you have 123 and want to have the crosssum
// you first add 3 then 2 then 1
// mod 10 just gives you the most right digit
// example: 123 % 10 => 3
// 541 % 10 => 1 etc.
// crosssum means: crosssum(123) = 1 + 2 + 3
// so you need a mechanism to extract each digit
crossSum = crossSum + input % 10; // you add the LAST digit to your crosssum
// to make the number smaller (or move all digits one to the right)
// you divide it by 10 at some point the number will be 0 and the iteration
// will stop then.
input = input / 10;
}
cout << crossSum << endl;
system ("pause");
return 0;
}
but still dont understand why theres need of the while statement
Actually, there isn't need (in literal sense) for, number of digits being representable is limited.
Lets consider signed char instead of int: maximum number gets 127 then (8-bit char provided). So you could do:
crossSum = number % 10 + number / 10 % 10 + number / 100;
Same for int, but as that number is larger, you'd need 10 summands (32-bit int provided)... And: You'd always calculate the 10 summands, even for number 1, where actually all nine upper summands are equal to 0 anyway.
The while loop simplifies the matter: As long as there are yet digits left, the number is unequal to 0, so you continue, and as soon as no digits are left (number == 0), you stop iteration:
123 -> 12 -> 1 -> 0 // iteration stops, even if data type is able
^ ^ ^ // to store more digits
Marked digits form the summands for the cross sum.
Be aware that integer division always drops the decimal places, wheras modulo operation delivers the remainder, just as in your very first math lessons in school:
7 / 3 = 2, remainder 1
So % 10 will give you exactly the last (base 10) digit (the least significant one), and / 10 will drop this digit afterwards, to go on with next digit in next iteration.
You even could calculate the cross sum according to different bases (e. g. 16; base 2 would give you the number of 1-bits in binary representation).
Loop is used when we want to repeat some statements until a condition is true.
In your program, the following statements are repeated till the input becomes 0.
Retrieve the last digit of the input. (int digit = input % 10;)
Add the above retrieved digit to crosssum. (crosssum = crosssum + digit;)
Remove the last digit from the input. (input = input / 10;)
The above statements are repeated till the input becomes zero by repeatedly dividing it by 10. And all the digits in input are added to crosssum.
Hence, the variable crosssum is the sum of the digits of the variable input.
Just need general project help.
Basically I need to do this for 8 players. The numbers come from a file im supposed to call in. The first 5 numbers for for the first 5 games, the next for rebounds, and then for blocks. Im assuming I need to call in a loop to read the first name, last name, points, rebounds and blocks, process that info and then output the information.Any tips/ suggestions?
ex from the text file:
Thomas Robinson 17 28 10 16 10 11 12 13 8 9 1 1 1 0 1
ex from what I'm supposed to return that information to
Game Log
-----------------------------------------------------------------------------
Player Name : Thomas Robinson
-----------------------------------------------------------------------------
Game # Points Rebounds Blocks
-----------------------------------------------------------------------------
1 17 11 1
2 28 12 1
3 10 13 1
4 16 8 0
5 10 9 1
-----------------------------------------------------------------------------
I think this is homework, but since I don't know which functions can be used, and which functions can't, my answers may be can't fit the request.
At a first look, I got three ideas.
1) using ifstream::get()
ifstream in_file;
in_file.open("your_file_name.txt");
char ch;
string str = "";
while(in_file.get() != '\n')
{
str = "";
while((ch = in_file.get()) != ' ')
{
// add ch to str.
str += string(&ch, 1);
}
// push str into an array, vector, stack, etc.
/*...*/
}
in_file.close();
2) read the line into a string, and then use a split function, you can find how to implement a split function everywhere.
3) use the ifstream::getline() function, it provides a delemiter parameter.
you can find the usage of ifstream::get() and ifstream::getline() here and here
The code I provide in 1) is probably not a good practice, you should check the 'EOF' stream error, in_file.open()'s exceptions etc.
btw, the code I first wrote was an error code, you can't use str += string(ch), you should either write str += string(&ch, 1) or str += string(1, ch) or str += ch you can find string's constructors here. Sorry for the error code again.
You can parse the file with the ">>" operator pretty nicely if everything is separated by spaces and newlines. Which is how the ">>" operator works. So, yes, you need a loop. Basically you want the loop to work like this:
(I never knew you could do this in Comp Sci 1. It would've saved me so much trouble...I used to do things like what the other answer is doing.)
(I'm also assuming you know how to open a txt file as an ifstream. If not, see http://www.cplusplus.com/reference/iostream/ifstream/open/.)
int temp;
int n = 0;
int x = 1;
while(textfile >> temp) // Each time through the loop, this will make temp
// the next value in the file. It will stop when
// there's nothing more to read.
{
/* Now it's going to go from left to right through the file, so you
need some logic to put it in the right place. you know that every
five numbers start a new column, so:*/
array[x][n] = temp; //Start x at 1 because you're skipping the first column
n++;
if (n == 5) {
n = 0;
x++; //Every five values, move on to the next column
}
Now your array will have the stuff where it needs to be. Just output it according to plan.
gooday programers. I have to design a C++ program that reads a sequence of positive integer values that ends with zero and find the length of the longest increasing subsequence in the given sequence. For example, for the following
sequence of integer numbers:
1 2 3 4 5 2 3 4 1 2 5 6 8 9 1 2 3 0
the program should return 6
i have written my code which seems correct but for some reason is always returning zero, could someone please help me with this problem.
Here is my code:
#include <iostream>
using namespace std;
int main()
{
int x = 1; // note x is initialised as one so it can enter the while loop
int y = 0;
int n = 0;
while (x != 0) // users can enter a zero at end of input to say they have entered all their numbers
{
cout << "Enter sequence of numbers(0 to end): ";
cin >> x;
if (x == (y + 1)) // <<<<< i think for some reason this if statement if never happening
{
n = n + 1;
y = x;
}
else
{
n = 0;
}
}
cout << "longest sequence is: " << n << endl;
return 0;
}
In your program, you have made some assumptions, you need to validate them first.
That the subsequence always starts at 1
That the subsequence always increments by 1
If those are correct assumptions, then here are some tweaks
Move the cout outside of the loop
The canonical way in C++ of testing whether an input operation from a stream has worked, is simply test the stream in operation, i.e. if (cin >> x) {...}
Given the above, you can re-write your while loop to read in x and test that x != 0
If both above conditions hold, enter the loop
Now given the above assumptions, your first check is correct, however in the event the check fails, remember that the new subsequence starts at the current input number (value x), so there is no sense is setting n to 0.
Either way, y must always be current value of x.
If you make the above logic changes to your code, it should work.
In the last loop, your n=0 is execute before x != 0 is check, so it'll always return n = 0. This should work.
if(x == 0) {
break;
} else if (x > y ) {
...
} else {
...
}
You also need to reset your y variable when you come to the end of a sequence.
If you just want a list of increasing numbers, then your "if" condition is only testing that x is equal to one more than y. Change the condition to:
if (x > y) {
and you should have more luck.
You always return 0, because the last number that you read and process is 0 and, of course, never make x == (y + 1) comes true, so the last statement that its always executed before exiting the loop its n=0
Hope helps!
this is wrong logically:
if (x == (y + 1)) // <<<<< i think for some reason this if statement if never happening
{
Should be
if(x >= (y+1))
{
I think that there are more than one problem, the first and most important that you might have not understood the problem correctly. By the common definition of longest increasing subsequence, the result to that input would not be 6 but rather 8.
The problem is much more complex than the simple loop you are trying to implement and it is usually tackled with Dynamic Programming techniques.
On your particular code, you are trying to count in the if the length of the sequence for which each element is exactly the successor of the last read element. But if the next element is not in the sequence you reset the length to 0 (else { n = 0; }), which is what is giving your result. You should be keeping a max value that never gets reset back to 0, something like adding in the if block: max = std::max( max, n ); (or in pure C: max = (n > max? n : max );. Then the result will be that max value.