Pointer refer different values - c++

I got a problem while solving a beginner c++ challenge in hackerrank.
https://www.hackerrank.com/challenges/variable-sized-arrays/problem
The challenge require me to create an array of int array which simply is a 2d array, but the order of input constraints is so bad that I cannot make it. Suddenly, it pops up to me an idea of creating an array of pointers *arrA that each element refers &arrB[0] of its sub-array arrB.
Note: It is similar to vector<vector<int>> but I would not use vector here.
int main() {
int n, q, k, i, j;
cin >> n >> q;
int *arr[n];
for (int l = 0; l < n; l++) {
cin >> k;
int arr_i[k];
for (int m = 0; m < k; m++) {
cin >> arr_i[m];
}
arr[l] = &arr_i[0];
cout << *arr[l] << " " << arr[l] << endl;
}
// after 2 loop, it prints
// 1 0x7fff17940030
// 2 0x7fff17940020
for (int l = 0; l < q; l++) {
cin >> i >> j;
cout << *arr[l] << " " << arr[l] << endl;
}
// after 2 loop, it prints
// random integer(eg: 395575472) 0x7fff17940030
// random integer(eg: 922493088 ) 0x7fff17940020
return 0;
}
The constraints are:
2 2 // n q
3 1 5 4 // k k[0] k[1] k[2]
5 2 2 8 9 3 // k k[0] k[1] k[2] k[3] k[4]
0 1 // i j
1 3 // i j
Back to the problem, the first loop prints exactly what i need. But in the second loop, the values are missing though the address are the same. I have search many stackoverflow question but none of them meets my needs.
Can someone explain this to me. Many thanks !!!

The scope for int arr_i[k]; is the first loop, and while it's fine to take it's address with arr[l] = &arr_i[0]; those addresses are out of scope when you dereference them in the 2nd loop.

The C++ way to have variable sized arrays is std::vector. And you can have a vector-of-vectors.
Example:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main() {
int nrOfVectors, q /* what is q?*/;
std::cin >> nrOfVectors >> q;
std::vector<std::vector<int>> vecvec(nrOfVectors);
for(auto& vec : vecvec) {
int nrOfElements;
std::cin >> nrOfElements;
vec.reserve(nrOfElements);
std::copy_n(std::istream_iterator<int>(std::cin), nrOfElements, back_inserter(vec));
}
}
edit:
An array solution has no added value (actually makes thing unnecessarily complex and error-prone), but whatever
#include <iostream>
#include <memory>
int main() {
int nrOfVectors, q /* what is q?*/;
std::cin >> nrOfVectors >> q;
std::unique_ptr<std::unique_ptr<int[]>[]> vecvec(new std::unique_ptr<int[]>[nrOfVectors]);
for (int i = 0; i < nrOfVectors; ++i) {
int nrOfElements;
std::cin >> nrOfElements;
auto vec = new int[nrOfElements];
for (int j = 0; j < nrOfElements; ++j) {
std::cin >> vec[j];
}
vecvec[i].reset(vec);
}
}

Related

How to find missing number in array

#include <iostream>
#include <algorithm>
using std::cin;
using std::cout;
using std::endl;
using std::sort;
int main()
{
int x = 0;
int n; // Enter Size of 2 array
cin >> n; // enter 5
long long *ptr1 = new long long[n - 1]; // size of array must be less than 5 by one n-1
for (int x = 0; x < n - 1; x++)
{
cin >> ptr1[x];
}
sort(ptr1, ptr1 + (n - 1));
for (int z = 1; z < n; z++)
{
if (z != ptr1[x])
{
cout << z;
break;
}
x++;
}
return 0;
}
You're given all positive integers from 1,2,…,n except one integer. Find the missing integer.
Input
The first line of input contains an integer n (2≤n≤2×105).
The second line of input contains n−1 distinct integers from 1 to n (inclusive).
Output
Print the missing integer.
when i try to sumbit this code i get wrong in test 10 but i don't know why! and he didn't show the test so what is wrong?
I have a three-fold answer:
This program leaks memory
You included <algorithm> please use it. (Look on cppreference)
Spoilers vector, iota, mismatch
Also, you don't reset x before the second loop.
That's never going to work unless the missing integer is the last of the array, and not equal to 1
// for (... z)
if (z != ptr1[x] /* Here */) {
// print 1, end loop OR invoke undefined behavior
}
x++; // Now x is equal to (n - 1)
There are some problems with your code:
long long *ptr1 = new long long[n - 1];
You call new, without delete. This will create a memory leak.
You haven't reinitialized x, so any access to ptr1[x] is out-of-bounds.
Slove all of that, and your code will look like:
#include <iostream>
#include <algorithm>
#include <vector>
int main()
{
int n;
cin >> n;
std::vector<int> vec(n-1); // std::vector instead
for (int x = 0; x < n - 1; x++)
{
std::cin >> vec[x];
}
std::sort(vec.begin(), vec.end());
int x = 0; // use another variable instead of reused the old one.
for (int z = 1; z < n; z++)
{
if (z != vec[x])
{
std::cout << z;
break;
}
x++;
}
return 0;
}
But, this isn't the best approach anyway. As #molbdnilo suggest:
#include <iostream>
int main()
{
int n;
std::cin >> n;
int sum{};
for (int i = 0; i < n - 1; ++i)
{
int tmp;
std::cin >> tmp;
sum += tmp;
}
std::cout << (n + 1) * n / 2 - sum;
}
You can solve this in a more straightforward way if you subtract the numbers that were entered from the expected sum of all numbers 1, 2, ..., n (see comments by #molbdnilo, #Aconcagua and #marcus-müller):
#include <iostream>
int main() {
std::size_t n;
std::cin >> n;
std::size_t sum{ n*(n + 1)/2 };
for (std::size_t idx = 1; idx != n; ++idx) {
std::size_t thisNumber;
std::cin >> thisNumber;
sum -= thisNumber;
}
std::cout << "Missing number: " << sum << std::endl;
}
Building blocks:
The expected sum: int expected_sum = n * (n + 1) / 2;
The sum of all integers fed to the test after you've read n:
#include <iterator> // istream_iterator
#include <numeric> // accumulate
int sum = std::accumulate(std::istream_iterator<int>(std::cin),
std::istream_iterator<int>{}, 0);
Now, expected_sum - sum should give you the missing value.

How can I start a loop from middle of the array?

There is a given pseudo code.
int Function(X : array[P..Q] of integer)
1 maxSoFar = 0
2 for L = P to Q
I was using C and trying to change it into C++ code.
The reason that I am struggling with it is I have no idea how to express it is start from 'P' in the loop.
I do not know how to do that before initilization even without parameter.
int Function(vector<int> X)
{
int maxSoFar = 0;
for (int I = 0; I < X.size(); I++) ;
}
This is what I did.
I wonder if it is same with the pseudo code or not.
You can just divide your vector size by 2:
#include <vector>
#include <iostream>
using namespace std;
int f(vector<int> v) {
int maxSoFar = 0;
int len = v.size();
for (int i = len / 2; i < len; i++) { // i = len / 2, starts from the middle
maxSoFar += v[i];
cout << v[i] << ' ';
cout << maxSoFar << endl;
}
}
int main(void) {
vector<int> v = {1, 3, 5};
f(v);
}
output:
3 3
5 8
You should take a closer look at the for loop on wikipedia: for (initialization; break condition; incrementation)
#include<iostream>
using namespace std;
int main()
{
int i,n;
cout<<"enter the number of elements : ";
cin>>n;
int a[n];
cout<<endl<<"enter the value of this array : ";
for(i=0;i<n;i++)
{
cin>>a[i];
}
cout<<endl<<"print the last half elements of this array : ";
for(i=(n/2);i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
return 0;
}

How to pass a 2D array in C++ without knowing the dimensions [duplicate]

This question already has answers here:
Passing a 2D array to a C++ function
(17 answers)
Closed 2 years ago.
#include<iostream>
using namespace std;
int n;
int diagonal(int m[][n]){
int r = 0,l = 0;
for(int i=0;i<n;i++){
l += m[i][i];
r += m[n-i][i];
}
if(r>l) return r - l;
else return l - r;
}
int main(){
cin >> n;
int a[n][n];
for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin >> a[i][j];
cout << diagonal(a) << endl;
return 0;
}
I don't know why I am getting errors running above code.
Error No.1: array bound is not an integer constant before ']' token, how am I supposed to pass a constant value if I am taking it from the user.
Error No.2: 'n' was not declared in this scope
6 | for(int i=0;i<n;i++){, no idea about this one.
Error No.1: array bound is not an integer constant before ']' token,
how am I supposed to pass a constant value if I am taking it from the user.
You can't. When you want to use variable length arrays, you should usually replace them with std::vectors.
Example:
#include <cstdlib>
#include <iostream>
#include <vector>
int diagonal(const std::vector<std::vector<int>>& m) {
int r = 0, l = 0;
for(size_t i = 0; i < m.size(); ++i) {
l += m[i][i];
// r += m[n - i][i]; // m[n][0]` when `i == 0`.
r += m[m.size() - i - 1][i];
}
// this is most likely implemented without branching:
return std::abs(r - l);
}
int main() {
// use an unsigned type suitable for indexing like size_t
if(size_t n; std::cin >> n) {
// int a[n][n]; // not valid C++
// vector replacement:
std::vector<std::vector<int>> a(n, std::vector<int>(n));
for(size_t i = 0; i < n; i++) {
for(size_t j = 0; j < n; j++) {
std::cin >> a[i][j];
}
}
std::cout << diagonal(a) << '\n';
}
}
Using templates:
template<auto X, auto Y>
int diagonal(int (&m)[X][Y]){

dynamically allocated arrays with user input c++

I want to have a mini function that allows the user to type a group of numbers, and each of them will be dynamically allocated into an array. For example:
int main()
{
int* x = NULL;
int n, numbers;
std::cin >> n;
x = new int[n]
for (int i=0;i<n;i++){
std::cin >> numbers;
x[i] = numbers;
}
delete [] x;
So when the user types in
3
The user will be able to type in 3 numbers following that
3 1 2 3
I am trying to store the values 1, 2, 3 into an array so it will look like
[1, 2, 3]
but right now it's storing as
[123]
Anyway i can fix this? I'm new to C++ programming so I feel like there's an easy solution to this but i'm not sure how.. thank you!
You could store each element of the array directly into x[i]. Not sure what numbers is used for (I've assigned numbers from x[i]).
x is the array that is to be deleted. And there is a missing ; at x = new int[x] - is that a typo?
int main()
{
int* x = NULL;
int n, numbers;
std::cin >> n;
x = new int[n];
for (int i=0;i<n;i++){
std::cin >> x[i];
numbers = x[i];
}
delete [] x;
You can use a vector instead:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n;
cin >> n;
vector<int> v;
for (int i = 0; i < n; ++i)
{
int val;
cin >> val;
v.push_back(val);
}
}
C++'s vector takes care of memory allocation for you. You could then simply traverse it and print its contents.
cout << "[";
for (int i = 0; i < v.size(); ++i)
{
if (i != 0)
cout << ",";
cout << v[i];
}
cout << "]";
Example 1
int main()
{
int* x = NULL;
int n, numbers;
std::cin >> n;
x = new int[n]; // need a semi-colon here
for (int i=0;i<n;i++)
{
std::cin >> numbers;
x[i] = numbers;
}
for (int j = 0; j < n; ++j)
{
std::cout << "x[" << j << "] = " << x[j] << std::endl;
}
delete [] x; // you mean x, not a
return 0;
}
Once you fix (what I assume are just typos), what you have works fine. However, unless this is for an assignment, you should consider using std::vector instead of raw dynamic memory allocation. Doing so would reduce your code to about 4 lines.
int main()
{
std::vector<int> myvector;
std::copy(std::istream_iterator<int>(std::cin), std::istream_iterator<int>(), std::back_inserter(myvector));
std::copy(myvector.begin(), myvector.end(), std::ostream_iterator<int>(std::cout, "\n"));
return 0;
}
or, in C++11
int main()
{
std::vector<int> myvector{std::istream_iterator<int>(std::cin), std::istream_iterator<int>()};
std::copy(myvector.begin(), myvector.end(), std::ostream_iterator<int>(std::cout, "\n"));
return 0;
}
Why not just create the array dynamically? This way, the user won't have to type in the number of elements in advance:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vec;
int x;
while (cin >> x)
vec.push_back(x);
for (int y: vec)
cout << y << ' ';
cout << '\n';
}
The cout statements are just to illustrate that everything worked.

C++ How to change the output on a new array

So I wrote a program that is supposed select the perfect squares from an array and put it into another array. Example: (2,4,13,5,25,66) and the second array(the result) should look like this (4,25)
My result looks like this (0,4,0,0,25,0) ...so its half good ...how to make it show only 4,25 ?
#include<iostream.h>
#include<math.h.>
int main()
{
int A[100],i,n,p,j;
cout << "Number of array elements=";
cin >> n;
for(i=1;i<=n;i++)
{
cout<<"A["<<i<<"]=";
cin>>A[i];
}
for(i=1;i<=n;i++)
{
p=sqrt(A[i]) ;
if(p*p==A[i])
A[j]=A[i];
else
A[i]=0;
cout << A[i] << " ";
}
return 0;
}
USING ONLY c++ basic commands...as i did
You need to keep a separate count of how many perfect squares you've found and use that to place your answers into an array of perfect squares:
int squares[???];
// ...
if(p*p==A[i]) {
squares[squaresFound]=A[i];
squaresFound++;
}
The problem now will be to decide how long the squares array should be. You don't know ahead of time how many squares you're going to get. Are you going to have it the same size as A and fill the rest with 0s? Or do you want the array of squares to be exactly the right size?
If you want it to be the right size, you're much better off using a std::vector:
std::vector<int> squares;
// ...
if(p*p==A[i]) {
squares.push_back(A[i]);
}
But I think your silly "only basic C++ commands" restriction will not allow you to do this.
You talk about a second array (the result), yet your code declares only one array! Additionally, you reference A[j], but your j has not be initialized.
You should declare another array B[100], initialize j to zero, and then use this code when you find a square:
int j = 0;
for (int i=0 ; i != n ; i++) {
int p = sqrt(A[i]);
if(p*p==A[i]) {
B[j++] = A[i];
}
}
Make another array, remove all occurrences of 0 from the resultArray and add non-0 to newArray.
OR
int j=0
if(A[i]==p*p)
squares[j++]=A[i];
#include <cmath>
#include <iostream>
using namespace std;
int main()
{
int A[100];
int n;
cout << "Number of array elements = " << endl;
cin >> n;
for(int i = 0; i < n; i++)
{
cout << "A[" << i << "] = ";
cin >> A[i];
}
int B[100];
int cnt_sqr = 0;
for(int i = 0; i < n; i++)
{
int p = sqrt(A[i]);
if (p * p == A[i])
{
B[cnt_sqr++] = A[i];
}
}
for (int i = 0; i < cnt_sqr; i++)
{
cout << B[i] << ' ';
}
return 0;
}
Full code of that about what you were told above
If you do not want to modify your code you can write the following:
for(i=1;i<=n;i++)
{
p=sqrt(A[i]) ;
if(p*p==A[i])
{
cout << A[i] << " ";
}
}
It will print you only perfect squares.
If you want to copy elements to another array:
int squares[100] = {0}; // Assuming that all values can be perfect squares
int square_count = 0;
for(i=1;i<=n;i++)
{
p=sqrt(A[i]) ;
if(p*p==A[i])
{
squares[square_count++] = A[i];
}
}