What is the principle of tellp() calculating the length of stringstream? - c++

I think the length ofstringstream is calculating by the blocks.that means how many blocks in it, how long it is.the blocks is splited by '\t' '\s' '\n'.
for example, stringstream = '23\t45\t5.677\t' , its length should be 6. The delimiter should be counted.
I just can verify my idea while the type of arguments are all int.
here is my code.
I wonder that s_double.tellp() is not 10.
#include<iostream>
#include<sstream>
#include<cstdlib>
using namespace std;
int main()
{
stringstream s_int;
stringstream s_double;
srand((unsinged)time(NULL));
for(int index = 0;index<5;index++)
{
double random = rand() / (double) RAND_MAX * 5;
s_int<<index<<'\t';
s_double<<random<<'\t';
}
cout<<s_int.tellp()<<'\n';
cout<<s_double.tellp()<<'\n';
exit(0);
}
output:
10
40
after I changed the range of random, the output of s_double changed too.
double random = rand() / (double) RAND_MAX *9;
output:
10
42

The easiest but not faster method is:
auto nLength = strm.str().length();
Regarding s_double position - it is easy to answer your question by examining the content of this stream in a debugger or print it. You will see that double could be "0.554213" for 0.554212545 or "1" for 1 so string length for defferent doubles is complitely different.

Related

How to find year using mod function?

I want to know the mod function. It's like we've been searching for years after using the mod function in Excel. Can we do the same in c++?
For example, when mod in Excel,
Id = 199734902138
= mod(id,100000000)
As the answer,
34902138
Then id - 34902138
As the answer,
199700000000
Then 199700000000/100000000
Then we can get as the answer 1997
This is the year 1997
How to do the same thing in c++ using mod as mentioned above? I want to know that. Can you please help with that?
In C++, % is modulo operator, like
long int ID = 199734902138;
long int m = ID % 100000000; // results 34902138
int year = (ID - m) / 100000000; // results 1977
But a simple division does the same thing in C++, because an integer divided by an integer results another integer
int year = 199734902138 / 100000000; // results 1977
Modulo doesn't find year, it returns the remainder after a division.
The modulo operator is %.
For example:
#include <iostream>
int main() {
int x;
x = 10 % 8;
std::cout << x << std::endl; // output is 2
return 0;
}
Given your example, the following code would perform the same order of operations as your question. Notice the use of the long long int data type. Values this high (12-digit numbers) can only be expressed using long long int type.
#include <iostream>
int main() {
// declare variable id = 199734902138 and initial answer
long long int id = 199734902138;
long long int answer = id % 100000000;
// answer is now 199700000000
answer = id - answer;
//final calculation, divide the answer by 100000000
id = answer / 100000000;
// output id for verification
std::cout << id <<std::endl;
return 0;
}
As mentioned, this is all a bit superfluous as a simple divide operation will yield the same result, however if these steps need to be explicitly used in your calculation, then the code above would fit.

pigeon hole / multiple numbers

input : integer ( i'll call it N ) and (1 <= N <= 5,000,000 )
output : integer, multiple of N and only contains 0,7
Ex.
Q1 input : 1 -> output : 7 ( 7 mod 1 == 0 )
Q2 input : 2 -> output : 70 ( 70 mod 2 == 0 )
#include <string>
#include <iostream>
using namespace std;
typedef long long ll;
int remaind(string num, ll m)
{
ll mod = 0;
for (int i = 0; i < num.size(); i++) {
int digit = num[i] - '0';
mod = mod * 10 + digit;
mod = mod % m;
}
return mod;
}
int main()
{
int n;
string ans;
cin >> n;
ans.append(n, '7');
for (int i = ans.length() - 1; i >= 0; i--)
{
if (remaind(ans, n) == 0)
{
cout << ans;
return 0;
}
ans.at(i) = '0';
}
return 0;
}
is there a way to lessen the time complexity?
i just tried very hard and it takes little bit more time to run while n is more than 1000000
ps. changed code
ps2. changed code again because of wrong code
ps3. optimize code again
ps4. rewrite post
Your approach is wrong, let's say you divide "70" by 5. Then you result will be 2 which is not right (just analyze your code to see why that happens).
You can really base your search upon numbers like 77777770000000, but think more about that - which numbers you need to add zeros and which numbers you do not.
Next, do not use strings! Think of reminder for a * b if you know reminder of a and reminder of b. When you program it, be careful with integer size, use 64 bit integers.
Now, what about a + b?
Finally, find reminders for numbers 10, 100, 1000, 10000, etc (once again, do not use strings and still try to find reminder for any power of 10).
Well, if you do all that, you'll be able to easily solve the whole problem.
May I recommend any of the boost::bignum integer classes?
I suspect uint1024_t (or whatever... they also have 128, 256, and 512, bit ints already typedefed, and you can declare your own easily enough) will meet your needs, allowing you to perform a single %, rather than one per iteration. This may outweigh the performance lost when using bignum vs c++'s built-in ints.
2^1024 ~= 1.8e+308. Enough to represent any 308 digit number. That's probably excessive.
2^512 ~= 1.34e+154. Good for any 154 digit number.
etc.
I suspect you should first write a loop that went through n = 4e+6 -> 5e+6 and wrote out which string got the longest, then size your uint*_t appropriately. If that longest string length is more than 308 characters, you could just whip up your own:
typedef number<cpp_int_backend<LENGTH, LENGTH, unsigned_magnitude, unchecked, void> > myReallyUnsignedBigInt;
The modulo operator is probably the most expensive operation in that inner loop. Performing once per iteration on the outer loop rather than at the inner loop (O(n) vs O(n^2)) should save you quite a bit of time.
Will that plus the whole "not going to and from strings" thing pay for bignum's overhead? You'll have to try it and see.

Why does the following program gives wrong answer when I remove "+ mod" from statement check . Problem link: https://www.codechef.com/problems/FFC219B

The statement check is where I don't understand why it shows wrong answer on submission when I write "sum = (solution[R]-solution[L-1])%mod;" instead. Here I have not added mod within the bracket. I don't see how the answer changes by adding a value of taking the mod of same. Problem code in codechef: https://www.codechef.com/problems/FFC219B
#include<iostream>
#define ll long long
#define mod 1000000007 //the modulus we need to take for the final answer
#define endl "\n"
using namespace std;
long long solution[100007] = {0}; //Initialising all the values with zero
int main(){
ios_base :: sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solution[0] = 0;
ll a1=1,a2=2,a3=3,a4=4; //The variable initialising as per the problem
for(int i = 1;i <= 100007;i++){
ll k=(a1 * a2) % mod * a3 % mod * a4 % mod;
solution[i] = (solution[i-1]+k)%mod; //Adding the previous values as we are to find the sum in range
a1++;
a2++;
a3++;
a4++;
}
int t; //Taking input for number of test cases
cin>>t;
while(t-->0)
{
int L,R;
cin>>L>>R; //Taking the range input
long long sum = 0;
sum = (solution[R]-solution[L-1] + mod)%mod; //statement check & final answer
cout<<sum<<endl;
}
return 0;
}
The program can give the incorrect answer since the correct answer must always be a positive - not a negative - number.
When you subtract consecutive modulo values, the result may well be negative even though the numbers themselves are increasing (eg, (4^3)%10 - (4^2)%10 = 64%10 - 16%10 = 4-6 = -2), . This means “solution[R]-solution[L-1]” may also well be negative, which means “(solution[R]-solution[L-1]) % mod” will also be negative - although clearly the answer (the number of people affected) must always be positive.
So adding the mod value in this fashion ensures that the result will always be positive.

Logic error in writing the number twice in a row (C++)

I have been trying to implement something in C++ but apparently, there's a syntax error.
The following code yields "1 3100" when 31 is entered as input :
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
long long n; cin>>n;
long long j = floor((log10(n)));
long long nn = (n*((long long)pow(10,j+1)))+n;
cout<<j<<" "<<nn;
}
The following code yields "1 3130" for the same input, i.e, 31 :
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
long long n; cin>>n;
long long j = floor((log10(n)));
long long nn = (n*(pow(10,j+1)))+n;
cout<<j<<" "<<nn;
}
And I wished to produced "1 3131" for the input 31. Basically, I am trying to write the number twice in a row: the same thing that you get when you parse the number into string and add the same string twice (like, n=11, parse into s = "11" and then yield s+s).
So I want to multiply the input by a suitable power of ten to get enough "trailing zeros" and then add the input again.
Where am I going wrong? Also, why is there a difference between the two codes above? (Please explain why the first code gives that as an output and the second code that as an output and also help me with a newer code to get the desired output).
There is no syntax error, otherwise your code would not end up in an executeable to run.
The explanation for the unexpected output of "3130" is a misuse of a floating point function in an integer context.
long long n; cin>>n; // n becomes 31
long long j = floor((log10(n))); // j becomes 1
long long nn = (n*(pow(10,j+1)))+n; // the result from pow is a floating point just below 100
// integer-multiplied by 31 gives 3099
// adding 31 results in 3130
cout<<j<<" "<<nn; // output 3130

Why do I keep getting Nan as output?

I am trying to write a simple gradient descent algorithm in C++ (for 10,000 iterations). Here is my program:
#include<iostream>
#include<cmath>
using namespace std;
int main(){
double learnrate=10;
double x=10.0; //initial start value
for(int h=1; h<=10000; h++){
x=x-learnrate*(2*x + 100*cos(100*x));
}
cout<<"The minimum is at y = "<<x*x + sin(100*x)<<" and at x = "<<x;
return 0;
}
The output ends up being: y=nan and x=nan. I tried looking at the values of x and y by putting them into a file, and after a certain amount of iterations, I am getting all nans (for x and y). edit: I picked the learning rate (or step size) to be 10 as an experiment, I will use much smaller values afterwards.
There must be something wrong with your formula. Already the first 10 values of x are increasing like hell:
-752.379
15290.7
-290852
5.52555e+06
-1.04984e+08
1.9947e+09
-3.78994e+10
7.20088e+11
-1.36817e+13
2.59952e+14
No matter what starting value you choose the absolute value of the next x will be bigger.
|next_x| = | x - 20 * x - 100 * cos(100*x) |
For example consider what happens when you choose a very small starting value (|x|->0), then
|next_x| = | 0 - 20 * 0 - 100 * cos ( 0 ) | = 100
Because at h=240 the variable "x" exceeds the limits of double type (1.79769e+308). This is a diverging arithmetic progression. You need to reduce your learn rate.
A couple of more things:
1- Do not use "using namespace std;" it is bad practice.
2- You can use "std::isnan() function to identify this situation.
Here is an example:
#include <iomanip>
#include <limits>
int main()
{
double learnrate = 10.0;
double x = 10.0; //initial start value
std::cout<<"double type maximum=" << std::numeric_limits<double>::max()<<std::endl;
bool failed = false;
for (int h = 1; h <= 10000; h++)
{
x = x - learnrate*(2.0*x + 100.0 * std::cos(100.0 * x));
if (std::isnan(x))
{
failed = true;
std::cout << " Nan detected at h=" << h << std::endl;
break;
}
}
if(!failed)
std::cout << "The minimum is at y = " << x*x + std::sin(100.0*x) << " and at x = " << x;
return 0;
}
Print x before the call to the cosine function and you will see that the last number printed before NaN (at h = 240) is:
-1.7761e+307
This means that the value is going to infinity, which cannot be represented (thus Not a Number).
It overflows the double type.
If you use long double, you will succeed in 1000 iterations, but you will still overflow the type with 10000 iterations.
So the problem is that the parameter learnrate is just too big. You should do let steps, while using a data type with larger range, as I suggested above.
The "learn rate" is far too high. Change it to 1e-4, for example, and the program works, for an initial value of 10 at least. When the learnrate is 10, the iterations jump too far past the solution.
At its best, gradient descent is not a good algorithm. For serious applications you want to use something better. Much better. Search for Brent optimizer and BFGS.