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.
Related
Why doesn't this simple function output all permutations of the inputted 5 letter string? I think there should be 120 and it only outputs 90.
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
// Creates permutation lists for strings
vector<string> createdcombos2(string letters)
{
vector<string> lettercombos;
cout << "Letters are: " << letters << endl; //input string
do
lettercombos.push_back(letters);
while(next_permutation(letters.begin(), letters.end()));
cout <<"Letter combos: " << endl; //print out permutations
for (auto i : lettercombos)
cout << i << endl;
cout << endl << lettercombos.size() << endl; //number of permutations
return lettercombos;
}
int main()
{
string letters = "gnary";
vector<string> lettercombos;
lettercombos = createdcombos2(letters);
}
To return all permutations in a loop until next_permutation returns false, the vector must be sorted before the start of the loop. next_permutation returns the permutations in ascending order. So if you start off with an unsorted vector, it will begin part way through the series of permutations.
std::sort(letters.begin(), letters.end());
do
lettercombos.push_back(letters);
while(next_permutation(letters.begin(), letters.end()));
You need to sort the input, next_permutation will return the next permutation in lexicographical order. Because the input permutation: "gnary" is lexicographically "larger" than a permutation such as "angry", those "smaller" permutations will never be reached.
You can sort the string using std::sort()
As some of the previously made answers state, if you want to use the bool return value of std::next_permutation to stop the iterations, you have to make sure that you start from a "sorted" permutation. Otherwise, your cycle will terminate prematurely.
This is not absolutely necessary though.
Permutations enumerated through std::next_permutation form a cyclic sequence without a beginning or an end, which means that you can call std::next_permutation indefinitely and it will cycle through the same sequence of 120 permutations again, again and again. This means that you can start from absolutely any permutation in that cycle. You just have to remember your starting permutation and watch for the moment this permutation appears again. The very moment you arrive at your original permutation the iteration is over. In your case it will expectedly take 120 calls to std::next_permutation.
For example, the following code prints all 5-letter permutations for "abcde" set even though it starts from a completely arbitrary one
std::string start = "cadeb", current = start;
do
std::cout << current << std::endl;
while (std::next_permutation(current.begin(), current.end()), current != start);
One can note though that comparing permutations at each iteration of the cycle is more expensive than using the return value of std::next_permutation (which comes "for free" from the innards of the algorithm), so if you are happy with the solution that pre-sorts the starting permutation, then it is indeed a more efficient way to do it.
Alternatively, if you know the exact number of permutations in the cycle (120 in this case), you can simply call std::next_permutation exactly that number of times (as suggested in #Potatoswatter's answer).
The return bool value of next_permutation is like an overflow condition or a carry bit. It's false when it advances from the last permutation back to the first, in lexicographical order. But it still does advance, unconditionally.
If you know there are exactly 120 permutations, you can ignore the return value and just loop blindly:
for ( int i = 0; i != 120; ++ i ) {
lettercombos.push_back(letters);
next_permutation(letters.begin(), letters.end());
}
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
I have the below piece of code and I'm very confused by it. I'm trying to figure out how much memory (bytes of memory/space is actually being taken up by my partially filled array). I've got the below piece of code but I'm a bit confused.
If I declare a string array of 8 elements, and partially fill the elements with the two strings. The for loop will start at 0 and go until size of my array 32 possible bytes (assuming I need 4 bytes per string) divided by size of the first element in the array. That is returns 4 - the size of the element of the first string in the array. But that still doesn't tell me how many letters/characters are in that string.
I understand inside the loop we increment count when the value in the array doesn't equal a blank/null value. Giving us the total filled (non empty) positions in our array. However I still don't have a value for our actual amount of characters.
How does this tell us how many characters are in my strings?
#include <iostream>
#include <string>
using namespace std;
int main()
{
string test_array[8] = {"henry", "henry2"};
size_t count = 0;
for (size_t i = 0; i < sizeof(test_array)/sizeof(*test_array); i++)
{
cout << "NOT THE POINTER: "<<sizeof(test_array) << endl;
cout << "POINTER: "<<sizeof(*test_array) << endl;
if(test_array[i] != "")
count ++;
}
int num_elem = sizeof(test_array)/sizeof(test_array[0]);
cout << num_elem << endl;
cout << count << endl;
return 0;
}
To know how many characters are in a std::string use the size() method.
Hey I currently have this code. It gets the user to input strings into an array, with a limit of 5. I plan to use the array to then form words from the array. How can I achieve this?
const int row = 5;
char array[row];
char count = 0;
char letter;
while (count < 5)
{
cout << "Enter a letter: ";
cin >> letter;
array[count] = letter;
count++;
}
cout << "Letter inputed" << endl;
for (count = 0; count < 5; count++)
{
cout << array[count] << " " << endl;
}
system("pause");
Here's a hint to get you started on the right track: don't even consider using std::next_permutation unless this is something you'll only ever use once or twice (and probably not even then, because it's actually more complicated than doing the job right).
Using std::next_permutation, your function will be approximately N! times slower than necessary1 -- in the case of 5 letters, that'll be 120 times slower, and if you ever use longer words, it'll get worse very quickly (e.g., for 10 letters it's over 3.5 million).
Instead, start by pre-processing your dictionary. Instead of a std::set<std::string> of words, create an std::map<std::string, std::vector<string>> (or std::unordered_map, though English has few enough words that this probably won't make a huge difference). As you read in a word from the dictionary, create a sorted version of that string. Use that as the key, and push the original version of the word onto the vector for that key.
Then when you get a word from the user, sort it, look that up in the map, and the associated vector will contain every word (from your dictionary) that can be created from those letters.
1. If you use std::map instead of std::unordered_map, that should be something like N!/(log N), but N! grows so fast and log N grows so slowly that it the difference is negligible (if you get N large enough that log N = 3, N! will be so large that N!/log N computation steps...well, you start to get into questions of cosmology, like whether the universe will have died of heat death before then (to which the answer seems to be "yes, probably").
Here's a hint to get you started. There's a function in the standard library called std::next_permutation. Assuming you have a dictionary of words to check against, a possible solution could look like this:
std::sort(array, array + row);
do {
// Check if array is a word.
} while (std::next_permutation(array, array + row));
This will cycle through every permutation of letters. It's now up to you to verify that it is a valid word.
This solution uses an associative array to map from sorted letters of the word to the words having such sorted letters. It's thus possible to get an answer with one lookup in the map, which takes asymptotically O(log N) time, where N is a size of your dictionary.
Create a file named dic.txt. In case you're using Visual Studio it should be in the same directory as your *.cpp files. Put several words inside in a "word in a row" format. Try the following code:
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <fstream>
#include <algorithm>
using namespace std;
int main() {
// Dictionary file is in a "word in a row" format
map< string, vector<string> > dictionary;
ifstream dictionary_file("dic.txt");
if (!dictionary_file.good()) {
cout << "File doesn't exist" << endl;
return 0;
}
string word;
while (dictionary_file >> word) {
string key = word;
sort(key.begin(), key.end());
dictionary[key].push_back(word);
}
// Read the letters
string letters;
cin >> letters;
if (letters.size() > 5) {
cout << "Too much letters" << endl;
return 0;
}
// Sort the letters
sort(letters.begin(), letters.end());
// Output the answers
vector<string> & ret = dictionary[letters];
for (size_t i = 0, ilen = ret.size(); i < ilen; ++i) {
cout << ret[i] << endl;
}
}
Mention that such a solution cares for a case your letters are in. In case you don't need it, you can add calls to strtolower function (got that name from PHP) before you add a word to your dictionary and before you sort your letters.
string strtolowers(string const & word) {
string ret = word;
transform(ret.begin(), ret.end(), ret.begin(), tolower);
return ret;
}
You'll need to add <cctype> header for this function to work.
I'm fairly new to c++ programming and I need help with the coding to sort the numbers from a text file into ascending order so I can take the median of it, but I'm not sure how to do that.
Here is my code so far:
//Create a Vector to hold a set of exam scores.Write a program to do the following tasks: 1. Read exam scores into a vector from Scores.txt
//2. Display scores in rows of five(5) scores.
//3. Calculate average score and display.
//4. Find the median score and display.
//5. Compute the Standard Deviation and display
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
int main ()
{ const int array_size = 36; // array size
int numbers[array_size]; //array with 36 elements
int count = 0;
int column_count = 5;
ifstream inputfile; //input file into stream object
//open file
inputfile.open("Scores.txt");
//read file
while (count < array_size && inputfile >> numbers[count])
count++;
//close file
inputfile.close();
//display numbers read
for (count = 0; count < array_size; count++) {
cout << numbers[count] << " ";
if ( count % column_count == column_count - 1 ) {
cout << "\n";
}
}
//find the average
double average; //average
double total = 0; //initialize accumulator
cout << "\nAverage:\n";
for (count = 0; count < array_size; count++)
total += numbers[count];
average = total/array_size;
cout << average << " ";
cout << endl;
//find the median
std::sort(numbers.begin(), numbers.end(), std::greater<int>());
system ("pause");
return 0;
}
Thanks in advance!
You probably copied this line from somewhere without understanding what it really means:
std::sort(numbers.begin(), numbers.end(), std::greater<int>());
Since you are using regular arrays, the first argument is a pointer to the first position in the array. The second argument is a pointer to one past the last element in the array. The third argument indicates in which direction the array should be sorted (in your case, you want to find the median, so the direction doesn't matter). For your array called numbers with a length of array_size, the new function call is rewritten as:
std::sort(&(numbers[0]), &(numbers[array_size]), std::greater<int>());
When passing arrays to functions, they decay into pointers on their own. So, you don't need to use the & operator. The function call can be simplified to:
std::sort(numbers, numbers + array_size, std::greater<int>());
The purpose for sorting the data in this situtation is to find the median. Regardless of sorting the array ascending or descending, the average of the middle element(s) will be the same. If you had further use for the array where it needs to be sorted in ascending order, change the third argument to std::less<int>() (or remove it completely). It will cause the array to be sorted in ascending order.
std::sort(numbers, numbers + array_size);
#include <algorithm>
// ...
std::sort( numbers, numbers + array_size );
For std::sort(...) function please refer to http://www.cplusplus.com/reference/algorithm/sort/.
For your question, you are dealing with built-in type. The first overloaded version of std::sort which does not take an "Compare" parameter will suffice. And if you don't I think, you need to specify 'less' instead of "greater"