This question already has answers here:
Find the count of elements in array in C++
(3 answers)
Closed 5 years ago.
I have a simple array here:
int someNumbers[10] = { 16, 2, 77, 40, 12071 };
How can I get the number of data inside the array? As the array was set to 10, but there is only 5 data inside.
My desired outcome should be something like this:
int icount = sizeof(someNumbers); // This is wrong, but I have no idea how..
cout << icount << endl;
I need icount to return 5 instead of 10. How can I do that?
This will do:
#include<iostream>
using namespace std;
int main(){
int someNumbers[10] = { 16, 2, 77, 40, 12071 };
int count = 0;
int i = 0;
for(i = 0; i < sizeof(someNumbers) / sizeof(int); i++){
if(someNumbers[i]){
count = count + 1;
}
}
cout << count << endl;
return 0;
}
I am using if(someNumber[i]) alone because this will return true as long as someNumber[i] is not undefined. Therefore, this works.
This is the output:
5
You can always make this a separate function like this:
#include<iostream>
using namespace std;
int dataInArray(int someNumbers[], int size);
int main(){
int someNumbers[10] = { 16, 2, 77, 40, 12071, 2};
int count = dataInArray(someNumbers, 10);
cout << count << endl;
return 0;
}
int dataInArray(int someNumbers[], int size){
int count = 0;
int i = 0;
for(i = 0; i < size; i++){
if(someNumbers[i]){
count = count + 1;
}
}
return count;
}
Since you are using a static array where the size is predefined, you would have to use a for loop to run through your array. See example here:
int someNumbers[10] = { 16, 2, 77, 40, 12071 };
int icount = 0;
for (int i = 0; i < 10; i++)
{
if (someNumbers[i])
icount++;
}
cout << icount << endl;
A bit of background information. If one of the memory blocks assigned to this array is not set by the user, it will store an empty value. Therefore, if we do if(isNumber[i]) then it will return true if someNumber at iis filled with a value, and it will return false if not filled with a value.
That is how the for-loop works in the code I posted. For every run of the loop, when the if statement is true, (if someNumber[i] has a value), then the counter is incremented.
EDIT: This solution works fine; for your array, it will output 5. It also works for any int array; just change the counter to run while it less than the static size you assign for the array.
EDIT 2: this solution works as long as there is no zero in your array, because a zero will falsify the if-condition. See more in this stackoverflow post: Find the count of elements in array in C++. To overcome this obstacle, it is recommended that you use std::vector, or use a counter variable and update the exact number of memory locations in the array that are filled in this variable manually.
What you are asking for just is not possible, because according to the language rules, there is no difference at all between:
int someNumbers[10] = { 16, 2, 77, 40, 12071 };
and
int someNumbers[10] = { 16, 2, 77, 40, 12071, 0, 0, 0, 0, 0 };
Both of them definitely initialize all ten elements.
If you're interested in finding the first zero (whether it was typed by the programmer or implied by the language rules) then #ABusyProgrammer's answer will help.
If you need to count zeros which the programmer typed, then you have to let the compiler infer the array (or initializer_list, as mentioned in comments) length from the initializer as #Kelm's answer shows.
There's no way to both detect zeros typed by the programmer and also specify the array size.
Use this:
int someNumbers[] = { 16, 2, 77, 40, 12071 };
cout << sizeof(someNumbers)/sizeof(int) <<endl;
This is because sizeof(someNumbers) does not give you the count of the array but rather the total number of bytes it is taking. So divide it by sizeof(int) and it will give you the number of integers in the array.
Also, if you specify [10] while declaring the array then the count of the array will be 10, regardless of whether it is initialized with fewer values. The way shown above, with an empty [], it will automatic set the count according to the number of elements specified.
ideone link
This should do it:
int someNumbers[] = {1,2,3,4,5,6};
int icount = sizeof(someNumbers) / sizeof(int);
Related
I want to store the Values to the CustomValues array. How can I do this?
Any code and explanation would be great.
int main() {
int CustomValues[4][3];
int Values[3] = {234, 98, 0};
int Values1[3] = {21, 34, 5};
int Values2[3] = { 12, 6, 765 };
int Values3[3] = { 54, 67, 76 };
}
The CustomValues array should look like:
{{234, 98, 0}, { 21, 34, 5 }, { 12, 6, 765 }, { 54, 67, 76 }}
There's a few different ways you can do this. Since we already know your constraints, I've taken liberties to not do this dynamically.
The first is memcpy, which is in the <cstring> header:
memcpy(CustomValues[0], Values, sizeof(Values));
memcpy(CustomValues[1], Values1, sizeof(Values1));
memcpy(CustomValues[2], Values2, sizeof(Values2));
memcpy(CustomValues[3], Values3, sizeof(Values3));
Another is to loop through the array and store the values individually:
for (int i = 0; i < sizeof(CustomValues)/sizeof(CustomValues[0]); i++) {
for (int j = 0; j < sizeof(CustomValues[0])/sizeof(CustomValues[0][0]); j++) {
if (i == 0) {
CustomValues[i][j] = Values[j];
}
else if (i == 1) {
CustomValues[i][j] = Values1[j];
}
else if (i == 2) {
CustomValues[i][j] = Values2[j];
}
else if (i == 3) {
CustomValues[i][j] = Values3[j];
}
}
}
There is probably a better way to handle the logic for selecting which Values array you want, but that was just a quick solution to demonstrate.
EDIT: Example of 2D Vector usage
This example doesn't contain the logic for actually controlling the number of elements in a vector, but you can simply do that by following the for loop logic. Basically, you just need something to check the size of your vector with size(), and then move to a different one.
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<vector<int>> CustomValues; //2D vector
//1D vectors
vector<int> Values;
vector<int> Values1;
Values.push_back(234); //to insert a value individually
Values.insert(Values.end(), {98, 0}); //to append multiple values
Values1.insert(Values1.end(), {21, 34, 5});
//inserting the 1D arrays to the 2D arrays
CustomValues.push_back(Values);
CustomValues.push_back(Values1);
//example of getting # of elements
int countOfInnerVectors = 0;
for (int i = 0; i < CustomValues.size(); i++)
countOfInnerVectors++;
cout << "The number of 1D vectors in CustomValues is: " << countOfInnerVectors;
}
An example of checking for the correct amount of vectors would be:
//check if we have less than 10 inner vectors
int maxCustomValuesSize = 10;
if (CustomValues2.size() < maxCustomValuesSize)
In this example, you would have something like int index = 0, and when that if is no longer satisfied, you could do index++ or some other logic to start inserts at your new index, like CustomValues2[index].push_back(Values);.
You can follow the same logic for the inner vectors as well, you would just be changing to a new 1D array instead of changing to a new "row" like the outer vector does.
I don't have any idea about this syntax int *count = new int[sizeof(int)* (size - 2)]
What kind of array that will create.
I thought they are trying to create map like structure. But how does it work?
#include <bits/stdc++.h>
using namespace std;
void printRepeating(int arr[], int size)
{
int *count = new int[sizeof(int)*(size - 2)];
int i;
cout << " Repeating elements are ";
for(i = 0; i < size; i++)
{
if(count[arr[i]] == 1)
cout << arr[i] << " ";
else
count[arr[i]]++;
}
}
// Driver code
int main()
{
int arr[] = {4, 2, 4, 5, 2, 3, 1};
int arr_size = sizeof(arr)/sizeof(arr[0]);
printRepeating(arr, arr_size);
return 0;
}
// This is code is contributed by rathbhupendra
Finding duplications in an array is of course a solved problem. IMHO a very simple solution is:
sort the array use std::sort()
use a loop to check if an element is equal to it's successor, ie. for(int i = 1; i < num_elements; i++){ if(arr[i-1]==arr[i]){...duplicate!...}}
This requires O(n) memory and O(n*log(n)) time, so it's quite ok. You can also use a hashmap, but that's pretty much the same.
Anyways, to your question(s):
int *count = new int[sizeof(int)* (size - 2)];
This is incorrect. I assume it used to be this C code:
int num_elements = size-2; // we want size-2 elements (not sure why)
int total_bytes = sizeof(int) * num_elements;
int *count = calloc(total_bytes); // reserve space, and set to 0
Which one could translate to this C++ code:
int num_elements = size-2;
int * count = new int[num_elements]{0}; // alloc and set to zero
So the person who did the port misunderstands fundamentals about C++.
Let's dig further.
For the sake of it, the problem formulation appears to be:
You are given an array of n+2 elements. All elements of the array
are in range 1 to n. And all elements occur once except two
numbers which occur twice. Find the two repeating numbers
I have made tiny changes to make the solution less crazy, and I've added annotations.
// #include <bits/stdc++.h> is a bad choice.
// This includes _EVERYTHING_ in C++,
// but it only works in GCC afaik. For this particular
// case we just need cout, so:
#include <iostream>
// using the std namespace like this spills function calls like crazy in the global namespace.
// it is both, conventient and "not too bad" (imho) in cpp files,
// but never ever do this in .h files where it affects multiple cpp files.
using namespace std;
void printRepeating(int arr[], int size)
{
// create a new array of size-2 and set to zero
int *count = new int[(size - 2)]{0};
int i;
cout << " Repeating elements are ";
// loop all elements
for(i = 0; i < size; i++)
{
int value = arr[i];
// increase the count for `value`
// note that if value<=0 or value>size-2,
// then the program will crash!
// the problem description is contrived, but it does
// state that all values need to be >0 and <=size-2,
// so this next array access is fine!
count[value-1]++;
// we still have to subtract 1, because C arrays start
// at index 0, but our problem description says we start at 1.
// we could also create an array of size-1 and
// "ignore" the first position in count[0] (it would never get used!)
// if the element appears the second time...
if(count[value-1] == 2){
// then print it
cout << value << " ";
// btw: if you check with count[value-1]==2, then only
// the first duplicate is printed.
// you could compare with count[value-1]>=2 then all
// repeating elements are printed repeatetly.
}
}
// free up the memory. we allocated with `new[]`
// so we also have to use `delete[]`
delete [] count;
}
// Driver code
int main()
{
int arr[] = {4, 2, 4, 5, 2, 3, 1};
// next line is a standard trick.
// a single int consumes 4bytes (typically),
// the array will have size 7*4=28 bytes, so sizeof(arr)=28
// the first element is an int, so sizeof(arr[0]) = 4
// so sizeof(arr)/sizeof(arr[0]) = 7
// c and c++ don't have arr.length like java,etc., that's
// why under certain circumstances this "trick" is used.
int arr_size = sizeof(arr)/sizeof(arr[0]);
// call the function
printRepeating(arr, arr_size);
return 0;
}
// This is code is contributed by rathbhupendra.
// Maybe fixed and annotated by hansi:)
I hope this helps you and answers some questions. Good luck with your C++ adventures!
I'm writing class that manages dynamic array of objects. Right now I got stuck on method that should insert element at given index, but before it checks if that index isnt bigger than array capacity. Then it should resize array first.
template <class T>
void MyVector<T>::insertAt(int index, const T &m_element) {
if(p_size == p_capacity) extendArray();
if(index >= p_capacity) extendArray(index);
p_size++;
p_array[index] = m_element;
}
template <class T>
void MyVector<T>::extendArray(int new_capacity) {
std::unique_ptr<T[]> temp_array = std::make_unique<T[]>(new_capacity);
for (int i = 0; i <= p_size; i++) {
temp_array[i] = p_array[i];
}
p_array.reset();
p_array = std::make_unique<T[]>(new_capacity);
for (int i = 0; i <= p_size; i++) {
p_array[i] = temp_array[i];
}
}
extendArray()just extends array capacity 2 times, extendArray(int) extends array capacity to the number given by the index. First method works fine, second not so really.
int main(){
MyVector<int> test;
test.insertAt(0, 5);
test.insertAt(1, 3);
test.insertAt(2, 1);
test.insertAt(6, 11);
cout <<"Size " << test.getSize() << "\n";
for(int i = 0; i < test.getCapacity(); i++) {
cout << test.get(i) << ", ";
}
}
Id expect something like 5, 3, 1, 0, 0, 0, 11, 0
But I get just 5, 3, 1, 0 so it never extends array but it increases size (number of elements).
You did not post your extendArray() function but even though you say it's a copy of extendArray(int) first seems to be updating p_capacity when the latter you provided doesn't.
Fixing that would gain you couple of extra zeros in the output 5, 3, 1, 0, 0, 0 since you extending only to the index, not to the index+1. Furthermore, in insertAt(int index, const T &m_element) you are incrementing the p_size, instead of assigning it to index+1
Extending to p_size+1 and fixing the p_size assignment, prints 5, 3, 1, 0, 0, 0, 11 and I am not quite sure how you came to the conclusion that it should have an extra trailing 0 as p_capacity ends up being 7, regardless if the initial value is 1, 2 or 4 as in the code snippet I put a link to.
I also noticed couple of bugs I without looking too close: your loops shouldn't go to the p_size, but rather to p_size-1, so instead for (size_t i = 0; i <= p_size; i++) it should be for (size_t i = 0; i < p_size; i++)
I would also suggest using unsigned int (or size_t) instead of int for indexing as that allows to get compiler warnings when you do something which potentially can result in a negative index.
Lastly, you should be able to use unique_ptr::swap to avoid two allocations in extendArray(..).
Good luck with learning!
I was trying to solve the following problem,
Given an array of integers, every element appears three times except
for one. Find that single one.
When the input are all positive, I will not get any errors, but when the input contains negative integers, the line delete index; will give error, does anybody know why?
i.e.
A[] = {1,2,3,4,1,2,3,4,1,3,4} works fine, but A[] = {-2,-2,1,1,-3,1,-3,-3,-4,-2} does not.
The code is as follow,
#include <iostream>
#include <map>
class Solution {
public:
int singleNumber(int A[], int n) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
int *index;
std::map<int, int> m;
index = new signed int[(n+1)/3];
int flag = 0;
int result;
for(int i=0; i<n; i++) {
if(m.find(A[i]) == m.end()) {
m[A[i]] = 1;
index[flag] = A[i];
flag++;
} else {
m[A[i]] = m[A[i]] + 1;
}
}
for(int i=0; i<(n+1)/3; i++) {
if(m[index[i]] != 3) {
result = index[i];
}
}
delete index;
return result;
}
};
int main()
{
Solution s;
int A[] = {1,2,3,4,1,2,3,4,1,3,4};
int result = s.singleNumber(A, 11);
std::cout <<result;
return 0;
}
The first array contains 11 elements, which causes the line index = new signed int[(n+1)/3]; to allocate an array of (11+1)/3 = 4 elements. The second array contains 10 elements, which causes that line to allocate an array of (10+1)/3 = 3 elements.
3 elements is insufficient to record the unique values in A (-4, -3, -2, and 1), so you overflow the array.
You should allocate at least (n+2)/3 elements. It would also be prudent to test the value of flag to ensure it never exceeds the array bounds. It will not if the input array obeys the constraint that every element but one appears three times (presuming this means it will appear one or two times, not four or more), but can you rely on that constraint being obeyed?
Additionally, the loop for(int i=0; i<(n+2)/3; i++) is insufficient to iterate through all the elements that were added to the map. You should be sure you iterate through all the members of m.
Incidentally, singleNumber can be implemented in a much more fun way without any dynamic allocation or library calls:
int singleNumber(int A[], int n) {
int b = 0, c = 0;
while (n--)
{
b ^= A[n] & c;
c ^= A[n] & ~b;
}
return c;
}
However, this is completely not what your instructor is expecting.
I'm teaching myself C++ and doing a problem from a textbook. So far I have covered the basics such as data types, declarations, displays, assignment, interactive input, selection (if-else), and repetition (for/while loops...), functions and arrays. I have NOT done anything with pointers, but I know what they are...
I came across this problem:
The answers to a true-false test are as follows: T T F F T. Given a two-dimensional answer array, in which each row corresponds to the answers provided on one test, write a function that accepts the two-dimensional array and number of tests as parameters and returns a one-dimensional array containing the grades for each test. (Each question is worth 5 points so that the maximum possible grade is 25.) Test your function with the following data:
My understanding is that C++ functions cannot return arrays--At least this is what I read on other posts on this forum. Is this correct? If so, how are they expecting you to do this problems because I haven't covered pointers yet. The only other way I thought MIGHT be possible is by passing in the array by reference.... but the question stem only says there are 2 arguments to the function so I thought maybe that method was ruled out. That method would require a third argument which is the array your modifying so its implicitly returned.
I have some code, but its not correct (only my calcgrade function needs work) and I'm not sure how to move forward.Could someone please advise? Thank you!!
#include<iostream>
// Globals
const int NROW = 6, NCOL = 5;
bool answers[NCOL] = {1, 1, 0, 0, 1};
bool tests[][NCOL] = {1, 0, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 0, 0, 1,
0, 1, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 0, 1, 0};
int grade[NROW] = {0};
// Function Proto-Types
void display1(bool []);
void display2(bool [][NCOL]);
int calcgrade(bool [][NCOL], int NROW);
int main()
{
calcgrade(tests, NROW);
display2(tests);
return 0;
}
// Prints a 1D array
void display1(bool answers[])
{
// Display array of NCOL
for(int i = 0; i < NCOL; i++)
std::cout << std::boolalpha << answers[i] << std::endl;
return;
}
// Print 2d Array
void display2(bool answers[][NCOL])
{
// Display matrix: 6x5
for(int i = 0; i < NROW; i++)
{
for(int j= 0; j < NCOL; j++)
{
std::cout << std::boolalpha << answers[i][j] << std::endl;
}
std::cout << std::endl;
}
return;
}
int calcgrade(bool tests[][NCOL], int NROW)
{
for(int i = 0; i < NROW; i++)
{
for(int j = 0; j < NROW; j++)
{
if(tests[i][j]==answers[j])
grade[i] += 5;
}
printf("grade[%i] = %i", i, grade[i]);
}
return grade;
}
Try to use std::vector.
Vectors are sequence containers representing arrays that can change in size.
You can do so:
vector<bool> function()
{
vector<bool> vec;
vec.push_back(true);
vec.push_back(false);
vec.push_back(true);
return vec;
}
If you're passing the number of tests as the second parameter, it means you actually know the number of tests, so you don't need to use a vector. You can return an dynamically allocated array (either using new or malloc).
The code would look like this:
int* calcgrade(bool tests[][NCOL], int NROW){
int* array = new int[NROW];
for(int i=0;i<NROW;i++)
array[i] = calculatedGrade;
return array;
}
You can:
as you said, return pointer to dynamically allocated array,
you can make structure type with word struct that includes static array, read more on C++ Reference and return/take as argument structure of your type.
Another way of doing this would be to create the Answer array in your main function, then pass it along with the T/F array to your grading function. Then, your grading function could operate on the Answer array, and wouldn't even need to return anything.
Essentially, when you pass arrays in functions, you're actually passing pointers to the arrays, and thus you can operate on them as if they were passed by reference (which they were).
semi-pseudocode ex:
void getGrades( const int answerVector, int gradeVector ) {
// code that computes grades and stores them in gradeVector
}