I was creating a function that takes an integer number, finds the next multiple of 5 after the number and then if the difference between the multiple and the number is less than 3, then it prints out the multiple else the number itself, finally prints out an array of all the numbers.
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
vector<int> gradingStudents(vector<int> grades) {
int size=grades.size();
int c=0;
int d;
vector<int> array;
for(int i=0;i<size;i++){
while(grades[i]>(c*5)){
c++;
}
d=c*5;
if((d-grades[i])<3){
array[i]=d;
}else{
array[i]=grades[i];
}
d=0;
c=0;
}
return array ;
Now I tried running this function, and the compiler gives shows no error in the program in the code, however the code doesn't print anything.
Someone Please help.
First, I have to say that this code is extremely inefficient. Finding the difference between the closest muliplication of 5 and a number can be simply done by:
int difference = (n - (n + 4) / 5 * 5) - n;
Explanation: C++ is rounding down the division, so (n + 4) / 5 is n / 5 rounded up, and hence (n+4)/5*5 is the closest multiplication of 5.
Another thing, you declare an array but never resize it, so its size is 0. You need to resize it either by specifying the size in the constructor or using the std::vector::resize method.
code:
std::vector<int> gradingStudents(std::vector<int> grades) {
std::size_t size = grades.size();
std::vector<int> array(size);
for (int i = 0; i < size; i++) {
int closestMul = (grades[i] + 4) / 5 * 5;
if (closestMul - grades[i] < 3) {
array[i] = closestMul;
}
else {
array[i] = grades[i];
}
}
return array;
}
Proably your code is crashing, which is why it doesn't print anything. And one reason it might be crashing is your vector use is wrong.
It's very common to see beginners write code like this
vector<int> array;
for (int i=0;i<size;i++) {
array[i] = ...;
But your vector has zero size. So array[i] is an error, always.
Two possible solutions
1) Make the vector the correct size to begin with
vector<int> array(size);
for (int i=0;i<size;i++) {
array[i] = ...;
2) Use push_back to add items to the vector, every time you call push_back the vector increases in size by one.
vector<int> array(size);
for (int i=0;i<size;i++) {
array.push_back(...);
And please don't call your vector array, that's just taking the piss.
i feel nothing is wrong with your function but calling of this function is a bit tricky let me give you a quick main to try may be that will help you.
int main() {
vector <int> test ;
test.push_back(1);
test.push_back(2);
gradingStudents(test);
return 0;
}
Try initially the size of the vector is empty i hope you are sending something from the main . Your code is very inefficient whenever you find time must read how to write an efficient code.
Related
I am learning DSA and while practising my LeetCode questions I came across a question-( https://leetcode.com/problems/find-pivot-index/).
Whenever I use vector prefix(size), I am greeted with errors, but when I do not add the size, the program runs fine.
Below is the code with the size:
class Solution {
public:
int pivotIndex(vector<int>& nums) {
//prefix[] stores the prefix sum of nums[]
vector<int> prefix(nums.size());
int sum2=0;
int l=nums.size();
//Prefix sum of nums in prefix:
for(int i=0;i<l;i++){
sum2=sum2+nums[i];
prefix.push_back(sum2);
}
//Total stores the total sum of the vector given
int total=prefix[l-1];
for(int i=0; i<l;i++)
{
if((prefix[i]-nums[i])==(total-prefix[i]))
{
return i;
}
}
return -1;
}
};
I would really appreciate if someone could explain this to me.
Thanks!
You create prefix to be the same size as nums and then you push_back the same number of elments. prefix will therefore be twice the size of nums after the first loop. You never access the elements you've push_backed in the second loop so the algorithm is broken.
I suggest that you simplify your algorithm. Keep a running sum for the left and the right side. Add to the left and remove from the right as you loop.
Example:
#include <numeric>
#include <vector>
int pivotIndex(const std::vector<int>& nums) {
int lsum = 0;
int rsum = std::accumulate(nums.begin(), nums.end(), 0);
for(int idx = 0; idx < nums.size(); ++idx) {
rsum -= nums[idx]; // remove from the right
if(lsum == rsum) return idx;
lsum += nums[idx]; // add to the left
}
return -1;
}
If you use vector constructor with the integer parameter, you get vector with nums.size() elements initialized by default value. You should use indexing to set the elements:
...
for(int i = 0; i < l; ++i){
sum2 = sum2 + nums[i];
prefix[i] = sum2;
}
...
If you want to use push_back method, you should create a zero size vector. Use the constructor without parameters. You can use reserve method to allocate memory before adding new elements to the vector.
I am writing a code that takes an array of 10 and collects user input. I want to print out the array after the user has finished putting all the values into it. The problem is that when I printout the array it gives me a bunch of garbage values and a weird output. I am not sure why it is doing what it is doing.
This is my code:
#include <iostream>
#include<ctime>
using namespace std;
int main(){
int num;
int arr[10] = {0};
cout<<"Enter 10 numbers: "<< endl;
for(int i = 0; i < 10; i++){
cin>>arr[i];
}
for(int i = 0; i < sizeof(arr); i++){
cout<<arr[i]<< " ";
}
return 0;
}
That is because you are running the loop from 0 till sizeof(arr), here sizeof(arr) means the size of array in bytes. Which happens to be sizeof(int) times the number of elements in the array.
So if we consider sizeof(int) to be 4bytes(i.e. each int takes 4bytes in memory), and number of elements to be 10, then it would be 4*10 = 40. So the for loop would run for 40 times.
Instead do the following:
#include <iostream>
#include<ctime>
using namespace std;
int main(){
int num;
int arr[10];
cout<<"Enter 10 numbers: "<< endl;
for(int i = 0; i < (sizeof(arr)/sizeof(arr[0])); i++){
cin>>arr[i];
}
for(int i = 0; i < (sizeof(arr)/sizeof(arr[0])); i++){
cout<<arr[i]<< " ";
}
return 0;
}
As pointed out by #user4581301, it's better to make the loop stop taking input at (sizeof(arr)/sizeof(arr[0])), as the size can be changed laterwards.
I have corrected it. It will work now.
Why you are getting garbage values is very well explained in the other answers. You can use std::begin and std::end or range-based for-loop here for iterating through the array. C++ is smart enough to deduce the length of the array for you.
int main(){
int arr[10]{0};
/* Take inputs from the console and fill the array here. */
auto start = std::begin(arr);
auto end = std::end(arr);
for(; start!=end; ++start)
std::cout<<*start<<" ";
// Or using range-based for-loop
for(auto val: arr)
std::cout<<val<<" ";
}
sizeof(arr) is the total size in bytes of the array, not the number of elements. That's probably 40 rather than 10, Because the typical compiler targeting desktop PC hardware uses a 32 bit int at this time.
If your compiler's up to date and supports at least the C++17 Standard revision, use std::size to get the number of elements in the array, but a better option (supported back to C++11) is to use range-based for loops and let the compiler figure out the bounds for you. This makes changes to the count of elements in arr self-managing.
Eg:
for(auto & val:arr){
cin>>val;
}
for(auto & val:arr){
cout<<arr[i]<< " ";
}
If range-based for and std::size are not available, define and use a constant value everywhere you use 10 or sizeof(arr).
Eg:
const int ARR_SIZE = 10;
and then the definition of arr becomes
int arr[ARR_SIZE] = {0};
and the control for both for loops become
for(int i = 0; i < ARR_SIZE; i++)
This allows you to vary the size of arr with only one change required to make the code function correctly. This is also less cumbersome than repeating sizeof(arr)/sizeof(arr[0]) everywhere the number of elements in arr is needed.
I tried to generate 25 arrays, each of them should contains number 1 to 25 without repetition and out of order. I executed the code to generate an array, there was no repetition. There were repeating numbers in the array when I tried to map the array into the 2D array.
Here is my code
int permutation(int arraystore[]){
int item[25], index;
for (int x = 0; x < 25; x++)
item[x] = x; //input values into item array
for (int x = 25; x > 0; x--) {
index = rand() % x; //generate random numbers
arraystore[x] = item[index];
while (index < x - 1) {
item[index] = item[index + 1];
index++;
}
}
}
I map the arraystore into the 2d array in main
int main(){
int ddarray[25][25];
for(int j=0;j<25)
for(int i=0;i<25;i++){
int array[25];
permutation(array);
ddarray[j][i]=array[i];
}
}
Here are some of results
192,9,7,3,11,20,18,9,23,11,21,5,11,17,5,12,11,3,10,9,2,5,7,7,19,
192,5,0,14,23,22,6,2,20,24,13,12,21,24,21,6,11,21,1,20,5,8,6,12,15,
192,21,6,14,14,11,11,8,17,19,9,24,22,6,24,11,2,22,6,13,2,18,6,14,20,
Did I do any wrong in the permutation function or miss something?
Thank you for answering my question!
There are several things that could/must be improved here.
First off, I would recommend using std::shuffle instead of rolling your own version.
The main issue that makes your program illegal C++: If x is 25, then you try to write to arraystore[x], which is past the end of a 25 element array. You probably want to write to arraystore[x-1].
The main issue that gives you repeating output: You are randomizing a new array for every i in the inner loop and then only use the ith element (so you generate 25*25 arrays with 25 elements each). It can happen (in fact, it is exceedingly likely) that you repeat some elements this way. The correct main would look like this:
int main() {
int ddarray[25][25];
for (int j=0; j<25; ++j)
{
int array[25];
permutation(array);
for (int i=0; i<25; i++) {
ddarray[j][i] = array[i];
}
}
}
(Note that a ++j was missing in your original code too...)
Your implementation of permutation is pretty inefficient, because it has to move lots of elements for every single output element. The standard Fischer Yates shuffle just swaps the elements at the current output and randomly chosen index.
Finally, I would suggest using std::array (or std::vector) instead of plain arrays. The latter are very inconvenient/surprising to work with (and have no standard-support for different sizes at runtime).
A simple implementation in C++11 based on std::shuffle could look like this:
int main() {
std::random_device rd;
std::mt19937 g(rd());
std::array<std::array<int, 25>, 25> ddarray;
for (auto& a : ddarray) {
std::iota(a.begin(), a.end(), 1);
std::shuffle(a.begin(), a.end(), g);
}
}
Live demo: https://wandbox.org/permlink/0abgD0Yqv9K1B1D9.
My code is to extract odd number and even number in an 1D array.
#include <iostream>
using namespace std;
int main() {
int a[6] = {1,6,3,8,5,10};
int odd[]={};
int even[]={};
for (int i=0; i < 6; i++) {
cin >> a[i];
}
for (int i=0; i < 6; i++) {
if (a[i] % 2 == 1) {
odd[i] = a[i];
cout << odd[i] << endl;
}
}
cout << " " << endl;
for (int i=0; i < 6; i++) {
if (a[i] % 2 == 0) {
even[i] = a[i];
cout << even[i] << endl;
}
}
return 0;
}
the output is:
1
3
5
2
1
6
It shows that it successfully extract odd numbers but the same method applied to the even number. It comes with an issue while the even number is 4.
Could anyone help me find the cause here? Thanks.
You've got an Undefined Behavior, so result may be any, even random, even formatted hard drive.
int odd[] = {} is the same as int odd[/*count of elements inside {}*/] = {/*nothing*/}, so it's int odd[0];
Result is not defined when you're accessing elements besides the end of array.
You probably have to think about correct odd/even arrays size, or use another auto-sizeable data structure.
First, although not causing a problem, you initialize an array with data and then overwrite it. The code
int a[6] = {1,6,3,8,5,10};
can be replaced with
int a[6];
Also, as stated in the comments,
int odd[]={};
isn't valid. You should either allocate a buffer as big as the main buffer (6 ints) or use a vector (although I personally prefer c-style arrays for small sizes, because they avoid heap allocations and extra complexity). With the full-size buffer technique, you need a value like -1 (assuming you intend to only input positive numbers) to store after the list of values in the arrays to tell your output code to stop reading, or store the sizes somewhere. This is to prevent reading values that haven't been set.
I don't understand your problem when 4 is in the input. Your code looks fine except for your arrays.
You can use std::vector< int > odd; and then call only odd.push_back(elem) whem elem is odd.
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int main() {
int t,m,n;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&m,&n);
int rootn=sqrt(double(n));
bool p[10000]; //finding prime numbers from 1 to square_root(n)
for(int j=0;j<=rootn;j++)
p[j]=true;
p[0]=false;
p[1]=false;
int i=rootn;
while(i--)
{
if(p[i]==true)
{
int c=i;
do
{
c=c+i;
p[c]=false;
}while(c+p[i]<=rootn);
}
};
i=0;
bool rangep[10000]; //used for finding prime numbers between m and n by eliminating multiple of primes in between 1 and squareroot(n)
for(int j=0;j<=n-m+1;j++)
rangep[j]=true;
i=rootn;
do
{
if(p[i]==true)
{
for(int j=m;j<=n;j++)
{
if(j%i==0&&j!=i)
rangep[j-m]=false;
}
}
}while(i--);
i=n-m;
do
{
if(rangep[i]==true)
printf("%d\n",i+m);
}while(i--);
printf("\n");
}
return 0;
system("PAUSE");
}
Hello I'm trying to use the sieve of Eratosthenes to find prime numbers in a range between m to n where m>=1 and n<=100000000. When I give input of 1 to 10000, the result is correct. But for a wider range, the stack is overflowed even if I increase the array sizes.
A simple and more readable implementation
void Sieve(int n) {
int sqrtn = (int)sqrt((double)n);
std::vector<bool> sieve(n + 1, false);
for (int m = 2; m <= sqrtn; ++m) {
if (!sieve[m]) {
cout << m << " ";
for (int k = m * m; k <= n; k += m)
sieve[k] = true;
}
}
for (int m = sqrtn; m <= n; ++m)
if (!sieve[m])
cout << m << " ";
}
Reason of getting error
You are declaring an enormous array as a local variable. That's why when the stack frame of main is pushed it needs so much memory that stack overflow exception is generated. Visual studio is tricky enough to analyze the code for projected run-time stack usage and generate exception when needed.
Use this compact implementation. Moreover you can have bs declared in the function if you want. Don't make implementations complex.
Implementation
typedef long long ll;
typedef vector<int> vi;
vi primes;
bitset<100000000> bs;
void sieve(ll upperbound) {
_sieve_size = upperbound + 1;
bs.set();
bs[0] = bs[1] = 0;
for (ll i = 2; i <= _sieve_size; i++)
if (bs[i]) { //if not marked
for (ll j = i * i; j <= _sieve_size; j += i) //check all the multiples
bs[j] = 0; // they are surely not prime :-)
primes.push_back((int)i); // this is prime
} }
call from main() sieve(10000);. You have primes list in vector primes.
Note: As mentioned in comment--stackoverflow is quite unexpected error here. You are implementing sieve but it will be more efficient if you use bistet instead of bool.
Few things like if n=10^8 then sqrt(n)=10^4. And your bool array is p[10000]. So there is a chance of accessing array out of bound.
I agree with the other answers,
saying that you should basically just start over.
Do you even care why your code doesn’t work? (You didn’t actually ask.)
I’m not sure that the problem in your code
has been identified accurately yet.
First of all, I’ll add this comment to help set the context:
// For any int aardvark;
// p[aardvark] = false means that aardvark is composite (i.e., not prime).
// p[aardvark] = true means that aardvark might be prime, or maybe we just don’t know yet.
Now let me draw your attention to this code:
int i=rootn;
while(i--)
{
if(p[i]==true)
{
int c=i;
do
{
c=c+i;
p[c]=false;
}while(c+p[i]<=rootn);
}
};
You say that n≤100000000 (although your code doesn’t check that), so,
presumably, rootn≤10000, which is the dimensionality (size) of p[].
The above code is saying that, for every integer i
(no matter whether it’s prime or composite),
2×i, 3×i, 4×i, etc., are, by definition, composite.
So, for c equal to 2×i, 3×i, 4×i, …,
we set p[c]=false because we know that c is composite.
But look closely at the code.
It sets c=c+i and says p[c]=false
before checking whether c is still in range
to be a valid index into p[].
Now, if n≤25000000, then rootn≤5000.
If i≤ rootn, then i≤5000, and, as long as c≤5000, then c+i≤10000.
But, if n>25000000, then rootn>5000,†
and the sequence i=rootn;, c=i;, c=c+i;
can set c to a value greater than 10000.
And then you use that value to index into p[].
That’s probably where the stack overflow occurs.
Oh, BTW; you don’t need to say if(p[i]==true); if(p[i]) is good enough.
To add insult to injury, there’s a second error in the same block:
while(c+p[i]<=rootn).
c and i are ints,
and p is an array of bools, so p[i] is a bool —
and yet you are adding c + p[i].
We know from the if that p[i] is true,
which is numerically equal to 1 —
so your loop termination condition is while (c+1<=rootn);
i.e., while c≤rootn-1.
I think you meant to say while(c+i<=rootn).
Oh, also, why do you have executable code
immediately after an unconditional return statement?
The system("PAUSE"); statement cannot possibly be reached.
(I’m not saying that those are the only errors;
they are just what jumped out at me.)
______________
† OK, splitting hairs, n has to be ≥ 25010001
(i.e., 50012) before rootn>5000.