Here is what I have to do!
Write a program to perform the following steps.
Allocate memory dynamically to store an array of 10 ints.
Assign each int a random value between 1 and 100.
Copy each of the 10 random ints to a vector of ints.
Print the dynamically allocated array of ints and the vector of ints, each with a width of 5, as shown in the sample output below.
I have trouble with the last point. My code is working perfectly, but I don't know how to set width in vector of ints so it is the same as array of ints.
#include<iostream>
#include<iomanip>
#include<cstdlib>
#include <vector>
#include <algorithm>
#include <iterator>
#include <stdexcept>
using namespace std;
int main(){
const int SIZE = 10;
int *arr = new int[SIZE];
//assign rand numbers between 0 and 100
for (int i = 0; i < SIZE; ++i){
*(arr + i) = rand() % 100+1;
}
//print array
for (int i = 0; i < SIZE; ++i){
cout << setw(5) << *(arr +i) << " ";
}
std::vector<int> integers (arr, arr + 10);
std::ostream_iterator<int> output(cout, " ");
cout << endl;
cout << "Vector integers contain: " << endl;
std::copy(integers.begin(), integers.end(), output);
return 0;
}
Your code works fine as is. cout << setw(5); sets the width just fine. You could also use cout.width(5);.
If you really want to do this with an ostream_iterator, the cleanest way is probably with a small proxy class:
class integer {
int i;
public:
integer(int i) : i(i) {}
friend std::ostream &operator<<(std::ostream &os, integer i) {
return os << std::setw(5) < i.i;
}
};
Then to write them out, use that type as the template parameter to the ostream_iterator:
std::copy(integers.begin(), integers.end(),
std::ostream_iterator<integer>(std::cout, ' '));
This will create a temporary integer object, then write it out using the operator<< for integer, which sets the width. At least in theory, this probably imposes some overhead, but I'd expect (at least with optimization enabled) most compilers will probably see through the subterfuge (so to speak) and eliminate any extra copies and such.
Of course, if the width isn't cast in concrete, you could make integer a template, and supply the width as a template parameter:
template <int N>
class integer {
// ...
return os << std::setw(N) < i.i;
Unless I really needed to use an ostream_iterator, I think I'd use a range-based for loop though:
for (int i : integers)
std::cout << std::setw(5) << i << ' ';
Since the width of a stream is reset to 0 everytime it is used, you can't use a std::ostream_iterator<int> (well, you could by using a custom std::num_get<char> facet which restores the width but that seems a bit radical).
You can print the std::vector<int> like this, however:
std::for_each(integers.begin(), integers.end(),
[](int v){ std::cout << std::setw(5) << v << ' '; });
Related
I've seen that a dynamic 2D array in C++ can be created as follows:
auto arr{ new int[nRows][nCols] };
nRows and nCols are compile-time known and the size of the array will not change during runtime.
I've tested what is the type of arr is PAx_i (where x is nCols). But I cannot figure out what to put instead of auto (if I don't want to use it) to create a dynamic 2D array with a single statement.
So, the question: Is it possible in C++ to specify the type of a dynamic 2D array directly (C-style like)? If yes, how?
C++ does not support dynamically-sized raw arrays (aka Variable Length Arrays, or VLAs). Whenever you come across the need for such a dynamic array (how ever many dimensions it may have), you should be immediately thinking of using the std::vector container.
Once properly created, you can use the [] operator (concatenated, for 2-D vectors) in much the same way as you would with raw arrays.
Here's a short code demo that creates a dynamic, 2-dimensional 'array' of integers, using the std::vector class, and initializes all elements with an especially significant, non-zero value:
#include <iostream>
#include <vector>
int main()
{
size_t nCols, nRows;
std::cout << "Enter nRows and nCols: ";
std::cin >> nRows >> nCols;
if (nCols < 2 || nRows < 2) {
std::cout << "Matrix is too small!\n";
return 1;
}
// The following SINGLE LINE declares and initializes the matrix...
std::vector<std::vector<int>> arr(nRows, std::vector<int>(nCols, 42));
std::cout << "nRows = " << arr.size() << "\n";
std::cout << "nCols = " << arr[0].size() << "\n";
for (auto& row : arr) {
for (auto i : row) {
std::cout << i << " ";
}
std::cout << std::endl;
}
// Demo for how to use the "[][]" operator ...
arr[0][0] = arr[nRows - 1][nCols - 1] = 33; // Change 1st and last
std::cout << "------------\n";
for (auto& row : arr) {
for (auto i : row) {
std::cout << i << " ";
}
std::cout << std::endl;
}
return 0;
}
One of the great benefits of using std::vector over new[] is that you don't have to worry about subsequently calling delete[] – the container class takes care of all memory allocation and deallocation internally.
In C++ try to avoid new/delete unless you have no other choice.
Next up is std::make_unique (or std::make_shared).
For dynamic arrays C++ has 'std::vector'
Like this :
#include <vector>
#include <iostream>
int main()
{
// 2x2 vector
std::vector<std::vector<int>> values{ {0,1},{2,3},{4,5} };
std::cout << values[1][1];
return 0;
}
Thusly, vector of vector, in this case the values are uninitialized.
std::vector<std::vector<int>> arr(nRows,std::vector<int>(nCols));
You can also do this with gcc compiler, but its not per standard, and won't work if nRows or nCols is variable in Visual Studio:
int arr[nRows][nCols];
It's better for you to get comfortable with C++ standard library, as it will open up new worlds for you.
Another way:
int *arr = new int[nRow*nCol];
You can then index into the flat buffer like:
arr[0][1]
I was trying to sort the areas of a circle in an ascending order. First, the user chooses the number of circles, then he should type the coordinates and the area of his circles. In the end the program should output the radius of a circle in an ascending order.But the output of areas is not in an ascending order(It's the same as input). What is my problem?
#include<iostream>
#include <algorithm>
using namespace std;
struct circle {
int 반지름;
int coordinates;
int coordinates2;
};
bool compare(circle a, circle b){
if(a.반지름 < b.반지름)
return 1;
else
return 0;
}
int main()
{
int n = 1;
int* ptr1;
ptr1 = new int;
circle* circle1;
circle1 = new (nothrow) circle[5];
circle1[0].반지름;
circle1[0].coordinates;
circle1[0].coordinates2;
circle1[1].반지름;
circle1[1].coordinates;
circle1[1].coordinates2;
circle1[2].반지름;
circle1[2].coordinates;
circle1[2].coordinates2;
circle1[3].반지름;
circle1[3].coordinates;
circle1[3].coordinates2;
circle1[4].반지름;
circle1[4].coordinates;
circle1[4].coordinates2;
circle1[5].반지름;
circle1[5].coordinates;
circle1[5].coordinates2;
cout << "Enter the number of circles: ";
cin >> *ptr1;
cout << "중심 좌표, 반지름 : " << endl;
for (int i = 0; i < *ptr1; i++) {
cin >> circle1[i].coordinates >> circle1[i].coordinates2 >> circle1[i].반지름;
}
sort(circle1, circle1 + 1, compare);
for (int i = 0; i < *ptr1; i++) {
cout << "The result: " << circle1[i].coordinates << " " << circle1[i].coordinates2 << " " << circle1[i].반지름 << endl;
}
delete[] circle1;
delete ptr1;
return 0;
}
That's not C++, that's a strange and hybrid thing between C and C++... And this is your main problem. You're mixing up things that should not be mixed, not if you don't know PERFECLY what you do - and obviously, it's not the case, otherwise your code should have worked, and it haven't.
Corrected code, in real C++:
#include <iostream> // std::cout & co
#include <algorithm> // std::sort
#include <cstdlib> // std::rand & co
#include <vector> // std::vector
struct circle {
int area ;
int x ;
int y ;
} ;
// For printing a circle easily and not repeat code X times.
// Print as: [area#(x,y)]
std::ostream& operator<<(std::ostream& os, const circle& c) {
os << "[" << c.area << "#(" << c.x << "," << c.y << ")]" ;
return os;
}
int main() {
// Set a constant seed: each run will produce the same result, if needed to debug.
std::srand(1234) ;
// 5 circles declared within a vector, not a C array.
auto circles = std::vector<circle>(5) ;
// Fill the vector.
std::cout << "Original circles:" << std::endl ;
// Use a simpler for syntax.
for ( auto& c: circles ) {
// Random values used. The fixed seed will always give the same values on each run.
c.area = 10 + std::rand() % 50 ;
c.x = std::rand() % 1920 ;
c.y = std::rand() % 1080 ;
// Print the circle.
std::cout << "\t" << c << std::endl ;
}
// Sort the vector, use a lambda expression for the compare operator.
// No need for a "real" function, if it's used only once and only there.
// Compare function returns directly a bool, not an integer.
std::sort(circles.begin(), circles.end(), [](const circle& a, const circle& b) -> bool { return (a.area<b.area) ; });
// Display sorted vector.
std::cout << std::endl << "Sorted circles:" << std::endl ;
for ( const auto& c: circles )
std::cout << "\t" << c << std::endl ;
return 0;
}
Still strange that you use area instead of radius or diameter, but anyway... Area is for a disc, not a circle, but that's mathematical precision at this stage.
First, if you print a structure like circle at least twice, do a stream operator to do it only once. Please note that I send directly the structure to std::cout, after...
Then, I use a C++ container, not a C allocated array. You can still allocate memory for big amount of data, but for this example, that's unneeded.
Then, instead of asking for each values, I use std::rand() to fill them. Easier. Can be used in any language. Refined trick: I initialize the pseudo-random generator to a constant, fixed value, so each time the program is run, it will generate the exact same sequence of pseudo-random numbers - this can vary on each machine / OS / compiler / compiler version but it will be constant on YOUR machine during your tests, and it can be debugged easily.
Please also note that I use a compact form of for that will iterate on the whole circles container, giving me each time a circle& (reference) on each element so that I can modify it - needed for initialization.
Now, the sort itself: from begin() to end() of the container, using a lambda expression to define the compare operator. Please note that I return directly the result of the comparison, which is a bool, and that I don't cast an int to a bool implicitely...
Finally, print the result. Note that this time, I ask for a const auto& reference, to be sure to not modify data by mistake.
Nothing to delete, C++ will take care of that.
An example output, on my machine:
Original circles:
[28#(213,881)]
[18#(16,157)]
[34#(1468,816)]
[14#(745,718)]
[31#(143,818)]
Sorted circles:
[14#(745,718)]
[18#(16,157)]
[28#(213,881)]
[31#(143,818)]
[34#(1468,816)]
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. */
string list[] = {"fiorello", "nonuterine", "asquint", "commodore", "semiprogressive",
"aviculturist", "brayley", "tendentious", "hungriness", "overbulkily",
"subfumigation", "praline", "fiorello", "presurvey", "unjealous",
"brayley", "unimpassionate", "welshman", "dcor", "traducianist"};
int size = sizeof(list);
for (int i = 0; i < size; i++) {
cout << list[i] << endl;
// THIS IS WHERE I REALIZE NOTHING ELSE PRINTS AFTER THIS POINT.
}
cout << endl;
int z = sizeof(list) / sizeof(list[0]);
sort(list, list + z);
for (int y = 0; y < z; y++) {
cout << list[y] << endl;
}
return 0;
}
I don't have a strong background in C++, coming from HTML, CSS etc. so trying to figure this out.
What I'm trying to accomplish is to print out the array, then print out in alphabetical order, then find duplicates and remove and print out again. And lastly, find length of each word in array and print that out.
As mentioned in comments, you are using sizeof incorrectly the first time. A good solution would be to not use it at all, instead use standard library algorithms which will find the size by template deduction:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string list[]={"fiorello","nonuterine","asquint","commodore","semiprogressive","aviculturist","brayley","tendentious","hungriness","overbulkily","subfumigation","praline","fiorello","presurvey","unjealous","brayley","unimpassionate","welshman","dcor","traducianist"};
// Operate on each item in list - don't need to mention count explicitly
for ( auto&& s : list )
cout << s << '\n';
cout << endl;
// Same as sort(list, list+z)
sort( begin(list), end(list) );
for ( auto&& s : list )
cout << s << '\n';
cout << endl;
}
Your comments suggest you plan to remove duplicates but you still want to use a C-style array. So presumably you'll be using a variable for the list count; you can get this by using:
size_t count = distance( begin(list), end(list) );
rather than using the sizeof thing. As well as being less error-prone, this will keep working even if you later change the code to use a container instead of a C-style array.
I have made this code to store the position of each bit 1 entered in a binary sequence. The output of the program is not what it is desired. The output I get for 10100 is 0x7fff9109be00. Here is the code:
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
bitset <5> inpSeq;
int x = 0;
int xorArray[x];
unsigned int i;
cout << "Enter a 5-bit sequence: \n";
cin >> inpSeq;
for ( i = 0; i < inpSeq.size(); i++)
{
if ( inpSeq[i] == 1 )
{
x = x+1;
xorArray[x] = i;
}
}
cout << xorArray << "\n";
}
Update for clarity: What I had in mind was that 'cout << xorArray' will print bit 1's positions.
cout << xorArray << "\n";
This does not print the elements of xorArray; it prints its address.
You must iterate ("loop over") it:
for (auto x : xorArray)
cout << x << ' ';
cout << '\n';
Your other problem is that you're trying to use a variable-length array, which does not exist in C++. Use a vector instead.
Now it gives you your desired output:
#include <iostream>
#include <bitset>
#include <vector>
using namespace std;
int main()
{
bitset<5> inpSeq("10111");
std::vector<int> xorArray;
for (unsigned int i = 0; i < inpSeq.size(); i++) {
if (inpSeq[i] == 1)
xorArray.push_back(i);
}
for (auto x : xorArray)
cout << x << ' ';
cout << '\n';
}
If you're not using C++11 for whatever reason, you can perform that final loop the traditional way:
for (std::vector<int>::const_iterator it = xorArray.begin(),
end = xorArray.end(),
it != end; ++it) {
cout << *it << ' ';
}
Or the naive way:
for (unsigned int i = 0; i < xorArray.size(); i++)
cout << xorArray[i] << ' ';
I am a little unclear on exactly what you are trying to achieve, but I think the following might help.
#include <iostream>
#include <bitset>
#include <list>
using namespace std;
int main() {
bitset<5> inpSeq;
unsigned int i;
list<int> xorList;
cout << "Enter a 5-bit sequence: \n";
cin >> inpSeq;
for (i = 0; i < inpSeq.size(); ++i) {
if (inpSeq[i] == 1) {
xorList.push_back(i);
}
}
for (list<int>::iterator list_iter = xorList.begin();
list_iter != xorList.end(); list_iter++)
{
cout << *list_iter << endl;
}
return 0;
}
The reason why I am using a list is because you mentioned wanting to store the positions of the 1 bit. The list is being used as the container for those positions, in case you need them in another point in the program.
One of the problems with the original code was that you assigned variable 'x' the value 0. When you declared xorArray[x], that meant you were essentially creating an array of length 0. This is incorrect syntax. It looks like you actually were trying to dynamically allocate the size of the array at runtime. That requires a different syntax and usage of pointers. The list allows you to grow the data structure for each 1 bit that you encounter.
Also, you cannot print an array's values by using
cout << xorArray << endl
That will print the memory address of the first element in the array, so, xorArray[0]. Whenever you want to print the values of a data structure such as a list or array, you need to iterate across the structure and print the values one by one. That is the purpose of the second for() loop in the above code.
Lastly, the values stored are in accordance with the 0 index. If you want positions that start with 1, you'll have to use
xorList.push_back(i+1);
Hope this helps!
i'm trying to store some elements that is going to change every time, but i don't know which
way is better and why. I'm thinking about two ways, 1) declaring array of int and loop or
use vector's.
Which way is better and why?
Does declaring array of int have any future memore problems as leak?
the code down below show the two ways i'm talking about:
1)
#include <iostream>
#include <vector>
int main()
{
int x[5];
x[0] = 10;
x[1] = 20;
x[2] = 30;
x[3] = 40;
x[4] = 50;
for(unsigned int i = 0;i<=sizeof(x[5]); i++)
{
std:: cout << "x[" << i << "] = "<< x[i] << std::endl;
}
system("pause");
return 0;
}
2)
#include <iostream>
#include <vector>
int main()
{
std::vector<int> x;
x.push_back(10);
x.push_back(20);
x.push_back(30);
x.push_back(40);
x.push_back(50);
for(unsigned int i = 0;i<=x.size()-1; i++)
{
std:: cout << "x[" << i << "] = "<< x[i] << std::endl;
}
system("pause");
return 0;
}
If this is all you have to do, and your array will always have a size that is known at compile time, then you do not need std::vector.
On the other hand, in C++11 you could use std::array instead of a plain C array (std::array is a zero-overhead, safer and more functional wrapper over a C array):
#include <iostream>
#include <array>
int main()
{
std::array<int, 5> x = { 10, 20, 30, 40, 50 };
for (unsigned int i = 0; i < x.size(); i++)
// ^^^^^^^^
{
std:: cout << "x[" << i << "] = "<< x[i] << std::endl;
}
}
Here is a live example. Notice, that std::array offers a size() member function which you may want to use instead of the sizeof operator.
Moreover, since std::array is a standard sequence container, you could iterate through its element this way:
std::size_t i = 0;
for (auto e : x)
{
std:: cout << "x[" << i++ << "] = "<< e << std::endl;
}
Here is a live example.
If the size is known at compile time, use std::array. If not, use std::vector. In either case, use iterators to look at the elements:
typedef std::array<int> my_container_type;
typedef my_container::iterator iterator;
my_container_type my_container = { whatever };
for (iterator it = my_container.begin(); it != my_container.end(); ++it)
std::cout << "x[" << (it - my_container.begin()) << "] = " << *it << '\n';
By using iterators you greatly reduce the risk of accidentally using a loop limit like sizeof(x[5]), which is nonsense.
Neither is "better". They both address entirely different use cases.
If you know the array size at compile time and are 100% sure it will never change, sure, use a plain old array. It has less overhead, and the compiler can even aid you with static analysis by spotting any attempts to read outside the boundaries.
On the other hand, if you are unsure of the array's side (i.e. you will be reading input from a file or the user), then use the std::vector. It can grow to any size to meet your needs.