Insert values from long variable into array and read values - c++

I'm working on a program that takes a long variable (x) and stores it into an array, then is able to read the separate values both reversed and in order. I've used a while loop in order to store the values but am a little stuck getting the program to read the values, but practices like this will help my understanding of the subject in the long run. Any advise on where I'm making a mistake would be great, thanks in advance! I'm still kind of a n00b with arrays in C++
int arr[]={};
long x;
int i=0;
int j;
cout<<"Enter value to be stored: "<<endl;
cin>>x;
while(x>0){
int lastdigit=x%10;
arr[i]=lastdigit;
x=x/10;
}
if(arr[i]>0){
for(j=i-1;j>-1;j--){
cout<<"Array values "<<arr[j];
}
}
}
This is just to read the array values in order, I'll add the reversal once I get this part down.

Your fundamental error is here
int arr[] = {};
this creates a zero size array if it was allowed but on my machine its not even valid syntax
cannot allocate an array of constant size 0 ConsoleApplication1 C:\work\ConsoleApplication1\ConsoleApplication1.cpp 12
I changed it to
int arr[12] = {};
since 10 decimal digits is enough for a 32 bit integer, plus one to be sure, and another one just in case :-)
Next mistake is you never increment i in the mod / divide loop
Then finally you test arr[i] > 0. This is not needed, take it out
Now your code works fine
PS. Make arr a std::vector<int> so it will grow rather than hard coding to 12 digits

Related

Time Limit Exceeded in dealing with large arrays

I'm trying to solve this question:
As we all know that Varchas is going on. So FOC wants to organise an event called Finding Occurrence.
The task is simple :
Given an array A[1...N] of positive integers. There will be Q queries. In the queries you will be given an integer. You need to find out the frequency of that integer in the given array.
INPUT:
First line of input comprises of integer N, the number of integers in given array.
The next line will comprise of N space separated integers. The next line will be Q, number of Queries.
The next Q lines will comprise of a single integer whose Occurrence you are supposed to find out.
OUTPUT:
Output single integer for each Query which is the frequency of the given integer.
Constraints:
1<=N<=100000
1<=Q<=100000
0<=A[i]<=1000000
And this is my code:
#include <iostream>
using namespace std;
int main()
{
long long n=0;
cin >> n;
long long a[1000000];
for (int i=1;i<=n;i++)
{
cin >> a[i];
}
long long q=0;
cin >> q;
while (q--)
{
long long temp=0,counter=0;
cin >> temp;
for (int k=1;k<=n;k++)
{
if (a[k]==temp)
counter++;
}
cout << "\n" << counter;
temp=0;
counter=0;
}
return 0;
}
However, I encountered the 'Time Limit Exceeded' error. I suspect this is due to the failure to handle large values in arrays. Could someone tell me how to handle such large size arrays?
The failure is in the algorithm itself, note that for each query, you traverse the whole array. There are 100,000 queries and 100,000 elements. That means at worse case you're traversing 100,000 * 100,000 elements = 10,000,000,000 elements, which won't finish in time. If you analyze the complexity using the Big-O notation, your algorithm is O(nq), which is too slow for this problem, since n*q are large.
What you're supposed to do is to calculate the scores before any query is made, then store in an array (this is why the range of A[i] is given. You should be able to do this by traversing the array only once. (hint: you don't need to store the input into an array, you can just count directly).
By doing this, the algorithm will just be O(n), and since n is small enough (as a rule of thumb, less than one million is small), it should finish in time.
Then you can answer each query instantly, making your program fast enough to be under the time limit.
Another thing that you can improve is the data type of the array. The value stored in that array won't be larger than 1 million, and so you don't need long long, which uses more memory. You can just use int.
Your algorithm was inefficient. You read all the numbers into an array, then you searched linearly through the array for each query.
What you should have done is make one array of counts. In other words, if you read the number 5, do count[5]++. Then for each query all you have to do is return the count from the array. For example, how many 5's were there in the array? Answer: count[5].
Since your maximum number can be 10^6, I think that your problem will take memory limit exceeded, even if it fits in time. Another solution is to sort the array( you can do it in N*logN using STL sort function) and for each query you can make two binary searches. First is used to find the first position where the element appears and the second is used to find the last position where your element appears, so the answer for each query will be lastPosition - firstPosition + 1.

Wrong result for code doing dynamic programming in C++

I am solving a dp problem .The problem is that I have N dices; each of them has K faces numbered from 1 to K. Now I have arranged the N dices in a line. I can rotate/flip any dice if I want. How many ways I can set the top faces such that the summation of all the top faces equals S?
Now I am given N, K, S; I have to calculate the total number of ways.It is worthy of mention I have to print the result modulo 100000007.I have tried to solve this problem and write a code for this one but my code doesn't work for this case:800 800 10000 why? I can't understand .Can anyone explain the cause for which my code doesn't work. My code is here:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<memory.h>
#define M 100000007
#define ull unsigned long long
using namespace std;
ull n,K,s,dp[1001][1001];
ull fnc(int num,int sum,int k)
{
ull temp;
if(num==0){
if(sum==0) return 1;
else return 0;
}
if(dp[num][k]!=-1)
return dp[num][k];
for(int i=1;i<=K;i++)
{
temp=temp%M+fnc(num-1,sum-i,i)%M;
}
return dp[num][k]=temp%M;
}
int main()
{
int T;
cin>>T;
for(int t=1;t<=T;t++)
{
cin>>n>>K>>s;
memset(dp,-1,sizeof(dp));
printf("Case %d: %lld\n",t,fnc(n,s,0));
}
return 0;
}
You used the wrong subscripts for dp.
Consider how many ways you can get 800 dice, each with numbers from 1 to 800,
to have the sum 10000 if you make the number 1 uppermost on the first die
and you make 4 uppermost on the second die.
Now consider how many ways to have the sum 10000 if you make 2 uppermost on the first die
and 3 uppermost on the second die.
Those two quantities are the same: each is the number of ways to get 798 dice (with numbers 1 to 800) to have the sum 99995. That is the kind of quantity you want to memoize.
But you have not even allocated enough space in dp to store this kind of partial answer.
I also have to wonder why you are using unsigned long long rather than just unsigned long, since your answer is to be given modulo 100000007. You should never have to
work with numbers that are even near the maximum value of a signed long.
According to http://linux.die.net/man/3/memset :
The memset() function fills the first n bytes of the memory area pointed to by s with the constant byte c.
Note it doesn't say "the constant unsigned long long c".
You have the value k and K defined in the same scope, which is infuriating.
You hard coded 1001 and -1 instead of giving them proper soft coded variable names.
Most of your variable names are 1 character long.
You have persistent behavior in a return statement.
You have absolutely nothing checking if the values of k, K, and num are within the proper range of dp, which is partially a consequence of hard coding 1001.
Spacebar is your friend, writingcodelikethisthatwehavetoreadisannoying.

Segmentation Fault C++ (array too large?)

I'm working on the Project Euler Problem 14, where I need to find the longest collatz sequence under 1,000,000. I've come up with an algorithm that works for smaller numbers (say, 100) that stores each collatz number from 1 - 100 into an array and uses that array as a reference to speed up the computations for higher numbers.
My code is as follows:
#include <iostream>
using namespace std;
long even(long n){ //the even-collatz function
n=n/2;
return n;
}
long odd(long n){ //the odd collatz function
n=3*n+1;
return n;
}
int main(){
long x, c=0, y[1000000]; // x= the number we are finding the collatz number of, c a counter that keeps track of how many steps we've taken in the sequence, y is an array to store the collatz numbers.
for (x=1; x<1000000; x++){ //iterates from x=1 to 1 million
long a = x; //sets a number a equal to the number we are currently trying to find the collatz number of
long b = a;
c=0; //intializes counter at 0
while (a!=0){ //loops infinitely; the only way to exit is through a break.
if (a%2==0){ // detects if the number is even
a=even(a); //applies the even-collatz function if so; sets x=x/2
c=c+1;
if (y[a]!=0){ // checks if the collatz number of x is already discovered
y[b]=c+y[a]; //adds the current number of steps to the collatz number of x and
break; //exits the while loop
}
}
else if (a==1){ //checks if the new x is equal to one and
y[b]=c; //if it is, it writes the current value of c to y[b] and
break; // exits the loop
}
else if (a%2==1){ //same as the "even" block, except for odd numbers
a=odd(a);
c=c+1;
if( y[a]!=0){
y[b]=c+y[a];
break;
}
}
//this is the end of the while loop; we've applied the collatz function as many times as we've needed to to x, and incremented the counter each time
}
}
long z;
for (int n=0;n!=100;n++){
if (y[n+1]>y[n]){
z=y[n+1];
}
}
cout << z << "\n";
}
The issue I'm having is that I get a segfault after x=1818 in the for loop. Through debugging, I've found that how quickly the segfault occurs depends on the size of array y, so I'm assuming that the array is just too big. From my (basic) understanding of segfaults, I think I'm just accessing memory that I'm "not allowed". Is there any way for me to circumvent this, or should I just start working towards another solution to this problem? I'm compiling using g++ on Ubuntu studio.
This array is probably too big for your system's default stack size; the simplest fix is to change its definition to:
std::vector<long> y(1000000);
and everything else can stay the same. You could use y.size() instead of the magic number 1000000 later in your loop.
For a starting number under N collatz sequence can go way beyond N. For N == 1000000 consider x == 333335.
I would suggest you to make y a vector<int> and expand it dynamically, or just make it unordered_map<int, int>.
If y was too big for your stack, you would get a stack overflow exception as soon as main tried to run.
Your problem is more likely that a gets bigger than the size of y.
When I ran it through the debugger, a was 1417174 when x was 4255, so you might have a problem with your algorithm.
That said, you should either allocate it yourself, or make it static, as there is no guarantee that whatever compiler Project Euler uses will allow such a large stack size.

C++ array (Beginner)

I misstook arrays for vectors, Sorry (array is vektor in swedish)
I would need some help with a program I'm making. It is a assignment so I really need to understand how I do this and not just get the code :P
I need to make a array containing 10 "numbers" (I would like to make them editable when the program is running).
After I'v done this I need to make the program calculate the "average value" of all the numbers "/
Would be pretty neat if you could pick how many numbers you wanted the average value of as well, if anyone could share some knowledge in how I should to that :P
Anyways, I'v tried some code to make the vector that didn't work, I might as well add it here:
int vector[10];
and
vector[0] "number 1: ";
and so on for the input of numbers in the vector.
int sum = vector[0] + vector[1] + ...
cout << "average value is: " << sum/5;
should work for getting the average value though (right?)
I should allso add:
float average(int v[], int n)
to this thing as well, can't really se how though.
Any help/knowledge at all would be awesome! Cheers.
To pick how many numbers you wanted to average:
Native: (G++/Clang) only, not "legal" C++
cin >> num;
int vector[num];
"Correct" native (pointers):
int *vector = new int [num];
"Proper" C++:
#include <vector>
std::vector<int> v(num);
A function like following would work for computing average of an array containing n elements.
float average(int v[], int n)
{
float sum = 0;
for(int i = 0 ; i < n ; i++)
{
sum += v[i]; //sum all the numbers in the vector v
}
return sum / n;
}
You can declare your array as you have done however i do recommend you to name it something else then vector to avoid confusion. About tour issue with changing the numbers in the array you can do this by for example maning a loop going from one to 10 and then make the user enter values for all the fields.
Vektor på svenska = array på engelska (vector är något annat :))
If you want exactly 10 numbers, you can eliminate a lot of overhead by simply using an array. However, assuming you want to use a vector, you can easily find the average taking advantage of its "size" member, as such:
float average(std::vector<int> nums)
{
int sum = 0;
for (unsigned int i = 0; i < nums.size(); i++)
sum += nums[i];
return sum / nums.size();
}
Note that this does assume the sum won't be higher than 2^31-1, IE the highest number a signed integer can represent. To be safer you could use an unsigned and/or 64 bit int for sum, or some arbitrary precision library like gmp, but I'd assume that is all outside the scope of your assignment.
You must declare and array of size 10, which you have done.
Use a loop to get ten inputs from the user.
(for or while loops would do)
Use another loop to calculate the sum of all ten numbers and store it in a variable.
Divide the variable by ten.
This is what you need to do essentially. But, to make your driver program prettier, you can define the following functions:
void GetInput(int *A); //put the input loop here
You can also write any one of the given two functions:
long Sum(int * A) //put the summing loop here
double Average(int * A) //put the summing loop here AND divide the sum by ten
Since you are a beginner I feel obliged to tell you that you don't need to return an array since it isalways passed as a reference parameter. I did not bother to pass the array size as a parameter to any functions because that is fixed and known to be 10 but it will be good practice to do that.

Getting a memory address in my array?

I'm writing a C++ application that has a user enter a 0 (zero) or a one (1) as input, then stores the numbers as an array and sorts them so that the zeros come first and the ones come last.
However, I think I'm getting a memory address in my array that's messing up the sorting operation.
The function that accepts input looks like this:
cout << "Please enter number " << i+1 << ":\n";
cin >> ar[i];
Then there's a function that's called that sorts the input and displays the sorted list:
sort_elements(ar, number);
... and that function looks like this:
void sort_elements(int ar[], long int num_elements) {
int temp_num;
num_elements -= 1; //since the array starts at 0
cout << "num_elements is " << num_elements << "\n";
for (int i=0; i < (num_elements/2); i++ ) {
if (ar[i] > ar[num_elements-i]) {
temp_num = ar[i];
ar[i] = ar[num_elements-i];
ar[num_elements-i] = temp_num;
}
}
cout << "Here's your neatly sorted list of numbers: \n";
for (int j=0; j <= num_elements; j++) {
cout << ar[j] << ", ";
}
cout << "\n";
}
For a five number input, starting with three "1"s, and ending with two "0"s, this results in an output that looks like this:
1, 0, 1, 1, 1892218304,
I'm assuming the 1892218304 is a memory address, that's messing up the input. Though I don't really know.
Can anyone figure out why my sort operation is getting messed up?
Thanks in advance.
Suggestion
Use vector and sort in standard library
#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
int main()
{
std::vector<int> v;
for(int i=0; i < 10; i++)
{
v.push_back(i);
}
std::sort(v.begin(), v.end());
return 0;
}
The number you are seeing is not a memory address, but the value of the 4 bytes either immediately before or immediately after your array, interpreted as an int. Your code has an off-by-one error that causes an access to just outside the array. That much I suspect even though I don't have proof.
However, I can't find anything wrong with the code you posted that would cause it to access outside the array bounds.
Are you sure that num_elements has the correct value when this function is called?
Update to address the pastebin code
Things are going wrong already from the start:
int number;
int ar[number]
This is called a variable-length array and it's not legal in C90 or any flavor of C++. That your program compiles is probably "thanks to" a compiler extension... which helpfully raises a bug: the value of number is not initialized before the array is allocated.
You need to do one of the following:
declare ar as an array of constant size (a hard limit on the number of inputs you can accept)
dynamically allocate ar with new[] after number is entered from the user
(by far preferable) use an std::vector instead of an array
It looks to me like you're just getting an uninitialized value in your output.
Under the circumstances, the simplest "sorting" method is probably a counting sort -- i.e., count the number of 0's and the number of 1's the user enters, and then print out the appropriate number of 0's followed by the appropriate number of 1's.
As Tony said, your sorting algorithm is incorrect.
If we assume the following values:
ar[0] = 0
ar[1] = 1
ar[2] = 0
ar[3] = 1
ar[4] = 0
that gives us num_elements equal to 5.
Running this through your function as written, we get the following sorting behavior:
First pass, i = 0
ar[0] > ar[4] -> not true, so no switch
Secon pass, i = 1
ar[1] > ar[3] -> not true, so no switch
There is no third pass, as your for loop condition is met
i = 2
num_elements/2 = 2
2 is not less than 2
So based on your code, you didn't sort anything. This is the first issue.
Your print problem is interesting, based on what you have shown num_elements has been decremented by 1 at the top of your code snippet in your function - therefore the <= condition is correct and you should not be outside the bounds of your 'ar' array. Are you sure this is the exact code, or perhaps you did not copy it properly here and you are actually having a scoping issue?
(EDIT: Although the other answers suggesting using a built in sorting method via vectors, I'd suggest you still work your current implementation out to figure out WHY this is wrong, and what you need to do to fix it. You will not always have an available type that has built in sorting, so understanding the fundamentals is important for any young programmer.)
EDIT2: Based on the link you provided, you aren't properly defining your integer array. You are defining the array based on an uninitialized integer (int ar[number]) when number has not yet been initialized. You then read a value from the standard input to set number, and assume your array has been dynamically adjusted to be of the size read from cin. It does not work this way. Your entire loop is reading/writing outside the bounds of your array which is a big no-no. You want to read the number first, and then define your array based on the size read. - Looks like Jon beat me again.. BAH! :P
The last element being read and printed to the screen has never been written to. I think it's likely your function which accepts input has a fault, like maybe you have a line like you have here
num_elements -= 1; //since the array starts at 0
at the input function so that the first element you write to is at address 1. Then when you're reading them you read from address zero.
I kind of agree with Jim's point: Use the facilities in the C++ standard library to finish your task as much as possible.
Besides, I suggest you go through the algorithm all by yourself, manually, instead of letting the computer run it for you. Ever heard of the "Rubber Duck Debugging Method"? :-) Have a try.