unable to understand why adding zero in end after adding digits - c++

http://www.spoj.com/problems/JULKA/help me solve this question please .explain why we are adding zero in end after addition of bits.as commented in code below
#include <stdio.h>
#include <string.h>
#define MAX 111
char klaudia[MAX], natalia[MAX], total[MAX], diff[MAX];
void calc()
{
int len1 = strlen(total);
int len2 = strlen(diff);
int a, b, c, i, j, k, f;
char temp[MAX];
for(i=len1-1, j=len2-1, k=c=0; i>=0 || j>=0 || c; i--, j--, k++)
{
a = i>=0? total[i]-'0' : 0;
b = j>=0? diff[j]-'0' : 0;
temp[k] = (a+b+c)%10 + '0';
c = (a+b+c)/10;
}
temp[k] = 0;//explain
strcpy(klaudia,"0");
//explain below for loop what is actually being done in this loop//
for(i=k-1, j=a=f=0; i>=0; i--)
{
b = (a*10 + temp[i]-'0') / 2;
a = (a*10 + temp[i]-'0') % 2;
if(b) f = 1;
if(f) klaudia[j++] = b+'0';
}
if(!j) j++;
klaudia[j] = 0;
for(i=len1-1, j=len2-1, k=c=0; i>=0; i--, j--, k++)
{
a = total[i]-'0';
b = j>=0? diff[j]-'0' : 0;
if(a < b+c)
{
temp[k] = (10+a-b-c) + '0';
c = 1;
}
else
{
temp[k] = a-b-c + '0';
c = 0;
}
}
temp[k] = 0;
strcpy(natalia,"0");
for(i=k-1, j=a=f=0; i>=0; i--)
{
b = (a*10 + temp[i]-'0') / 2;
a = (a*10 + temp[i]-'0') % 2;
if(b) f = 1;
if(f) natalia[j++] = b+'0';
}
if(!j) j++;
natalia[j] = 0;
}
int main()
{
while(scanf("%s %s", total, diff)==2)
{
calc();
printf("%s\n%s\n", klaudia, natalia);
}
return 0;
}
why are we adding zeo in array temp after we have added all the digits

You are not computing with number but with character string. In C, character string are terminated by a Nul character whose code is zero.

Related

Rabin-Karp algorithm in c++

I am trying to understand the implementation of the Rabin-Karp algorithm. d is the number of characters in the input alphabet, but if I replace 0 or any other value instead of 20, it won't affect anything. Why is this happening like this ?
// Rabin-Karp algorithm in C++
#include <string.h>
#include <iostream>
using namespace std;
#define d 20
void rabinKarp(char pattern[], char text[], int q) {
int m = strlen(pattern);
int n = strlen(text);
int i, j;
int p = 0;
int t = 0;
int h = 1;
for (i = 0; i < m - 1; i++)
h = (h * d) % q;
// Calculate hash value for pattern and text
for (i = 0; i < m; i++) {
p = (d * p + pattern[i]) % q;
t = (d * t + text[i]) % q;
}
// Find the match
for (i = 0; i <= n - m; i++) {
if (p == t) {
for (j = 0; j < m; j++) {
if (text[i + j] != pattern[j])
break;
}
if (j == m)
cout << "Pattern is found at position: " << i + 1 << endl;
}
if (i < n - m) {
t = (d * (t - text[i] * h) + text[i + m]) % q;
if (t < 0)
t = (t + q);
}
}
}
int main() {
// char text[] = "ABCCDXAEFGX";
char text[] = "QWERTYUIOPASDFGHJKLXQWERTYUIOPASDFGHJKLX";
char pattern[] = "KLXQW";
int q = 13;
rabinKarp(pattern, text, q);
}
I believe the short answer is that the lower d is the more hash collisions you will have, but you go about verifying the match anyway so it does not affect anything.
A bit more verbose:
First let me modify your code to be have more expressive variables:
// Rabin-Karp algorithm in C++
#include <string.h>
#include <iostream>
using namespace std;
#define HASH_BASE 0
void rabinKarp(char pattern[], char text[], int inputBase) {
int patternLen = strlen(pattern);
int textLen = strlen(text);
int i, j; //predefined iterators
int patternHash = 0;
int textHash = 0;
int patternLenOut = 1;
for (i = 0; i < patternLen - 1; i++)
patternLenOut = (patternLenOut * HASH_BASE) % inputBase; // hash of pattern len
// Calculate hash value for pattern and text
for (i = 0; i < patternLen; i++) {
patternHash = (HASH_BASE * patternHash + pattern[i]) % inputBase;
textHash = (HASH_BASE * textHash + text[i]) % inputBase;
}
// Find the match
for (i = 0; i <= textLen - patternLen; i++) {
if (patternHash == textHash) {
for (j = 0; j < patternLen; j++) {
if (text[i + j] != pattern[j])
break;
}
if (j == patternLen)
cout << "Pattern is found at position: " << i + 1 << endl;
}
if (i < textLen - patternLen) {
textHash = (HASH_BASE * (textHash - text[i] * patternLenOut) + text[i + patternLen]) % inputBase;
if (textHash < 0)
textHash = (textHash + inputBase);
}
}
}
int main() {
// char text[] = "ABCCDXAEFGX";
char text[] = "QWEEERTYUIOPASDFGHJKLXQWERTYUIOPASDFGHJKLX";
char pattern[] = "EE";
int q = 13;
rabinKarp(pattern, text, q);
}
The easiest way to attack it is to set HASH_BASE (previously d) to zero and see where we can simplify. The rabinKarp function can then be reduced to:
void rabinKarp(char pattern[], char text[], int inputBase) {
int patternLen = strlen(pattern);
int textLen = strlen(text);
int i, j; //predefined iterators
int patternHash = 0;
int textHash = 0;
int patternLenOut = 0;
// Calculate hash value for pattern and text
for (i = 0; i < patternLen; i++) {
patternHash = (pattern[i]) % inputBase;
textHash = (text[i]) % inputBase;
}
// Find the match
for (i = 0; i <= textLen - patternLen; i++) {
if (patternHash == textHash) {
for (j = 0; j < patternLen; j++) {
if (text[i + j] != pattern[j])
break;
}
if (j == patternLen)
cout << "Pattern is found at position: " << i + 1 << endl;
}
if (i < textLen - patternLen) {
textHash = (text[i + patternLen]) % inputBase;
if (textHash < 0)
textHash = (textHash + inputBase);
}
}
}
now you'll notice that all the hashes becomes is the sum of the letters mod some number (in your case 13, in my case 2). This is a bad hash, meaning many things will sum to the same number. However, in this portion of the code:
if (patternHash == textHash) {
for (j = 0; j < patternLen; j++) {
if (text[i + j] != pattern[j])
break;
}
if (j == patternLen)
cout << "Pattern is found at position: " << i + 1 << endl;
}
you explicitly check the match, letter by letter, if the hashes match. The worse your hash function is, the more often you will have false positives (which will mean a longer runtime for your function). There are more details, but I believe that directly answers your question. What might be interesting is to record false positives and see how the false positive rate increases as d and q decrease.

Rabin-Karp giving wrong answer with increasing power raise to p

I have started learning string processing algorithms and wanted to implement the Rabin-Karp algorithm in C++. I have taken:
p = prime number larger than character set: 31
m = prime number for mod operations: 1e9+9
According to what I can find, there are multiple ways to implement the algorithm and I have tested two of them: increasing power as we go to higher index and decreasing power as we go to higher index.
For example on string S[0..n-1]
Let M1 = S[0]*p^0 + S[1]*p^1 + S[2]*p^2 + ... + S[n-1]*p^n-1
Let M2 = S[0]*p^n-1 + S[1]*p^n-2 + S[2]*p^n-3 ... + S[n-1]*p^0
I have implemented both the methods and could only get successful results using M2.
Code for M1:
int rabinKarpM1(string s, string t) {
int a = (int)s.size(), b = (int)t.size();
long long p = 31, m = 1e9+9;
long long powTable[a] = {0};
powTable[0] = 1;
for (int i = 1; i < a; i++) {
powTable[i] = powTable[i-1] * p % m;
}
long long hashS = 0, hashT = 0;
for (int i = 0; i < a; i++) {
hashS = (hashS + (s[i] - 'a' + 1)*powTable[i] % m) % m;
hashT = (hashT + (t[i] - 'a' + 1)*powTable[i] % m) % m;
}
if (hashS == hashT) {
bool match = true;
for (int i = 0; i < a; i++) {
if (s[i] != t[i]) {
match = false;
break;
}
}
if (match) {
return 0;
}
}
for (int i = 0; i+a-1 < b; i++) {
hashT = (hashT - (t[i] - 'a' + 1)) / p;
hashT = hashT + (t[i+a] - 'a' + 1)*powTable[a-1] % m;
hashT = hashT % m;
if (hashS == hashT) {
bool match = true;
for (int j = i+1; j < a+i+1; j++) {
if (s[j-i-1] != t[j]) {
match = false;
break;
}
}
if (match) {
return i+1;
}
}
}
return -1;
}
Code for M2:
int rabinKarpM2(string s, string t) {
int a = (int)s.size(), b = (int)t.size();
long long p = 31, m = 1e9+9;
long long powTable[a] = {0};
powTable[0] = 1;
for (int i = 1; i < a; i++) {
powTable[i] = powTable[i-1] * p % m;
}
long long hashS = 0, hashT = 0;
for (int i = 0; i < a; i++) {
hashS = (hashS + (s[i] - 'a' + 1)*powTable[a-i-1] % m) % m;
hashT = (hashT + (t[i] - 'a' + 1)*powTable[a-i-1] % m) % m;
}
if (hashS == hashT) {
bool match = true;
for (int i = 0; i < a; i++) {
if (s[i] != t[i]) {
match = false;
break;
}
}
if (match) {
return 0;
}
}
for (int i = 0; i+a-1 < b; i++) {
hashT = (hashT + m - (t[i] - 'a' + 1)*powTable[a-1] % m) % m * p;
hashT = hashT + (t[i+a] - 'a' + 1) % m;
hashT = hashT % m;
if (hashS == hashT) {
bool match = true;
for (int j = i+1; j < a+i+1; j++) {
if (s[j-i-1] != t[j]) {
match = false;
break;
}
}
if (match) {
return i+1;
}
}
}
return -1;
}
Test Input:
string s = foobarfoo
string t = barfoobarfoobarfoobarfoobarfoobarfoo
I have got correct results on M2 but not on M1.

Code runs fine through a debugger but crashes on execution

Can someone point out or give a hint on what's going on? Why is it when I run the code line-by-line using the built-in debugger, it gives the correct returnAry, but crashes when I try to execute the program?
No debugger:
With debugger:
Here is my code:
#include <iostream>
#include "fraction.h"
#include "fractionUtilities.h"
using namespace std;
int* getUncommon(Fraction*, int);
int main() {
Fraction testAry[] = { 1201, 6266, 35, 77 };
int size = 4;
int* result;
result = getUncommon(testAry, size);
for (int i = 0; i < result[0] + 1; i++) {
cout << result[i] << endl;
}
return 0;
}
int* getUncommon(Fraction* ary, int size) {
int* returnAry = 0;
int tmp;
int** digitInfoAry = new int*[size];
int i, j;
int sizeAry = 10;
int digitAry[10]{ 0 };
int uncommonDigitCount = 0;
for (i = 0; i < sizeAry; i++) {
*(digitInfoAry + i) = new int[sizeAry] {0};
}
for (i = 0; i < size; i++) {
tmp = (ary + i)->getNum() < 0 ? -(ary + i)->getNum() : (ary + i)->getNum();
do {
*(*(digitInfoAry + i) + tmp % 10) = 1;
tmp /= 10;
} while (tmp != 0);
}
for (i = 0; i < sizeAry; i++) {
for (j = 0; j < size; j++) {
digitAry[i] += *(*(digitInfoAry + j) + i);
}
}
for (i = 0; i < sizeAry; i++) {
if (digitAry[i] == 1) {
uncommonDigitCount++;
}
}
returnAry = new int[uncommonDigitCount + 1];
*returnAry = uncommonDigitCount;
if (uncommonDigitCount != 0) {
for (i = 0, j = 1; i < sizeAry; i += 2) {
if (digitAry[i] % 2 == 1) {
returnAry[j] = i;
j++;
}
}
for (i = 1; i < sizeAry; i += 2) {
if (digitAry[i] % 2 == 1) {
returnAry[j] = i;
j++;
}
}
}
return returnAry;
}
Thank you ahead of time for your help, I really cannot figure out what is going on, it's driving me insane!
Try to fix this:
int** digitInfoAry = new int*[size];
...
for (i = 0; i < sizeAry; i++) {
*(digitInfoAry + i) = new int[sizeAry] {0};
}
Then loop runs from 0 to sizeAry indices goes beyond allocated memory.

I use openMP to make my computation quick,but it doesn't work.Why?

I have a computation with a matrix(88147*2000) and it runs very slow.
So I want to use openMP to speed it up. This is my first time to use
openMP so I just use it in "loop-for".
This is my code:
#include<iostream>
#include<fstream>
#include<math.h>
#include<omp.h>
using namespace std;
#define LONGTH 88147
int label[LONGTH] ;
float data[LONGTH][2000] ;
float w[2000];
float e[2000];
void Input()
{
ifstream fin;
float a;
fin.open("/home/data.train");
if (!fin)
{
cout << "file error";
return;
}
for (int i = 0; i < LONGTH; i++)
{
fin >> a;
label[i] = int(a);
for (int j = 0; j < 2000; j++)
{
fin>>data[i][j];
}
}
fin.close();
cout<<"input over"<<endl;
return;
}
void Initial()
{
for (int i = 0; i < 2000; i++)
{
w[i] = 1;
e[i] = 1;
}
return;
}
bool End()
{
for (int i = 0; i < 2000; i++)
{
if (fabs(e[i])>pow(0.1, 6))
return 0;
}
return 1;
}
float Tkj(int i, int j, int k,float w[2000])
{
return w[i] * data[k][i] - w[j] * data[k][j];
}
float En(int n)//*computation*
{
float result = 0;
#pragma omp parallel for num_threads(64) reduction(+:result)
for (int k = 0; k < LONGTH; k++)
{
int tnum = omp_get_thread_num();
float tmp = 0;
int i = label[k] - 1;
for (int j = 0; j < 2000; j++)
{
if (j != i)
{
float l = 0;
if (n == i)
{
l = data[k][i];
float e = exp(Tkj(i, j, k,w));
tmp = tmp + (-e*l) / pow(1 + e, 2);
}
else if (n == j)
{
l = -data[k][j];
float e = exp(Tkj(i, j, k,w));
tmp = tmp + (-e*l) / pow(1 + e, 2);
}
else
{
continue;
}
}
}
result = result + tmp;
}
return result;
}
float Ex(float w[2000])
{
float result = 0;
#pragma omp parallel for num_threads(64) reduction(+:result)
for (int k = 0; k < LONGTH; k++)
{
int i = label[k] - 1;
float tmp = 0;
int tnum = omp_get_thread_num();
for (int j = 0; j < 2000; j++)
{
if (j != i)
{
tmp = tmp + 1 / (1 + exp(Tkj(i,j,k,w)));
}
}
result = result+tmp;
}
return result;
}
int main()
{
Input();
Initial();
float w2[2000] = { 0 };
float b = pow(0.1,5);
int times = 0;
while (!End()&&times<=30000)
{
times++;
cout<<times<<endl;
for (int i = 0; i < 2000; i++)
{
e[i] = En(i);
w2[i] = w[i] - b*e[i];
}
if (Ex(w2)<=Ex(w))//better
{
b = b * 2;
for (int i = 0; i < 2000; i++)
w[i] = w2[i];
}
else//worser
{
b = b / 2;
}
}
ofstream fout("/home/w.txt");
for(int i=0;i<2000;i++)
{
fout<<w[i]<<' ';
}
fout.close();
return 0;
}
The function 'En' costs most of time,so I use "#pragma omp parallel for num_threads(64) reduction(+:result)"to speed it up.
I run it in a CentOS server which has 32 cores and use "-fopenmp" to compile it.But it doesn't be a little quicker.
How can I speed this program up more?

Optimizing a program C++

I have to create a program, which counts bursted baloons, like from ZUMA. If I have a line with 3 or more baloons with the same color this sequence will burst. So in input, I have number of ballons (3 <= N <= 10^5) , and line with numbers (line with baloons color (1 <= сi <= 100) ), with 1 sequence for sure. I have to output number of bursted baloons. I have a programm, but it is working longer than 4000msv sometimes. How can I make it working faster?
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int Fmax(int n, const string& f){
int max;
vector<int> k(n);
int i, j, p = 0;
for (i = 0; i <= n; i++)
{
k[i] = 0;
}
for (i = 0; i <= n; i++)
{
for (j = i; j <= n; j++)
{
if (f[i] == f[j])
{
k[p]++;
}
else break;
}
p++;
}
max = k[0];
for (i = 0; i <= p; i++){ if (max <= k[i]){ max = k[i]; } }
return max;
}
string pog(int n){
int d;
string doa;
for (int i = 1; i <= n; i++){
cin >> d;
doa += (char)d;
}
return doa;
}
void main(){
int i, sc = 1, bf = 1;
string f;
int len;
cin >> i;
f = pog(i);
len = i;
while (Fmax(f.length(), f) >= 3){
for (int c = 1; c <= f.length(); c++){
if (f[c] == f[c - 1]){
if (sc == 1){ bf = c - 1; }
sc++;
}
else{
if (sc >= 3){ f.erase(bf, sc); sc = 1; break; }
sc = 1;
}
}
}
cout << len - f.length() << endl;
}
Any help is warmly welcome.
You are leaking memory. Use vectors to avoid that.
Why do you need to create array? Why not use the string directly?
Pass strings which aren't modified by const reference to avoid copies.
Use constant variables for the lengths:
const unsigned int f_length = f.length();
while (Fmax(f_length, f) >= 3){
for (int c = 1; c <= f_length ; c++){
This helps the compiler reduce the number of calls to the length method.