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 3 years ago.
Improve this question
When I run the code I get all those numbers as outputs which means that my while loop seems to be going over elements that it should not got over. Why is this happening ?
For context I am currently learning C++ with a tour of C++ and I am very confused with pointer and references.
This is where I got the code:
Buggy code in "A Tour of C++" or non-compliant compiler?
int counter(int* arr,int c){
int counter = 0;
while(*arr){
cout << *arr<<"\n";
if(*arr == c){
++counter;
}
++arr;
}
return counter;
}
int main()
{
int arr[3] = {1,2,3};
int count = counter(arr,1);
cout<< count;
}
Example run:
/Users/benediktschesch/CLionProjects/untitled/cmake-build-debug/untitled
1
2
3
-945684358
-1153026697
-280532248
32766
1839025881
32767
1839025881
32767
1
Process finished with exit code 0
This is very similar to not providing a null terminator for a character array that will be used as a string.
while(*arr)
means stop when you find a zero.
int arr[3] = {1,2,3};
provides no zero, therefore you have no control over when the loop will stop.
TL;DR Solution:
Use a Library container. std::vector or std::array would be a good fit here, as would std::count from the <algorithm> library and std::begin and std::end from the <iterator> library.
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
int arr[] = { 1, 2, 3 };
int count = std::count(std::begin(arr), std::end(arr), 1);
std:: cout << count;
}
Explanation:
You could provide a zero
int arr[] = {1,2,3,0};
Note I remove the explicit array size. It's not needed because the compiler knows from the number of elements in the initialzer.
Note also that this will stop upon reaching the first zero, so
int arr[] = {1,2,3,0,1,2,3,0};
will only spot one 1. This makes zero a very poor value to use to terminate a list of integers unless 0 is guaranteed to not be in the input.
To scan the whole array and only the array, the size of the array needs to be provided. This can be done by passing in a size parameter
int counter(int* arr, size_t len, int c)
{
int counter = 0;
while (len--)
{
std::cout << *arr << "\n";
if (*arr == c)
{
++counter;
}
++arr;
}
return counter;
}
int main()
{
int arr[3] = { 1, 2, 3 };
int count = counter(arr, std::size(arr), 1);
std:: cout << count;
}
but the preferred solution in Modern C++ would be to use a container in place of the array. Containers know their size and offer up a wide variety of other tools to make writing code easier and less error-prone.
#include <iostream>
#include <vector>
int counter(const std::vector<int> & arr, int c)
{
int counter = 0;
for (const auto & val: arr)
{
std::cout << val << "\n";
if (val == c)
{
++counter;
}
}
return counter;
}
int main()
{
std::vector<int> arr = { 1, 2, 3 };
int count = counter(arr, 1);
std:: cout << count;
}
Note the use of a range-based for loop to simplify the code. const auto & val deduces the type of val from the contents of arr with auto. The value is not going to be changed as a result of the loop so we declare it const to prevent accidents and make it a reference because maybe the compiler can pull off some extra optimization voodoo. In addition you can keep reusing this exact statement without having to change a thing if the container or the type of data in the container is ever changed. This prevents mistakes later when maintaining the code.
You could also use std::array and make counter a templated function that detects the size of the std::array here, but that's a bit much at this point.
The next evolution takes advantage of the <algorithm> library.
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> arr = { 1, 2, 3 };
int count = std::count(arr.begin(), arr.end(), 1);
std:: cout << count;
}
In this case Iterators are being used rather than specifying lengths. This lets you easily scan subsets of a container.
This allows us to go back to using a vanilla array by taking advantage of std::begin and std::end to turn the array into a pair of iterators :
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
int arr[] = { 1, 2, 3 };
int count = std::count(std::begin(arr), std::end(arr), 1);
std:: cout << count;
}
And that brings us around to the TL;DR solution.
I recommend to use std::array and range based for loops
#include <array>
#include <iostream>
int counter(const std::array<int, 3> &arr, int c){
int counter = 0;
for (auto const a : arr) {
std::cout << a << "\n";
if(a == c){
++counter;
}
}
return counter;
}
int main()
{
std::array<int, 3> arr = {1,2,3};
int count = counter(arr,1);
std::cout << count;
}
The reason for your problem is that in the line
while(*arr){
the statement
*arr
is evaluated as boolean. It is false for *arr == 0 and true in any other case. In your code you need to get the size of the array or a last element with value 0. There are different ways. You can add a last element with 0 or you can pass the size to the function. But C++ standard provides stl containers that solve your problem without overhead. std::array is such a container that contains the data and the size of your array. It is a template class so that there is no extra data needed for the size. First you should learn how to use the tools that a language provides like stl containers and algorithms. Later you can learn how to use low level functions and data types.
Except character arrays that contain strings all other arrays (if you do not use intentionally a sentinel value) do not contain a zero element that signals the end of an array. So your function can invoke undefined behavior if the array does not contain an element equal to 0 (as in your case).
So in general your function should have one more parameter that specifies the number of elements in the array and should look like
size_t counter( const int *arr, size_t n, int value )
{
size_t count = 0;
for ( const int *p = arr; p != arr + n; ++p )
{
if ( *p == value ) ++count;
}
return count;
}
and called like
int main()
{
int arr[] = { 1, 2, 3 };
const size_t N = sizeof( arr ) / sizeof( *arr );
size_t count = counter( arr, N, 1 );
std::cout << count << '\n';
}
If your compiler supports C++ 17 then instead of the expression sizeof( arr ) / sizeof( *arr ) you can include standard function std::size() declared in the header <iterator> like std::size( arr ).
Otherwise instead of the expression sizeof( arr ) / sizeof( *arr ) you could use expression
std::extent<decltype( arr )>::value
provided that the header <type_traits> is included.
Take into account that there is standard algorithm std::count declared in header <algorithm> that performs the same task. Here is a demonstrative program
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
int arr[] = { 1, 2, 3 };
auto count = std::count( std::begin( arr ), std::end( arr ), 1 );
std::cout << count << '\n';
}
Related
I am trying to get the size of an array, using that for the expression in my for loop, and getting a random sum when I compile.
#include <iostream>
int main()
{
int prime[5];
prime[0] = 2;
prime[1] = 3;
prime[2] = 5;
prime[3] = 7;
prime[4] = 11;
int holder = 0;
for (int i = 0; i < sizeof(prime); i++)
{
holder += prime[i];
}
std::cout << "The sum of the 5 prime numbers in the array is " << holder << std::endl;
}
The sum I get is 1947761361. Why is this? Shouldn't using the sizeof() function work here?
The sizeof operator returns the size in memory of its operand - in the case of arrays this is thus the number of element multiplied by the size in memory of each one - NOT the number of elements in the array. For that you want sizeof(array)/sizeof(prime[0])
#include <iostream>
int main()
{
int prime[5];
prime[0] = 2;
prime[1] = 3;
prime[2] = 5;
prime[3] = 7;
prime[4] = 11;
int holder = 0;
int arraySize = sizeof(prime)/sizeof(prime[0]);
for (int i = 0; i < arraySize; i++)
{
holder += prime[i];
}
std::cout << "The sum of the 5 prime numbers in the array is " << holder << std::endl;
}
The error is in your use of sizeof(). It returns the total size of what is passed in. You passed in an array of 5 integers. An int is typically 4 bytes, so your sizeof() should return 20.
The bare minimum fix is to change your for loop Boolean Expression:
i < sizeof(prime) becomes i < sizeof(prime) / sizeof(*prime)
It takes the total size of your array (20) and divides it by the size of the first element (*prime) to give you the number of elements in your array.
To explain a bit more about *prime, you need to understand that C-arrays decay to pointers to the first element if you look at them funny. The syntax here de-references the pointer and gives us the actual first element, an int. And so we get the size of an int.
All the stuff below is tangential to your actual question, but I like to put it out there.
Here's your code, squashing your array initialization and using a range-based for loop.
#include <iostream>
int main()
{
int prime[]{2, 3, 5, 7, 11}; // CHANGED: Declare and initialize
int holder = 0;
// CHANGED: Range-based for loop
for (auto i : prime) {
holder += i; // CHANGED: in a range-based for loop, i is the value of each
// element
}
std::cout << "The sum of the 5 prime numbers in the array is " << holder
<< std::endl;
}
The range-based for loop works here because the array is in the same scope as the array. If you were passing the C-array to a function, it wouldn't work.
Here's your code using a Standard Library function:
#include <iostream>
#include <iterator> // std::begin and std::end because C-array
#include <numeric> // std::reduce OR std::accumulate
int main() {
int prime[]{2, 3, 5, 7, 11};
std::cout << "The sum of the 5 prime numbers in the array is "
<< std::reduce(std::begin(prime), std::end(prime)) << std::endl;
}
The need for <iterator> is due to the fact that you are using a C-array. If we instead use a std::array or [better yet] std::vector, we can lose that requirement.
#include <iostream>
#include <numeric> // std::reduce
#include <vector>
int main() {
std::vector<int> prime{2, 3, 5, 7, 11};
std::cout << "The sum of the 5 prime numbers in the array is "
<< std::reduce(prime.begin(), prime.end()) << std::endl;
}
We got rid of the #include <iterator> requirement because std::arrays and std::vectors come with their own iterators. I also got rid of the holder variable completely, as there was no demonstrated need to actually store the value; so we print it directly.
NOTES: std::reduce() requires C++17, which any fairly recent compiler should provide. You could also use std::accumulate() if you wish.
You can specify that you're compiling C++17 code by passing -std=c++17 to the compiler. It's always a good idea to specify what C++ standard you expect your code to run against. And while we're talking about compiler flags, it's in your best interest to enable warnings with -Wall -Wextra at a minimum.
You expect sizeof(prime) == 5,
which will not be.
And int prime[5]; will always should
be known size, so
to avoid problems
use int const sizeOfArray = 5; which then
you can use for the loop.
And for better understanding of what is happening
monitor holder inside the loop with cout/cerr.
I need a function int countDifferentNumbers(int v[], int n) which counts how many different values the array v with n entries contains.
Example:
It should return the result 3 for the array v = {1, 5, 5, 8, 1, 1} because the array contains only 3 different values.
This is how the code looks like so far:
int countDifferentNumbers(int v[], int n)
{
int counter = 0;
for(int i = 0; i < n; ++i)
{
for(int j = i; j < n; ++j)
{
if(v[i] == v[j + 1])
{
cout << "match" << endl;
counter++;
cout << v[i] << endl;
}
}
}
return counter;
}
I would appreciate an explanation of what is wrong in my function and how I need to redesign it.
Note: Unfortunately, I have not found a suitable thread for this either. All threads with my problems were solved in Java and Python languages.
Recently I see more and more answers here on SO that lead users in the wrong direction by giving bad answers.
Also, for C++, the question has already been answered in the comment by Igor Tandetnik, and that should finally be used.
But let me answer the question of the OP as asked. What is wrong with my function? OK, there are several aspects. Let us first look at the style.
You have 0 lines of comments, so the code quality is 0. If you would write comments, then you would already find most bugs by yourself, because then, you need to explain your own wrong statements.
Then please see your source code with my amendments. I added the problems as comment.
// This is just a dumped function and not a minimum reproducible example
// All header files are messing
// Obviously "using namespace std;" was used that should NEVER be done
// The function should retrun an unsigned value, best size_t, because a count can never be negative
// Same for n, that is the size of an array. Can also never be negative
// C-sytle arrays should NEVER be used in C++. NEVER. Use std::vector or std::array instead
int countDifferentNumbers(int v[], int n)
{
int counter = 0; // Now in C++ we can use braced initialzation instead of assignement
for (int i = 0; i < n; ++i)
{
for (int j = i; j < n; ++j)
{
if (v[i] == v[j + 1]) // Accessing out of bounds element
{
cout << "match" << endl; // Now endl needed here. Can all be done in one cout statement in one line
counter++; // Always counting up the same counter for all kind of double numbers.
cout << v[i] << endl;
}
}
}
return counter;
That was one point of the answer. But now the second point. Evene more important. The algorithm or the design is wrong. And finding the correct solution, this thinking before codingt, you need to do, before you write any line of code.
You obviously want to find the count of unique numbers in an array.
Then you could look what is already there on Stackoverflow. You would probaly find 20 answers already that coud give you a hint.
You could use std::unique. Please see here for a description. This function sounds like it does what you want, right? Some example implementation:
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>
// If you want to keep the original data, remove the reference-specifier &
size_t countDifferentNumbers(std::vector<int>& v) {
std::sort(v.begin(), v.end()); // Sorting is precondition for std::unique
v.erase(std::unique(v.begin(), v.end()), v.end()); // Erase all non-unique elements
return v.size(); // Return the result
}
int main() {
std::vector test{ 1, 5, 5, 8, 1, 1 }; // Some test data
std::cout << countDifferentNumbers(test) << '\n'; // SHow result to user
return 0;
}
Then, we could count the occurence of each number in a std::map or std::unordered_map. And the number of counters will be the result. Example:
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>
// If you want to keep the original data, remove the reference-specifier &
size_t countDifferentNumbers(std::vector<int>& v) {
std::unordered_map<int, size_t> counter{}; // Here we will count all occurences of different numbers
for (const int i : v) counter[i]++; // Iterate over vector and count different numbers
return counter.size(); // Count of different numbers
}
int main() {
std::vector test{ 1, 5, 5, 8, 1, 1 }; // Some test data
std::cout << countDifferentNumbers(test) << '\n'; // Show result to user
return 0;
}
But, then, thinking further, about what conatiners we could use, we will find out the answer from Igor Tandetnik. There are 2 containers that can hold unique values only. No double values. And these are: std::set and std::unordered_set., So, we can simply copy the data into one of those containers, and, only unique values will be stored there.
There are many ways to get the data into a set. But the simplest one is to use its range constructor. Then, we have unique elements, and, the containers size function will give the result:
See here: Constructor Number 2.
The result will be a function with one line like this
#include <iostream>
#include <unordered_set>
#include <vector>
// If you want to keep the original data, remove the reference-specifier &
size_t countDifferentNumbers(std::vector<int>& v) {
return std::unordered_set<int>(v.begin(), v.end()).size();
}
int main() {
std::vector test{ 1, 5, 5, 8, 1, 1 }; // Some test data
std::cout << countDifferentNumbers(test) << '\n'; // Show result to user
return 0;
}
And since functions with one line are often not so usefull, we can also write the final solution:
#include <iostream>
#include <unordered_set>
#include <vector>
int main() {
std::vector test{ 1, 5, 5, 8, 1, 1 }; // Some test data
std::cout << std::unordered_set<int>(test.begin(), test.end()).size() << '\n'; // Show result to user
return 0;
}
So, by analyzing the problem and choosing the right algorithm and container and using C++, we come to the most easy solution.
Please enable C++17 for your compiler.
first sort the array v. if n >0 then initially there must be one number which is unique so just increment the value of counter once. then with loop check if the two consecutive number are same or not. if same do nothing else increment the value of counter.
if you are writing code in c then use qsort. #include <stdlib.h> add this in header and. use qsort() func
here is the code:
#include <bits/stdc++.h>
using namespace std;
int countDifferentNumbers(int v[] , int n)
{
int counter = 0;
sort(v, v+ n); // if you are writing code in c then just write a decent sort algorithm.
if (n>0 ){
printf("%d\n", v[0]);
counter ++;
}
for(int i = 0; i < n-1; ++i)
{
if(v[i] == v[i+1]){
continue;
} else {
printf("%d\n", v[i+1]);
counter++;
}
}
return counter;
}
int main()
{
int v[] = {1, 5, 5, 8, 1, 1};
int result = countDifferentNumbers(v,6);
printf("unique number %d", result );
return 0;
}
for example,
int func(int len){
int arr[len];
}
this doesn't compile. with the error
expression did not evaluate to a constant.
so, how can i initialize an array in such a way?
In fact the function deals with a variable length array. The C++ Standard does not allow to use variable length arrays though some compilers have their own language extensions that support variable length arrays.
So in any case you have to allocate the array dynamically/. Either you can do this using the operator new as it is shown in the demonstrative program below
#include <iostream>
#include <memory>
#include <numeric>
void func( size_t n )
{
std::unique_ptr<int[]>a( new ( std::nothrow ) int[n] );
if ( a )
{
std::iota( a.get(), a.get() + n, 0 );
for ( size_t i = 0; i < n; i++ ) std::cout << a[i] << ' ';
std::cout << '\n';
}
}
int main()
{
func( 10 );
return 0;
}
The program output is
0 1 2 3 4 5 6 7 8 9
Or you can use the standard container std::vector that itself allocates dynamically memory.
#include <iostream>
#include <vector>
#include <iterator>
#include <numeric>
void func( size_t n )
{
std::vector<int> v( n );
std::iota( std::begin( v ), std::end( v ), 0 );
for ( const auto &item : v ) std::cout << item << ' ';
std::cout << '\n';
}
int main()
{
func( 10 );
return 0;
}
The program output is the same as shown above.
Because your variable given could be dynamic I would use a vector:
#include <vector>
int func(const int len){
std::vector<int> arr(len);
}
if you want to avoid std::vector, you would use const (not required, but in the control structure you would not change the value):
int func(const int len){
int arr[len];
}
It least my compiler g++ 9.2 accepts that, but only if the feature Variable Length Array (VLA) is enabled. That is not part of the C++ standard though.
Static arrays like arr[] must have known length at compile time. You need to dynamically allocate, so use:
Int* arr = new int[len];
Basically, u need to allocate the array dynamically, therefore u can use new or malloc, in this case,
int fun(int len)
{
int *ar;
ar=new int [len];
for(int i=0;i<len;i++)
{
cin>>ar[i];
}
}
Now its all upto you what you want from your code now .
remmber if u are using malloc include header file in c or c++
How do I iterate through a list of numbers, and how many different ways are there to do it?
What I thought would work:
#include <cstdlib>
#include <iostream>
#include <list>
using namespace std;
int main()
{
int numbers[] = {2, 4, 6, 8};
int i = 0;
for(i=0; i< numbers.size();i++)
cout << "the current number is " << numbers[i];
system("pause");
return 0;
}
I get an error on the for loop line:
request for member 'size' in 'numbers', which is of non-class type 'int[4]'
Unlike a lot of modern languages plain C++ arrays don't have a .size() function. You have a number of options to iterate through a list depending on the storage type.
Some common options for storage include:
// used for fixed size storage. Requires #include <array>
std::array<type, size> collection;
// used for dynamic sized storage. Requires #include <vector>
std::vector<type> collection;
// Dynamic storage. In general: slower iteration, faster insert
// Requires #include <list>
std::list<type> collection;
// Old style C arrays
int myarray[size];
Your options for iteration will depend on the type you're using. If you're using a plain old C array you can either store the size somewhere else or calculate the size of the array based on the size of it's types. Calculating the size of an array has a number of drawbacks outlined in this answer by DevSolar
// Store the value as a constant
int oldschool[10];
for(int i = 0; i < 10; ++i) {
oldschool[i]; // Get
oldschool[i] = 5; // Set
}
// Calculate the size of the array
int size = sizeof(oldschool)/sizeof(int);
for(int i = 0; i < size; ++i) {
oldschool[i]; // Get
oldschool[i] = 5; // Set
}
If you're using any type that provides a .begin() and .end() function you can use those to get an iterator which is considered good style in C++ compared to index based iteration:
// Could also be an array, list, or anything with begin()/end()
std::vector<int> newschool;
// Regular iterator, non-C++11
for(std::vector<int>::iterator num = newschool.begin(); num != newschool.end(); ++num) {
int current = *num; // * gets the number out of the iterator
*num = 5; // Sets the number.
}
// Better syntax, use auto! automatically gets the right iterator type (C++11)
for(auto num = newschool.begin(); num != newschool.end(); ++num) {
int current = *num; // As above
*num = 5;
}
// std::for_each also available
std::for_each(newschool.begin(), newschool.end(), function_taking_int);
// std::for_each with lambdas (C++11)
std::for_each(newschool.begin(), newschool.end(), [](int i) {
// Just use i, can't modify though.
});
Vectors are also special because they are designed to be drop-in replacements for arrays. You can iterate over a vector exactly how you would over an array with a .size() function. However this is considered bad practice in C++ and you should prefer to use iterators where possible:
std::vector<int> badpractice;
for(int i = 0; i < badpractice.size(); ++i) {
badpractice[i]; // Get
badpractice[i] = 5; // Set
}
C++11 (the new standard) also brings the new and fancy range based for that should work on any type that provides a .begin() and .end(). However: Compiler support can vary for this feature. You can also use begin(type) and end(type) as an alternative.
std::array<int, 10> fancy;
for(int i : fancy) {
// Just use i, can't modify though.
}
// begin/end requires #include <iterator> also included in most container headers.
for(auto num = std::begin(fancy); num != std::end(fancy); ++num) {
int current = *num; // Get
*num = 131; // Set
}
std::begin also has another interesting property: it works on raw arrays. This means you can use the same iteration semantics between arrays and non-arrays (you should still prefer standard types over raw arrays):
int raw[10];
for(auto num = std::begin(raw); num != std::end(raw); ++num) {
int current = *num; // Get
*num = 131; // Set
}
You also need to be careful if you want to delete items from a collection while in a loop because calling container.erase() makes all existing iterators invalid:
std::vector<int> numbers;
for(auto num = numbers.begin(); num != numbers.end(); /* Intentionally empty */) {
...
if(someDeleteCondition) {
num = numbers.erase(num);
} else {
// No deletition, no problem
++num;
}
}
This list is far from comprehensive but as you can see there's a lot of ways of iterating over a collection. In general prefer iterators unless you have a good reason to do otherwise.
Change you for loop to
for(i=0; i< sizeof(numbers)/sizeof(int);i++){
In simple words,
sizeof(numbers) mean number of elements in your array * size of primitive type int, so you divide by sizeof(int) to get the number of elements
If you fix it so that it's list<int> numbers = {1,2,3,4}:
Iterating through using iterators:
#include <iterator>
for(auto it = std::begin(numbers); it != std::end(numbers); ++it) { ... }
Iterating through using std::for_each:
#include <algorithm>
#include <iterator>
std::for_each(numbers.begin(), numbers.end(), some_func);
Utilizing a for-each loop (C++11):
for(int i : numbers) { ... }
I didn't see it among the answers but this is imo the best way to do it: Range-based for loop
It is safe, and in fact, preferable in generic code, to use deduction to forwarding reference:
for (auto&& var : sequence).
Minimalist and working example :
#include <list>
#include <iostream>
int main()
{
std::list<int> numbers = {2, 4, 6, 8};
for (const int & num : numbers)
std::cout << num << " ";
std::cout << '\n';
return 0;
}
If your list of numbers is fixed be aware that you can simply write:
#include <iostream>
#include <initializer_list>
int main()
{
for (int i : {2, 4, 6, 8})
std::cout << i << std::endl;
return 0;
}
There is no size function on "plain" C-style arrays. You need to use std::vector if you want to use size, or calculate size through sizeof.
In C++11 you can use array initialization syntax to initialize your vectors, like this:
vector<int> numbers = {2, 4, 6, 8};
Everything else stays the same (see demo here).
You can also use the plain old C containers and use the iterator syntax for the loop:
#include <iostream>
int main()
{
int numbers[] = {2, 4, 6, 8};
int *numbers_end = numbers + sizeof(numbers)/sizeof(numbers[0]);
for (int *it = numbers; it != numbers_end; ++it)
std::cout << "the current number is " << *it << std::endl;
return 0;
}
There is no member function "size" because "numbers" isn't a class. You can not get the array's size this way, you must either know it (or compute it) or use some class to store your numbers.
The easiest way to do it, in my opinion, would be to use a span.
#include <cstdlib>
#include <iostream>
#include <gsl/span>
int main() {
int numbers[] = {2, 4, 6, 8};
for(auto& num : gsl::span(numbers)) {
cout << "the current number is " << num;
}
system("pause");
}
Notes:
Spans are part of the GSL library. To use them, download the library from here, and add the download path to the compilation command, e.g. g++ -o foo foo.cpp -I/path/to/gsl
In C++20, span will be part of the standard, so you would just use std::span and #include <span>.
i need to fill in the int[] array in C++ from zero to number defined by variable, but ISO C++ forbids variable length array...
How to easily fill in the array? Do i need to allocate/free the memory?
int possibilities[SIZE];
unsigned int i = 0;
for (i = 0; i < SIZE; i++) {
possibilities[i] = i;
}
btw. if you would ask - Yes, i need exactly standard int[] arrays, no vectors, no maps etc.
In c++11 you can use std::iota and std::array. Example below fills array sized 10 with values from 1 to 10.
std::array<int, 10> a;
std::iota(a.begin(), a.end(), 1);
Edit
Naturally std::iota works with vectors as well.
As you've found, you cannot create a variable-length array on the stack. So your choices are either to allocate it on the heap (introduces memory-management issues), or to use a std::vector instead of a C-style array:
std::vector<int> possibilities(SIZE);
for (int i = 0; i < SIZE; i++)
{
possibilities[i] = i;
}
If you want to get even more flashy, you can use STL to generate this sequence for you:
// This is a "functor", a class object that acts like a function with state
class IncrementingSequence
{
public:
// Constructor, just set counter to 0
IncrementingSequence() : i_(0) {}
// Return an incrementing number
int operator() () { return i_++; }
private:
int i_;
}
std::vector<int> possibilities(SIZE);
// This calls IncrementingSequence::operator() for each element in the vector,
// and assigns the result to the element
std::generate(possibilities.begin(), possibilities.end(), IncrementingSequence);
If you have access to boost then you already have access to an incrementing iterator.
#include <vector>
#include <boost/iterator/counting_iterator.hpp>
std::vector<int> possibilities(
boost::counting_iterator<int>(0),
boost::counting_iterator<int>(SIZE));
The counting iterator essentially wraps incrementing a value. So you can automatically tell it the begin and end values and vector will populate itself properly.
As mentioned elsewhere, the resulting vector can be used directly with std::next_permutation.
std::next_permutation(possibilities.begin(),possibilities.end());
std::vector<int> possibilities;
unsigned int i = 0;
for (i = 0; i < SIZE; i++) {
possibilities.push_back(i);
}
Use std::vector(you need to include <vector>)
If you want pass vector to std::next_permutation you need to write:
std::next_permutation(possibilities.begin(),possibilities.end());
also you can use vector as C style arrays. &vec[0] returns pointer to C style array.
You can use the std::generate_n function:
std::generate_n( myarray, SIZE, increment() );
Where increment is an object that generates numbers:
struct increment {
int value;
int operator() () { return ++value; }
increment():value(0){}
};
If you make SIZE a constant (macro or const), you can use it to specify the size of your static array. If it is not possible to use a constant, for example you are reading the intended size from outside the program, then yes you will need to allocate the memory.
In short, if you don't know the size at compile time you probably need to allocate the memory at runtime.
std::generate() can be used with a mutable lambda function to be more concise. The following C++ snippet will place the values 0..9 inclusive in a vector A of size 10 and print these values on a single line of output:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
size_t N = 10;
vector<int> A(N);
generate(A.begin(), A.end(), [i = 0]() mutable { return i++; });
copy(A.begin(), A.end(), ostream_iterator<int>(cout, " "));
cout << endl;
return 0;
}
Assuming SIZE is a constant expression and you're allowed to use std::array, you can create a function template that will allow you to do this at compile time. Note from C++17, std::array<T, N>::begin is constexpr so that you can do all this at compile time.
C++17 Version
template<std::size_t N> std::array<int, N> constexpr make_array()
{
std::array<int, N> tempArray{};
int count = 0;
for(int &elem:tempArray)
{
elem = ++count;
}
return tempArray;
}
int main()
{
const int SIZE = 8;
//-------------------------------V-------->number of elements
constexpr auto arr = make_array<SIZE>();
//lets confirm if all objects have the expected value
for(const auto &elem: arr)
{
std::cout << elem << std::endl; //prints 1 2 3 4 5 6 7 8 with newline in between
}
}
C++17 demo
C++11 Version
But prior to C++17, std::array<T, N>::begin was not constexpr, we will need to modify the above example slightly for C++11 as shown below:
template<std::size_t N> std::array<int, N> make_array()
{
std::array<int, N> tempArray{};
int count = 0;
for(int &elem:tempArray)
{
elem = ++count;
}
return tempArray;
}
int main()
{
const int SIZE = 8;
//---------------------VVVV---->number of elements
auto arr = make_array<SIZE>();
//lets confirm if all objects have the expected value
for(const auto &elem: arr)
{
std::cout << elem << std::endl; //prints 1 2 3 4 5 6 7 8 with newline in between
}
}
C++11 demo
Simply use a dynamic arrays?
type * pointer;
pointer = new type[number_of_elements];
void main()
{
int limit = 0; // Your lucky number
int * pointer = NULL;
cout << "Please, enter limit number: ";
cin >> n;
pointer = new int[limit+1]; // Just to be sure.
for (int i = 0; i < n; i++)
{
pointer[i] = i; // Another way is: *(pointer+i) = i (correct me if I'm wrong)
}
delete [] pointer; // Free some memory
pointer = NULL; // If you are "pedant"
}
I don't pretend this is the best solution. I hope it helps.
it should be help u man
int* a = NULL; // Pointer to int, initialize to nothing.
int n; // Size needed for array
cin >> n; // Read in the size
a = new int[n]; // Allocate n ints and save ptr in a.
for (int i=0; i<n; i++) {
a[i] = 0; // Initialize all elements to zero.
}
. . . // Use a as a normal array
delete [] a; // When done, free memory pointed to by a.
a = NULL; // Clear a to prevent using invalid memory reference