#include <algorithm>
#include <iomanip>
#include <iostream>
#include <vector>
#include <conio.h>
using namespace std;
int main()
{
cout << "Enter the numbers: " << endl << "Write eof() when you want to end" << endl;
int x;
vector<int> num;
//enter numbers till eof() is encountered
while (cin >> x) {
num.push_back(x);
}
//sort the vector
sort(num.begin(), num.end());
//get size of the vector
typedef vector<double>::size_type vec_sz;
vec_sz size = num.size();
//loop to print 4 numbers according to size
for (auto i = 0; i < size; i++)
{
cout << num[i];
if (i == size - 1)
break;
i++;
cout << " " << num[i];
if (i == size - 1)
break;
i++;
cout << " " << num[i];
if (i == size - 1)
break;
i++;
cout << " " << num[i];
if (i == size - 1)
break;
cout << endl;
//<< " " << num[i + 1] << " " << num[i + 2] << " " << num[i + 3] <<
}
_getch();
return 0;
}
I want to print 4 numbers at a time of a vector of int's. When I tried to print the vector by doing i+=4 in the for loop, the compiler complained that 'i' was going over the size of the vector and the program crashed.
Right now, what I have is works, but I find it really boring the way it's implemented right now and there must be a nice way to do it.
So my questions are -
1) How can I tidy up the code more?
2) When using a loop, how does the compiler access the memory in which vector contents are stored?
3) How to implement error checking so that the loop variable does not access elements beyond the vector size?
for (int i = 0; i < size; i++)
{
cout << num[i];
if ((i % 4) == 3)
cout << endl;
else
cout << " ";
}
if ((size % 4) != 0)
cout << endl;
One solution could be,
for( int i = 0; i < size; ++i ) {
int nextNumber = i + 1; // Just so you don't mix up the index
if ( ( nextNumber % 4 ) == 0 ) {
std::cout << num[ i ] << std::endl;
}
else {
std::cout << num[ i ] << ' ';
}
}
This allows you to easily change to other sizes by changing only one number. (ie, from 4 to 5, etc )
My entry to this competition is using a free function to your aid:
template <typename RAN_IT>
RAN_IT four_or_last(RAN_IT begin, RAN_IT end){
for (RAN_IT it = begin; it != begin + 4; it++){
if (it == end)
return end;
}
return begin + 4;
}
The loop can then be described as:
for (auto it = num.begin(); it != num.end(); /*inc in inner loop*/) {
for (auto in = it; in != four_or_last(it, num.end()); in++) {
std::cout << *in << " ";
}
it = four_or_last(it, num.end());
std::cout << std::endl;
}
Related
Currently this program will generate 10 random numbers and either sort (from least to greatest), reverse sort, or shuffle them. However, when trying to list the number of comparisons made, the number of comparisons printed out are completely incorrect. For example, it prints that there were 44 comparisons with bubble sort (this is the one that varies every time but is usually around 40), 45 with selection sort, and 9 with insertion sort. For now I'm only running the program with numbersSorted() just to make sure the comparisons work.
How can I print the correct number of comparisons made with each sorting method?
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int count1 = 0; //bubble
int count2 = 0; //selection
int count3 = 0; //insertion
vector<int> numbersSorted(int n);
vector<int> numbersReversed(int n);
vector<int> numbersShuffled(int n);
int main() {
srand(time(0));
numbersSorted(10);
//numbersReversed(10);
//numbersShuffled(10);
return 0;
}
vector<int> numbersSorted(int n)
{
vector <int> v(n);
for (auto &x : v)
x = rand() % 100;
cout << "Original list to be sorted: ";
for (auto x : v)
cout << x << " ";
cout << "\n\n";
// bubble sort
bool swapped = true;
for (int pass = 0; pass <= n - 2 && swapped; ++pass)
{
swapped = false;
for (int i = 0; i <= n - pass - 2; ++i)
{
++count1;
if (v.at(i) > v.at(i + 1))
{
swap(v[i], v[i + 1]);
swapped = true;
}
}
}
cout << "Bubble sort sorted: ";
for (auto x : v)
cout << x << " ";
cout << "\n";
cout << "There were " << count1 << " comparisons with bubble sort.\n" <<
endl;
// selection sort
for (int pass = 0; pass <= n - 2; ++pass)
{
// Find least element remaining in the list starting at index pass
int minIndex = pass;
// i = minIndex + 1, minIndex + 1, ..., n - 1
for (int i = minIndex + 1; i < n; i++)
{
++count2;
if (v[i] < v[minIndex])
{
minIndex = i;
}
// The element at index i is smaller than what I thought was the
min
}
swap(v[pass], v[minIndex]);
}
cout << "Selection sort sorted: ";
for (auto x : v)
cout << x << " ";
cout << "\n";
cout << "There were " << count2 << " comparisons with selection sort.\n" <<
endl;
//insertion sort
for (int pass = 0; pass <= n - 2; ++pass) {
// Take the element at pass+1 and move it to the left until it's in the
// right spot (i.e., as long as it's in the wrong spot).
// for i = pass, pass-1, ..., 0 while L[i] > L[i+1]
++count3;
for (int i = pass; i >= 0 && v[i] > v[i + 1]; --i) {
swap(v[i], v[i + 1]);
}
}
cout << "Insertion sort sorted: ";
for (auto x : v)
cout << x << " ";
cout << "\n";
cout << "There were " << count3 << " comparisons with insertion sort.\n" <<
endl;
//return v;
}
vector<int> numbersReversed(int n)
{
vector <int> v(n);
for (auto &x : v)
x = rand() % 100;
cout << "Original list to be reversed: ";
for (auto x : v)
cout << x << " ";
cout << "\n\n";
// bubble sort
bool swapped = true;
for (int pass = 0; pass <= n - 2 && swapped; ++pass)
{
swapped = false;
for (int i = 0; i <= n - pass - 2; ++i)
{
++count1;
if (v.at(i) > v.at(i + 1))
{
swap(v[i], v[i + 1]);
swapped = true;
}
}
}
//reverse the content of the vector
reverse(v.begin(),v.end());
cout << "Bubble sort reversed: ";
for (auto x : v)
cout << x << " ";
cout << "\n";
cout << "There were " << count1 << " comparisons with bubble sort.\n" <<
endl;
// selection sort
for (int pass = 0; pass <= n - 2; ++pass)
{
// Find least element remaining in the list starting at index pass
int minIndex = pass;
// i = minIndex + 1, minIndex + 1, ..., n - 1
for (int i = minIndex + 1; i < n; i++)
{
++count2;
if (v[i] < v[minIndex])
// The element at index i is smaller than what I thought was the
min
minIndex = i;
}
swap(v[pass], v[minIndex]);
}
reverse(v.begin(),v.end());
cout << "Selection sort reversed: ";
for (auto x : v)
cout << x << " ";
cout << "\n";
cout << "There were " << count2 << " comparisons with selection sort.\n" <<
endl;
// insertion sort
for (int pass = 0; pass <= n - 2; ++pass) {
// Take the element at pass+1 and move it to the left until it's in the
// right spot (i.e., as long as it's in the wrong spot).
// for i = pass, pass-1, ..., 0 while L[i] > L[i+1]
++count3;
for (int i = pass; i >= 0 && v[i] > v[i + 1]; --i) {
swap(v[i], v[i + 1]);
}
}
reverse(v.begin(),v.end());
cout << "Insertion sort reversed: ";
for (auto x : v)
cout << x << " ";
cout << "\n";
cout << "There were " << count3 << " comparisons with insertion sort.\n" <<
endl;
}
vector<int> numbersShuffled(int n)
{
vector<int> v(n);
for (auto &x : v)
{
x = rand() % 100;
++count1;
}
cout << "Numbers Shuffled: ";
for (auto x : v)
cout << x << " ";
cout << "\n";
cout << "There were " << count1 << " comparisons made. " << endl;
}
I want to cout an array as a row vector but when I write:
int main() {
int B[3]={0};
for (int w = 0; w <2; w++) {
cout <<"B="<<" "<< B[w] << " ";
}
cout << endl;
return 0;
}
The output is B=0 B=0
But I want output to be like:
B=(0 0)
For a fixed size array of only I would probably even prefer a oneliner like this, because I can read it at first glance:
cout << "B=(" << B[0] << " " << B[1] << " " << B[2] << ")\n";
For a container B with a dynamic or very high number of elements n, you should probably do something like this:
cout << "B=(";
if(n > 0)
{
cout << B[0];
// note the iteration should start at 1, because we've already printed B[0]!
for(int i=1; i < n; i++)
cout << ", " << B[i]; //I've added a comma here, so you get output like B=(0, 1, 2)
}
cout << ")\n";
This has the advantage, that no matter what number of elements, you don't end up with trailing commas or unwanted whitespace.
I'd reccommend making a generic (template) function for the purpose of printing array/std::vector content anyways - it's really useful for debugging purposes!
int main() {
int B[3] = { 0 };
cout << "B=(";
for (int w = 0; w < 3; w++) {
cout << B[w];
if (w < 2) cout << " ";
}
cout << ")" << endl;
return 0;
}
Output should be now:
B=(0 0 0)
The simplest way to do this is:-
#include<iostream>
using namespace std;
int main()
{
int B[3]={0};
cout << "B=(";
for (int w = 0; w < 3; w++)
{
cout << B[w] << " ";
}
cout << ")" << endl;
return 0;
}
the output will be B= (0 0 0 )
You can try this one if you want:
#include <iostream>
using namespace std;
int main() {
int B[3]={0};
cout << "B=(";
for (int w = 0; w <2; w++) {
cout << B[w];
if(w != 1) cout << " ";
}
cout << ")" << endl;
cout << endl;
return 0;
}
The output is:
B=(0 0)
The line if(w != 1) checks whether you 've reached the last element of the array. In this case the last index is 1, but in general the if statement should be: if(w != n-1) where n is the size of the array.
FizzBuzz program. The user enters numbers separated by a comma. The program reads input and lets the computer know if divisible by 3, 5 or both. When the user enters 15,5,30, the program will only output the first number, 15 and stops there. What am I doing wrong?
void processVector(vector<int> intVector)
{
bool loop;
for (int i = 0; i < intVector.size(); i++)
{
loop = true;
}
}
int main()
{
cout << "Welcome to the FizzBuzz program!" << endl;
cout << "This program will check if the number you enter is divisable by
3, 5, or both." << endl;
cout << "Please enter an array of numbers separated by a comma like so,
5,10,15" << endl;
cin >> userArray;
vector<int> loadVector(string inputString);
istringstream iss(userArray);
vector <int> v;
int i;
while (iss >> i);
{
v.push_back(i);
if (iss.peek() == ',')
iss.ignore();
if (i % 15 == 0)
{
cout << "Number " << i << " - FizzBuzz!" << endl;
}
else if (i % 3 == 0)
{
cout << "Number " << i << " Fizz!" << endl;
}
else if (i % 5 == 0)
{
cout << "Number " << i << " Buzz!" << endl;
}
else
{
cout << "Number entered is not divisable by 3 or 5." << endl;
}
}
system("pause");
}
Here is how I would approach the problem:
#include <iostream>
#include <string>
#include <vector>
int main() {
std::cout << "!!!Hello World!!!" << std::endl; // prints !!!Hello World!!!
std::cout << "Please enter your numbers seperated by a comma (5, 3, 5, 98, 278, 42): ";
std::string userString;
std::getline(std::cin, userString);
std::vector<int> numberV;
size_t j = 0; // beginning of number
for(size_t i = 0; i < userString.size(); i++){
if((userString[i] == ',') || (i == userString.size() -1)){ // could also use strncmp
numberV.push_back(std::stoi(userString.substr(j, i))); // stoi stands for string to int, and .substr(start, end) creates a new string at the start location and ending at the end location
j = i + 1;
}
}
for(size_t n = 0; n < numberV.size(); n++){
std::cout << numberV[n] << std::endl;
}
return(0);
}
This should give you a method to solve the problem (without handling the fizzbuzz part of your program) that I personally find simpler.
The basic form for using functions is:
<return type> <function_name(<inputs)>{
stuff
};
So, a basic function that takes a string and returns a vector (what you are wanting) would be:
std::vector myStringToVector(std::string inputString){
std::vector V;
// your code (see the prior example for one method of doing this)
return(V);
};
It also looks like they want a separate function for outputting your vector values, this could look something like:
void myVectorPrint(std::vector inputVector){
// your code (see prior example for a method of printing out a vector)
};
Thank you #Aaron for the help. Here is the finished code and it works great!
I had to take a little more time researching a few things and trying to understand which order and what to put where in terms of the functions and how to call them. I appreciate all the help as I said I am a noob.
#include "stdafx.h"
#include <iostream>
#include<sstream>
#include<string>
#include<vector>
using namespace std;
vector<int> loadVector(string inputString)
{
stringstream ss(inputString);
vector <int> numberV;
int n;
size_t j = 0; // beginning of number
for (size_t n = 0; n < inputString.size(); n++)
{
if ((inputString[n] == ',') || (n == inputString.size() - 1))
{
numberV.push_back(std::stoi(inputString.substr(j, n)));
j = n + 1;
}
}
return numberV;
}
void processVector(vector<int> intVector)
{
for (int i = 0; i < intVector.size(); i++)
{
int n = intVector.at(i);
if (n % 15 == 0)
{
cout << "Number " << n << " - FizzBuzz!" << endl;
}
else if (n % 3 == 0)
{
cout << "Number " << n << " Fizz!" << endl;
}
else if (n % 5 == 0)
{
cout << "Number " << n << " Buzz!" << endl;
}
else
{
cout << "Number entered is not divisable by 3 or 5." << endl;
}
}
}
int main()
{
cout << "Welcome to the FizzBuzz program." << endl
<< "Please enter an array of numbers separated by comma's (5, 10, 15)"
<< endl;
string inputString;
getline(cin, inputString);
try
{
vector<int> intVector = loadVector(inputString);
processVector(intVector);
}
catch (const exception& e)
{
cout << "Exception caught: '" << e.what() << "'!;" << endl;
}
system("pause");
return 0;
}
I have the users input in a vector of pairs. I am trying to determine the domain by just removing the duplicate x values. Then I need to determine the range by all the unique values of y. I have looked into map. I cant seem to figure it out. This is homework so I would prefer to understand how to do it rather than just a solution. Thanks!
CODE:
#include <iostream>
#include <map>
#include <vector>
using namespace std;
int main() {
vector<pair<int, int> > sample;
vector< vector<int> > relation;
vector< vector<int> > domain;
vector< vector<int> > range;
bool loop = true;
do {
int input;
int input2;
cout << "Enter the first INT in the ordered pair: ";
cin >> input;
cout << "Enter the second INT in the ordered pair: ";
cin >> input2;
if (input != -1 && input2 != -1) {
sample.push_back(make_pair(input, input2));
}
else if (input != -1 && input2 == -1) {
cout << "ERROR, must input 2 INTS for an ordered pair." << endl;
loop = false;
}
else if (input == -1) {
loop = false;
}
} while (loop == true);
map<int, int> s;
int size = sample.size();
for (unsigned i = 0; i < size; ++i) s.insert(sample[i]);
sample.assign(s.begin(), s.end());
cout << "TEST: { ";
for (int i = 0; i < s.size(); i++) {
cout << "(" << s[i].first << "," << s[i].second << ")" << ", ";
}
cout << "}" << endl;
cout << "Relation: { ";
for (int i = 0; i < sample.size(); i++) {
cout << "(" << sample[i].first << "," << sample[i].second << ")" << ", ";
}
cout << "}" << endl;
cout << "Domain: { ";
for (int i = 0; i < sample.size(); i++) {
cout << sample[i].first << ", ";
}
cout << "}" << endl;
cout << "Range: { ";
for (int i = 0; i < sample.size(); i++) {
cout << sample[i].second << ", ";
}
cout << "}" << endl;
return 0;
}
If all you want is the unique values of x and y (without worrying about the relationships between them), you should just be able to use a couple of sets (std::set).
Just create two empty sets, xset and yset then run through all the coordinates in your original vector.
For each coordinate, add the x value to xset and the y value to yset.
Then, when you're done, you have all the unique values in both sets and you can extract the smallest and largest (or all values) from each to give range and domain.
The following code (don't use this verbatim in assignments, you'll almost certainly be pinged for plagiarism) shows how this can be done:
#include <iostream>
#include <utility>
#include <vector>
#include <set>
using namespace std;
typedef pair < int, int > tPII;
typedef vector < tPII > tVPII;
typedef vector < int > tVI;
typedef set < int > tSI;
int main() {
// Test data to use.
tVPII sample;
tPII a ( 1, 2); sample.push_back (a);
tPII b ( 9, 99); sample.push_back (b);
tPII c (314158, 271828); sample.push_back (c);
tPII d ( 1, 77); sample.push_back (d);
tPII e ( 1, 99); sample.push_back (e);
// Place individual coordinates into sets.
cout << "input data:\n";
tSI xset, yset;
for (tVPII::iterator it = sample.begin(); it != sample.end(); ++it) {
cout << " (" << it->first << "," << it->second << ")\n";
xset.insert (it->first);
yset.insert (it->second);
}
// Construct range/domain vectors from sets.
tVI xvals;
tVI yvals;
for (tSI::iterator it = xset.begin(); it != xset.end(); ++it)
xvals.push_back (*it);
for (tSI::iterator it = yset.begin(); it != yset.end(); ++it)
yvals.push_back (*it);
// Output range/domain vectors.
cout << "x values:\n";
for (tVI::iterator it = xvals.begin(); it != xvals.end(); ++it)
cout << " " << *it << "\n";
cout << "y values:\n";
for (tVI::iterator it = yvals.begin(); it != yvals.end(); ++it)
cout << " " << *it << "\n";
}
The output of that shows how the information flows into the set (removing duplicates) and back out into individual vectors for the x and y values:
input data:
(1,2)
(9,99)
(314158,271828)
(1,77)
(1,99)
x values:
1
9
314158
y values:
2
77
99
271828
Keep in mind that this treats x and y values as totally separate. If you don't want to take into the account the y values for coordinates where x already exists, it's a slight modification:
// Place individual coordinates into sets,
// discount coordinates totally if x has already been seen.
cout << "input data:\n";
tSI xset, yset;
for (tVPII::iterator it = sample.begin(); it != sample.end(); ++it) {
cout << " (" << it->first << "," << it->second << ") - ";
if (xset.find (it->first) != xset.end()) {
cout << "duplicate.\n";
} else {
cout << "inserting.\n";
xset.insert (it->first);
yset.insert (it->second);
}
}
The output of that shows the changed behaviour:
input data:
(1,2) - inserting.
(9,99) - inserting.
(314158,271828) - inserting.
(1,77) - duplicate.
(1,99) - duplicate.
x values:
1
9
314158
y values:
2
99
271828
I'm trying to do some of my C++ homework, but I seem to have run into an issue. I need to make it so that the user inputs 8 numbers, and those said 8 get stored in an array. Then, if one of the numbers is greater than 21, to output said number. The code is below, and it's kind of sloppy. Yes, first year C++ learner here :p
#include <iostream>
using namespace std;
int main() {
const int NUM_ELEMENTS = 8; // Number of elements
int userVals[NUM_ELEMENTS]; // User numbers
int i = 0; // Loop index
int sumVal = 0; // For computing sum
int prntSel = 0; // For printing greater than 21
// Prompt user to populate array
cout << "Enter " << NUM_ELEMENTS << " integer values..." << endl;
for (i = 0; i < NUM_ELEMENTS; ++i) {
cin >> userVals[i];
}
for (int i = NUM_ELEMENTS - 1; i > 21; i--)
cout << "Value: " << sumVal << endl;
// Determine sum
sumVal = 0;
for (i = 0; i < NUM_ELEMENTS; ++i) {
sumVal = sumVal + userVals[i];
}
cout << "Sum: " << sumVal << endl;
return 0;
}
Don't reinvent the wheel, use standard algorithms:
std::copy_if(std::begin(userVals), std::end(userVals),
std::ostream_iterator<int>(std::cout, "\n"),
[] (auto x) { return x > 21; });
I improved the rest of your program as well:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
auto constexpr count = 8;
int main() {
std::vector<int> numbers(count);
std::cout << "Enter " << count << " integer values...\n";
std::copy_n(std::istream_iterator<int>(std::cin), numbers.size(), numbers.begin());
std::copy_if(numbers.begin(), numbers.end(),
std::ostream_iterator<int>(std::cout, "\n"),
[] (auto x) { return x > 21; });
auto sum = std::accumulate(numbers.begin(), numbers.end(), 0);
std::cout << "Sum: " << sum << '\n';
return 0;
}
See it live on Coliru!
Ok, I'm going to explain this to you and keep it simple. This loop
`for (int i = NUM_ELEMENTS - 1; i > 21; i--)`
will never execute because in your first iteration you are checking if (NUM_ELEMENTS-1=7)>21. You are then decrementing i so this will take the series (6,5,4,...) and nothing would ever happen here.
If you have to sum the numbers greater than 21, which I presume is what you need then you will have to remove the above loop and modify your second loop to:
for (i = 0; i < NUM_ELEMENTS; i++) {
if(userVals[i]>21)
sumVal = sumVal + userVals[i];
}
This way, you add the numbers in the array that are only greater than 21. The index of userVals is determined by the i variable which also acts as a counter.
You're on the right track. There's just a few things wrong with your approach.
#include <iostream>
#include <stdlib.h>
using namespace std;
int main() {
const int NUM_ELEMENTS = 8;
int userVals[NUM_ELEMENTS];
int i = 0;
int sumVal = 0;
int prntSel = 0;
int size = sizeof(userVals) / sizeof(int); // Get size of your array
// 32/4 = 8 (ints are 4 bytes)
cout << "Enter " << NUM_ELEMENTS << " integer values..." << endl;
for (i = 0; i < NUM_ELEMENTS; ++i) {
cin >> userVals[i];
}
for(int i = 0; i < size; i++) {
if(userVals[i] > 21) { // Is number > 21?
cout << userVals[i] << endl; // If so, print said number
exit(0); // And exit
}
else
sumVal += userVals[i]; // Else sum your values
}
cout << "Sum: " << sumVal << endl;
return 0;
}
#include <iostream>
using namespace std;
int main() {
const int NUM_ELEMENTS = 8; // Number of elements
int userVals[NUM_ELEMENTS]; // User numbers
int i = 0; // Loop index
int sumVal = 0; // For computing sum
int prntSel = 0; // For printing greater than 21
// Prompt user to populate array
cout << "Enter " << NUM_ELEMENTS << " integer values..." << endl;
for (i = 0; i < NUM_ELEMENTS; ++i) {
cin >> userVals[i];
}
// for (int i = NUM_ELEMENTS - 1; i > 21; i--)
// cout << "Value: " << sumVal << endl;
for( i = 0; i < NUM_ELEMENTS; ++i )
{
if( userVals[ i ] > 21 )
{
cout << "Value: " << i << " is " << userVals[ i ] << endl;
}
}
for (i = 0; i < NUM_ELEMENTS; ++i) {
sumVal = sumVal + userVals[i];
}
cout << "Sum: " << sumVal << endl;
return 0;
}
Try
for (int i = NUM_ELEMENTS - 1; i > 21; i--)
cout << "Value: " << sumVal << endl;
to
for (i = 0; i < NUM_ELEMENTS; ++i) {
if(userVals[i] > 21)
cout << "Value: " << userVals[i] << endl;
}
This line isnt needed as well, as you arent using it.
int prntSel = 0; // For printing greater than 21
for (int i = NUM_ELEMENTS - 1; i > 21; i--)
cout << "Value: " << sumVal << endl;
Here you are printing the value of sumVal, not the value of the array in the position i. The line should be:
cout << "Value: " << usersVals[i] << endl;
Also that that your for is not doing what you think it does. for doesn't use the condition you gave to decide if will execute the current iteration or not, it uses the condition to decide if the loop should continue or not. So when you put i > 21, means that it will continue running while i is bigger than 21. To achieve your goal, you should make a test (if statement) inside the loop.
The final result it would be:
for (i = 0; i < NUM_ELEMENTS; ++i) {
if (usersVals[i] > 21) {
cout << "Value: " << usersVals[i] << endl;
}
}