// Driver Code Starts
#include <bits/stdc++.h>
using namespace std;
vector<int> printNonRepeated(int arr[], int n);
int main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++)
cin >> arr[i];
vector<int> v;
v = printNonRepeated(arr, n);
for (int i = 0; i < v.size(); i++)
cout << v[i] << " ";
cout << endl;
}
return 0;
}
// } Driver Code Ends
// Function to print the non repeated elements in the array
// arr[]: input array
// n: size of array
vector<int> printNonRepeated(int arr[], int n) {
vector<int> a;
unordered_map<int, int> h;
int count = 0;
int i;
for (i = 0; i < n; i++) {
h[arr[i]]++;
}
int j = 0;
for (auto x : h) {
if (x.second == 1) {
a[j] = x.first;
j++;
}
}
return a;
}
I want to print the nonrepeating numbers using the function vector<int> printNonRepeated(int arr[],int n). I am trying using hashmap. I am getting segmentation error while compiling. Where am I doing a mistake.
I do not have the permission to change the main function. I can only change the 'printNonRepeated' function.
a[j] = x.first;
j++;
You can't access the jth index of a without having allocated space first. The size of the array needs to be predefined, or you can use push_back so that the vector adds a new element to the end.
a.push_back(x.first);
For starters variable length arrays as this
int n;
cin >> n;
int arr[n];
is not a standard C++ feature.
You may not use the subscript operator with an empty vector.
vector<int> a;
//...
for (auto x : h) {
if (x.second == 1) {
a[j] = x.first;
j++;
}
Creating vectors is redundant. You could initially store entered values in a container of the type std::map declared in main.
Related
I am new to coding and I am unable to see what is wrong with this Logic.
I am unable to get the desired output for this program.
The Question is to find the minimum and maximum elements of an array.
The idea is to create two functions for minimum and maximum respectively and have a linear search to identify the maximum as well as a minimum number.
#include <iostream>
#include<climits>
using namespace std;
void maxElement(int a[], int b)
{
// int temp;
int maxNum = INT_MIN;
for (int i = 0; i < b; i++)
{
if (a[i] > a[i + 1])
{
maxNum = max(maxNum, a[i]);
}
else
{
maxNum = max(maxNum, a[i+1]);
}
// maxNum = max(maxNum, temp);
}
// return maxNum;
cout<<maxNum<<endl;
}
void minElement(int c[], int d)
{
// int temp;
int minNum = INT_MAX;
for (int i = 0; i < d; i++)
{
if (c[i] > c[i + 1])
{
minNum = min(minNum,c[i+1]);
}
else
{
minNum = min(minNum,c[i]);
}
// minNum = min(minNum, temp);
}
// return minNum;
cout<<minNum<<endl;
}
int main()
{
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
minElement(arr,n);
maxElement(arr,n);
return 0;
}
You are already comparing each element to the current max / min. It is not clear why in addition you compare to adjacent elements. Trying to access a[i+1] in the last iteration goes out of bounds of the array and causes undefined behavior. Just remove that part:
void maxElement(int a[], int b)
{
// int temp;
int maxNum = INT_MIN;
for (int i = 0; i < b; i++)
{
maxNum = max(maxNum, a[i]);
}
cout<<maxNum<<endl;
}
Similar for the other method.
Note that
int n;
cin >> n;
int arr[n];
is not standard C++. Variable length arrays are supported by some compilers as an extension, but you don't need them. You should be using std::vector, and if you want to use c-arrays for practice, dynamically allocate the array:
int n;
cin >> n;
int* arr = new int[n];
Also consider to take a look at std::minmax_element, which is the standard algorithm to be used when you want to find the min and max element of a container.
Last but not least you should seperate computation from output on the screen. Considering all this, your code could look like this:
#include <iostream>
#include <algorithm>
std::pair<int,int> minmaxElement(const std::vector<int>& v) {
auto iterators = std::minmax_element(v.begin(),v.end());
return {*iterators.first,*iterators.second};
}
int main()
{
int n;
std::cin >> n;
std::vector<int> input(n);
for (int i = 0; i < n; i++)
{
std::cin >> input[i];
}
auto minmax = minmaxElement(input);
std::cout << minmax.first << " " << minmax.second;
}
The method merely wraps the standard algorithm. It isnt really needed, but I tried to keep some of your codes structure. std::minmax_element returns a std::pair of iterators that need to be dereferenced to get the elements. The method assumes that input has at least one element, otherwise dereferencing the iterators is invalid.
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]){
for example, I have to take input in the format:
2 // no of test cases
7 // n->size of an array
9 7 5 9 2 20 3 //n array elements
5 // second test case array size
4 5 8 96 6 // second test case array elements
I don't know what to write in the main function.
void sort(int arr[],int n)
{
for(int i=1;i<n;i++)
{
int current =arr[i];
int j;
for(j=i-1;j>=0;j--)
{
if(current<arr[j])
{
arr[j+1]=arr[j];
}
else
{
break;
}
}
arr[j+1]=current;
}
}
int main(){
// what should I write in the main func to test my problem for t no of times
// I have to take all inputs first then print the sorted arrays given by the user
// separated by space and new line for the next sorted array
}
I think this what you want.
const int N = 10;
int main(){
int t, n, arr[N];
cin >>t;
for(int T;T<t;++T){
cin >>n;
for(int i=0;i<n;++i){
cin>>arr[i];
}
sort(arr, n);
for(int i=0;i<n;++i){
cout <<arr[i]<<" ";
}
cout <<endl;
}
Make sure to put the value if N is the maximum possible size of the array. Or you can declare the array as a dynamic array with the entered n (or use one of the STL like vector)
for example:
int main(){
int t, n;
cin >>t;
for(int T;T<t;++T){
cin >>n;
int * arr = new int [n];
for(int i=0;i<n;++i){
cin>>arr[i];
}
sort(arr, n);
for(int i=0;i<n;++i){
cout <<arr[i]<<" ";
}
cout <<endl;
}
Or by using Vector:
#include<vector>
using namespace std;
//your sort func here, but make sure to change it to have a vector instead of an array
int main(){
int t, n;
vector<int>arr;
cin >>t;
for(int T;T<t;++T){
arr.clear();
cin >>n;
arr.resize(n);
for(int i=0;i<n;++i){
cin>>arr[i];
}
sort(arr, n);
for(int i=0;i<n;++i){
cout <<arr[i]<<" ";
}
cout <<endl;
}
PS: I would recommend to see websites like codeforces, Hackerrank and others to practice on competitive programming question which contains a lot of question that will help (If you're interested)
int main()
{
int t; // number of test cases
std::cin >> t;
while (t--) // repeat t times
{
// what you had before
}
}
to test you can
define an input and a desired output, i.e an array "unsorted" and how it SHOULD look like after sorted
define a method that sorts input "a" and allows you to verify that by eather returning the sorted array or modifying the reference given as parameter.
defined a compare method that takes x1 and x2 as parameter and returns a bool indicating if the operation failed or no. x1 can be the desired sorted array and x2 the array returned from step1
loop in a for with DIFFERENT unsorted arrays and theis according sorted values...
int main()
{
int t;
cin >> t;
while (t--)
{
int size;
cin >> size;
int *arr = new int[size];
for (int i = 0; i < size; i++)
{
cin >> arr[i];
}
sort(arr, size);
for (int i = 0; i < size; i++)
{
cout << arr[i] << " ";
}
delete[] arr;
cout << endl;
}
return 0;
}
I think this will work
this is a code example for what I mean
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
int numOfTest = 0;
std::vector<int>vec;
std::cin>>numOfTest ;
for(int j=; j<=numOfTest; ++j) // loop for num of tests
{
int n=0;
for(int i=0; i<n; ++i) // loop for num of veriabels in one test
{
int var=0;
std::cin >> var;
vec.push_back(var);
}
// option one
int* arr = new int[n] ;
std::copy(vec.begin(),vec.end(),arr);
sort(arr, n);
//option two
sort(&vec[0], n);
//option three
sort(vec.data(), n);
for(int f=0; j<=n ++j)
{
std::cout << arr[f] << " "; // print the sorted array;
}
delete [] arr;
}
return 0;
}
if your choosing option two or three you can using range base loop instead of for loop:
it will look like this:
for(auto& e: vec)
{
std::cout << e << " ";
}
How can I solve this problem without getting time limit exceeded
http://codeforces.com/problemset/problem/474/B
I tried putting all ranges in a 2D vector then looking for the desired index using binary search but it seems that the loop in the fn BS() takes a lot to execute as the size of the vector can be 10^6.
here is my code:
#include <iostream>
#include <vector>
using namespace std;
int Search(vector <vector<int> > a,int key){
int start = 0;
int end = a.size() - 1;
while (start <= end){
int mid = start + (end - start) / 2;
if (a[mid][0] > key && a[mid][1] > key){
end = mid - 1;
}
else if (a[mid][0] < key && a[mid][1] < key){
start = mid + 1;
}
else {
return mid;
}
}
return -1;
}
vector <int> BS(vector <vector <int> > v, vector<int> keys){
int j = 0;
vector <int> piles;
for (int i = 0; i < keys.size(); i++){
piles.push_back(Search(v, keys[i])+1);
}
return piles;
}
vector < vector<int> > Range(vector<int> v){
vector < vector<int> > ranges(v.size());
int sum1 = 1;
int sum2 = v[0];
for (int i = 0; i < v.size(); i++){
if (i == 0){
ranges[i].push_back(sum1);
ranges[i].push_back(v[i]);
sum1 += v[i];
}
else{
ranges[i].push_back(sum1);
sum2 += v[i];
ranges[i].push_back(sum2);
sum1 += v[i];
}
}
return ranges;
}
int main(){
int n, m;
cin >> n;
vector <int> a, q;
vector < vector <int> > v;
for (int i = 0; i < n; i++){
int k;
cin >> k;
a.push_back(k);
}
cin >> m;
for (int i = 0; i < m; i++){
int l;
cin >> l;
q.push_back(l);
}
v = Range(a);
vector <int> jucy = BS(v, q);
for (int i = 0; i < jucy.size(); i++){
cout << jucy[i] << endl;
}
}
In fact i don`t think you need 2D vector at all, you need just 1D. Which for example would look like this [2,9,12,16,25], the upper bound of each pile, you can construct this really easy. Then for every juicy worm you do binary search in that manner that it returns index with value greater or equal to the value you are looking for. The index you got from the search is the pile you are looking for.
Some pseudo-code:
A[n] - vector of upper bounds
A[0] = a0
For each 0<i<=n A[i]=A[i-1]+ai
For each q do std lower_bound on A looking for q,
the index you get is with first value equal or greater than q, so the pile where is q.
and C++ code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
int n, m;
cin >> n;
vector<int>A;
A.resize(n);
int ai;
cin >> ai;
A[0]=ai;
for (int i = 1; i < n; i++){
cin >> ai;
A[i]=A[i-1]+ai;
}
cin >> m;
int q;
for (int i = 0; i < m; i++){
cin >> q;
cout << std::distance(A.begin(),std::lower_bound(A.begin(),A.end(),q))+1<<endl;
}
return 0;
}
You have to add +1 to distance because the piles are numbered from 1. Work for the example, and looks pretty fast.
The most obvious optimization opportunity is, instead of using a vector<vector<int>> use a vector<int> and manually adjust the 2D indices to 1D. You can write a simple wrapper class that does this for you.
The reason that that will be much faster is that then all the memory will be allocated as a single contiguous unit. If you have a vector of vectors, then each row will be somewhere else and you'll have lots of cache misses.
Here's a code example:
struct 2D_Vector {
std::vector<int> me_;
int ncols_;
2D_Vector(int nrows, int ncols) : me(nrows * ncols), ncols_(ncols) {}
int & get(int y, int x) { return me_[y * ncols_ + x]; }
const int & get(int y, int x) const { return me_[y * ncols_ + x]; }
...
};
If you preallocate this with all the space that it will need, then it should use memory very efficiently.
Also, passing large function parameters by value instead of by reference is very wasteful, because it results in needless copies being made and destroyed. (Like WhozCraig pointed out.)
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.