C++ Comparing vector elements to determine correct answer - c++

I have been fighting with this for awhile. I am trying to create a score results from 2 vectors, 1 vector being the actual answer and the other being the entered answer.
Essentially comparing:
for (i=1;i<=totalQ;i++){
cout<<"Enter question answer: ";
cin>>inputQ;
questions.push_back(inputQ);
}
to this:
for (i=1;i<=totalQ;i++){
cout<<"Enter your answer: ";
cin>>studentA;
answers.push_back(studentA);
}
I cant quite figure out how to compare the elements with each other to return how many are the same (correct answers).
initially i tried without using the second vector, and comparing the string from the second input to the questions vector by doing this:
for (i=1;i<=totalQ;i++){
cout<<"Enter your answer: ";
cin>>studentA;
if(studentA == questions[i]){
score=score+1}
}
but the compare statement kept causing the program to crash. After researching a bit i came to the conclusion that I wouldnt be able to compare the vector using [] so i decided to create a vector to compare the 2... which hasnt panned out.
How can i compare the 2 vectors to provide the amount of matching elements and indexes, or how could i compare an input to a vector element.
Both vectors are string vectors, and studentA was a string variable.

You could do it like this
#include <vector>
#include <iostream>
#include <string>
//#include <cstring>
using namespace std;
int main(int, char**)
{
int i;
int score = 0;
int totalQ = 3;
vector<string> questions;
vector<string> answers;
for (i=0;i<totalQ;i++)
{
string inputQ;
cout<<"Enter question answer: ";
cin>>inputQ;
questions.push_back(inputQ);
}
for (i=0;i<totalQ;i++)
{
string studentA;
cout<<"Enter your answer: ";
cin>>studentA;
answers.push_back(studentA);
}
for (i=0;i<totalQ;i++)
{
//if(strcmp(answers[i].c_str(), questions[i].c_str()) == 0)
if(answers[i].compare(questions[i]) == 0)
{
score++;
}
}
cout << "You got " << score<< " correct" << endl;
}
I've assumed that you store your answers as strings.
The things you need to remember are
To start your indexes from 0, this is how they are accessed in the vector using operator []. You wont need the <= in your loop and it wont crash as you wont overrun your vector by one.
To compare the strings in a loop you can use either the compare method of the string or good old fashioned strcmp.

use the std::find function, for example, assuming answers is the vector of correct answer, and answer is the entered answer:
if( std::find(answers.begin(), answers.end(), answer) != answers.end() ) {
score+=1;
}
by the way, your program crashes because your index starts from 1 and ends with size:
for (i=1;i<=totalQ;i++){
in C++ vector index starts from 0, so you it should be:
for (i=0;i<totalQ;i++){

Your for loop is not looping through the whole vector. Indices start at 0, and use < instead <= .in example 2 you forgot a semicolon. Use score++; instead of score = score+1. Accessing a vector of size N at index N causes your program to crash since indices start at 0

Related

Looping vector in C++ causes invalid iterations [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have written a small program that takes inputs as string which is stored in a vector.
Looping through the vector causes many empty strings being printed before actual output.
I have copied the sample lines below.
int main(){
int totalStrings;
string inputs;
vector<string> testCases(totalStrings);
cin>>totalStrings;
while(cin>>inputs)
testCases.push_back(inputs);
for(vector<string>::iterator it=testCases.begin();it!=testCases.end();++it)
printCustom(*it);
return 0;
}
I tried printing the size of the string in the printCustom function. I had hundreds of zero printed before the actual input
vector<string> testCases(totalStrings);
This line of code has two issues:
totalStrings is uninitialized and thus garbage,
vector(N) creates a vector of size N default-initialized elements, as though you had called resize rather than reserve on the vector.
What you wanted was:
std::cin >> totalStrings;
std::vector<std::string> testCases;
testCases.reserve(totalStrings);
Try the following:
cin>>totalStrings;
vector<string> testCases(totalStrings);
You have initialized totalStrings (as int) without a proper value, and you have used it to initialize the vector. This is bad times!!
Moreover, please check your indentations (a very good practice).
All the best.
To explain further (Please check the code, if required):
In your code, you wrote:
int totalStrings;
string inputs;
vector<string> testCases(totalStrings);
Point 1:
In the first line, you have not initialized totalStrings to anything. In such case depending on the computer, the vector can be initialized to any possible length. In my computer, if I do the following:
int totalStrings;
cout << totalStrings; // printing un-initialized totalStrings
string inputs;
vector<string> testCases(totalStrings);
The code prints zero, meaning totalStrings is, by magic, initialized to zero. But it may or may not be the case with your system.
Point 2:
Now when you initialize a vector with a predefined size you have provided space for values but there is no value, by default. And since you are using push_back method, you are enlarging the vector and adding to the end of the vector.
Implication of point 1 and point 2 in your final output;
Therefore, when you print (using the for loop and iterator) you will get as many zeros as the initial length (defined by totalStrings and the vector initialization); and after printing the initial vector it will print the strings that you have entered manually.
Please play with the following code to get a feeling. I hope this helps.
#include <string>
#include <vector>
#include <iostream>
using namespace std;
int main() {
int totalStrings;
cout << "Please enter initial vector length: ";
cin >> totalStrings;
vector<string > testCases(totalStrings);
string inputs;
cout << "Enter the strings into the vector [Enter -1 to finish]: ";
while(true) {
cin >> inputs;
if (inputs == "-1") { break; }
testCases.push_back(inputs);
cout << "Next? ";
}
for (vector<string>::iterator it = testCases.begin(); it != testCases.end(); ++it)
cout << ' ' << it->size();
return 0;
}

Unexpected array behavior in basic averaging program

It seems like I always come here to ask silly questions, but here it goes. As of right now I am in my first compsci course and we are learning c++. I've had an extremely basic introduction to c before, so I had thought I'd go above and beyond my current assignment. Now I was doing this just to showboat, I felt like if I didn't practice my previous concepts they would eventually fade. Anyways, on to the problem! I was supposed to write some code that allowed the user to input their initials, and a series of exams. Now this was supposed to accomplish three things: average the exams, print out the entered exams, and print out their initials. Well, what was a simple assignment, got turned into a huge mess by yours truly.
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
string uInitials;
float avgExam = 0, tExam = 0;
int aExams[10] = {'0'};
int i, nExam = 0, cExam;
cout << "Enter your three initials!";
cin >> uInitials;
do
{
cout << "Enter your exam(s) to be averaged. Enter 0 when complete!\n";
cin >> cExam;
aExams[nExam] = cExam; //I used this before nExam was incremented, in order to get nExam while it was '0' That way the first exam score would be properly saved in the first space
nExam++;
tExam += cExam; //This is just to add all the exams up to later calculate the average
}
while(cExam != 0);
avgExam = tExam/(nExam - 1); //subtracted '1' from nExams to remove the sentinel value from calculations.
cout << "The average for initials: " << uInitials << " is: " << avgExam << endl;
cout << "This average was obtained using the following scores that were entered: \n";
for(i = 0; i < (nExam+1); i++)
{
cout << aExams[i] << endl; //Used a for loop to prevent redundancy
}
return 0;
}
The previous is my code, and the problem is that I'm getting output errors where it adds two '0's when I print out the list of entered exams. Also I feel like I made the whole do{}while() loop one huge clunky mess, so I'd like to refine that as well. If anyone could assist this poor, ignorant, beginner I would greatly appreciate it. Thank you for your time!
Some advice that i can give is for example in the 5th line there is no need
to put the 0 between ' ' and not even need to use the assign = operator.
You can initialize the array like this:
int aExams[10]{0};
Which will initialize all elements to 0,but can't be used for other value.
For example you won't have all the elements with value 1 if you write
int aExams[10]{1};
If your intention to initialize all elements in an array is with value other than 0 you can use fill_n(); function.
fill_n(aExams, 10, 1);
The first argument is the name of the array, the second is up-to which element you want to be initialized with the third argument, and the third is the value you want all elements to have.
Do not leave uninitialized variables like in line 6 with cExam and i variables. Initialize it like cExam=0; (copy-assign initialization) or cExam(0); (direct initialization). The latter calls the constructor for int built-in type.
A negative i see in your do-while loop is that you do not make sure that the user will enter under 10 exams,bad things will happen if the user tries to input 15 exams in an array that can hold only 10.
Just change the while to something more like this:
while( cExam != 0 && (nExam<10) );
You can also write the first two lines of the do-while loop outside the loop.
It is needed only once to tell the user that to stop the loop he/she needs to enter 0. There is no need to tell them this on every iteration plus that you will have a good performance benefit if you put those two lines outside the loop.
Look here how i would write the code and ask if you have any questions.
http://pastebin.com/3BFzrk5C
The problem where it prints out two 0's at the end of your code is a result of the way you wrote your for loop.
Instead of:
for(i = 0; i < (nExam+1); i++)
{
cout << aExams[i] << endl; //Used a for loop to prevent redundancy
}
Use:
for (i = 1; i < (nExam); i++)
{
cout << aExams[i - 1] << endl; //Used a for loop to prevent redundancy
}

count even length words in vectors

I have 2 problems.
1) cout << v_setir.capacity(); is not returns the correct number.
2) I want to count of the words which lengths are even. and I should do it with vectors.
Here is my codes:
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
int main()
{
int say = 0;
cout << "Setiri daxil edin: ";
string setir;
getline(cin, setir);
vector<string> v_setir;
string ifadeler;
istringstream yig(setir);
while (yig >> ifadeler)
v_setir.push_back(setir);
// First problem
cout << v_setir.capacity() << endl;
// Second problem
/* for (size_t i = 0; i < v_setir.capacity(); i++)
{
if (v_setir[i].size() % 2 == 0)
say += 1;
}
cout << "Uzunlugu cut olan sozerin sayi: " << say << endl;*/
return 0;
}
For example, if I enter this string line it returns "6" (why I don't know):
hi hello how are you
What is wrong? my brain stopped and I couldn't determine what is the wrong in my code and/or algorithm.
Please, help me to solve these problems.
Best regards.
capacity() is the currently allocated space not the count of elements in the vector. Use: size() instead
See:
http://en.cppreference.com/w/cpp/container/vector/capacity
http://en.cppreference.com/w/cpp/container/vector/size
Your loop should work fine now, but you can also take a look at the example there which does something similar for integer divisible by 3.
You can count even-length words with std::count_if:
#include <algorithm>
int even_words = std::count_if(v_setir.begin(), v_setir.end(), [] (const string& str) { return str.size() % 2 == 0; });
1) cout << v_setir.capacity(); is not returns the correct number.
Use vector::size as the number of the element in the vector.
2) I want to count of the words which lengths are even. and I should do it with vectors.
Firstly you should use v_setir.size() instead of v_setir.capacity() in your loop as the condition.
And secondly, why not you cout the string to check whether it's length is even or not? Actually you put 5 'hi hello how are you' into the vector.
I think you want to put every single words into the vector, but not the whole sentence. If that use v_setir.push_back(ifadeler); instead of v_setir.push_back(setir);
vector::capacity gives capacity of vector (how much elements it can store). Here, you want to calculate number of strings whose length is even. You need to iterate over the strings and count the strings whose length is even.
std::vector::capacity >= std::vector::size
The capacity is the maximum number of elements the vector can currently hold.
The size is the number of elements in the vector.

C++ Creating a variable sized array from ifstream

Just a heads up: My c++ programming skills and terminology is intermediate at best. So please be gentle ;).
I am working on a multi-sort algorithm for a college class. Originally, I built the program to take in an array of 20 integers, since that was as big as the .txt files were. The final lab is now asking to take in files that have 10, 100, 1000, 10000, 100000 and 1000000 different numbers. I originally used an ifstream inside a for loop to read in the ints. Now that I need to read a variable amount of ints from a file, I have run into issues with this code. I have extensively searched this site and Google to find an answer to this problem. I have tried dozens of different code snippets, to no avail. Here is the code I am currently running that works for 20 ints.
int i;
int A[20];
int length;
char unsortedFilename[200];
ifstream unsorted;
cout << "Please type the full name of the file you would like sorted.\n* ";
cin >> unsortedFilename;
unsorted.open(unsortedFilename);
length = (sizeof(A) / sizeof(*A));
for( i = 0; i < length; i++ )
{
unsorted >> A[i];
cout << A[i] << "\n";
}
insertionSort();
I do have other code mixed in there, but it's error checking, selection of duplicate number removal, etc. I would like it so that code like this would run "i" number of times, where "i" is actually the number of ints in the file. Also, as I mentioned earlier, I will need to input a file that has 1,000,000 numbers in it. I don't believe that an int array will be able to hold that many numbers. Is it going to be as easy as swapping all my ints over to longs?
Thanks for any help you could provide.
As suggested in the comments, use std::vector<int> instead of an array.
Instead of a for loop, use a while loop. Break out of the while loop when there are no numbers to read.
The while loop:
std::vector<int> A;
int item;
while ( unsorted >> item )
{
A.push_back(item);
}
You can sort the std::vector by using std::vector::iterator or simply access the data through the int* returned by A.data().
You can simply read all the numbers into a vector. Then use the vector as you would have used the array.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
int main()
{
std::string unsortedFilename;
std::cout << "Please type the full name of the file you would like sorted.\n";
std::cin >> unsortedFilename;
std::ifstream is(unsortedFilename);
std::istream_iterator<int> start(is), end;
std::vector<int> A(start, end);
std::cout << "Read " << A.size() << " numbers" << std::endl;
}
What you want is a vector.
try this,
int i;
vector<int> A;
int length;
string unsortedFilename;
ifstream unsorted;
cout << "Please type the full name of the file you would like sorted.\n* ";
cin >> unsortedFilename;
unsorted.open(unsortedFilename);
int temp;
for( i = 0; unsorted >> temp; i++ )
{
A.push_back(temp);
cout << A[i] << "\n";
}
insertionSort();
A vector is basically a dynamic array. It automatically grows as more space is needed. That way it doesn't matter if you have 10, 100, or even 100000 items, it'll automatically grow for you.
Also use a string for your file name, some file names are longer than 200 characters.
Good Luck!
will need to input a file that has 1,000,000 numbers in it. I don't believe that an int array will be able to hold that many numbers.
Sure it can. 1 Million ints is ~4Mb of memory, which is a trivial amount. You can even declare it static just as you do now int A[1000000];.
But real problem is that you're assuming a fixed length in your code, rather than determine the length from the input. I guess this is what your assignment is trying to teach you, so I won't show you the solution. But consider using ifstream::eof and make your sort accept the length as an argument...

Getting multiple lines of input in C++

The first line contains an integer n (1 ≤ n ≤ 100). Each of the following n lines contains one word. All the words consist of lowercase Latin letters and possess the lengths of from 1 to 100 characters.
(Source: http://codeforces.com/problemset/problem/71/A)
How would you get input from the user given n? I tried using a while loop but it doesn't work:
#include <iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int i;
while (i<=n) {
cin>>i ;
i++;
}
}
You probably meant to have something like:
#include <iostream>
int main() {
int n;
cin>>n;
int theInputNumbers[n];
for(int i = 0; i<n; ++i) {
cin >> theInputNumbers[i];
}
}
Your loop is really quite far off of what you need. What you wrote is extremely wrong such that I cannot provide advice other than to learn the basics of loops, variables, and input. The assistance you need is beyond the scope of a simple question/answer, you should consider buying a book and working through it cover to cover. Consider reading Programming Principles and Practice Using C++
Here is a working example of something approximating your question's requirements. I leave file input and output as an exercise up to you. I also make use of C++11's front and back std::string members. You would have to access via array index in older versions.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main(){
int totalWords;
cin >> totalWords;
stringstream finalOutput;
for (int i = 0; i < totalWords; ++i){
string word;
cin >> word;
if (word.length() > 10){
finalOutput << word.front() << (word.length() - 2) << word.back();
}else{
finalOutput << word;
}
finalOutput << endl;
}
cout << endl << "_____________" << endl << "Output:" << endl;
cout << finalOutput.str() << endl;
}
With that said, let me give you some advice:
Name your variables meaningfully. "int i" in a for loop like I have above is a common idiom, the "i" stands for index. But typically you want to avoid using i for anything else. Instead of n, call it totalWords or something similar.
Also, ensure all variables are initialized before accessing them. When you first enter your while loop i has no defined value. This means it could contain anything, and, indeed, your program could do anything as it is undefined behavior.
And as an aside: Why are you reading into an integer i in your example? Why are you then incrementing it? What is the purpose of that? If you read in input from the user, they could type 0, then you increment by 1 setting it to 1... The next iteration maybe they'll type -1 and you'll increment it by 1 and set it to 0... Then they could type in 10001451 and you increment by 1 and set it to 10001452... Do you see the problem with the logic here?
It seems like you are trying to use i as a counter for the total number of iterations. If you are doing this, do not also read input into i from the user. That completely undermines the purpose. Use a separate variable as in my example.