I'm trying to make a parallel version of "Harmonic Progression Sum" problem using opemMP.
But the output are differents each other depending on the inputs. (Parallel and Sequential)
Program:
#include "stdafx.h"
#include <iostream>
#include <sstream>
#include <omp.h>
#include <time.h>
#define d 10 //Numbers of Digits (Example: 5 => 0,xxxxx)
#define n 1000 //Value of N (Example: 5 => 1/1 + 1/2 + 1/3 + 1/4 + 1/5)
using namespace std;
void HPSSeguencial(char* output) {
long unsigned int digits[d + 11];
for (int digit = 0; digit < d + 11; ++digit)
digits[digit] = 0;
for (int i = 1; i <= n; ++i) {
long unsigned int remainder = 1;
for (long unsigned int digit = 0; digit < d + 11 && remainder; ++digit) {
long unsigned int div = remainder / i;
long unsigned int mod = remainder % i;
digits[digit] += div;
remainder = mod * 10;
}
}
for (int i = d + 11 - 1; i > 0; --i) {
digits[i - 1] += digits[i] / 10;
digits[i] %= 10;
}
if (digits[d + 1] >= 5) {
++digits[d];
}
for (int i = d; i > 0; --i) {
digits[i - 1] += digits[i] / 10;
digits[i] %= 10;
}
stringstream stringstreamA;
stringstreamA << digits[0] << ",";
for (int i = 1; i <= d; ++i) {
stringstreamA << digits[i];
}
string stringA = stringstreamA.str();
stringA.copy(output, stringA.size());
}
void HPSParallel(char* output) {
long unsigned int digits[d + 11];
for (int digit = 0; digit < d + 11; ++digit)
digits[digit] = 0;
int i;
long unsigned int digit;
long unsigned int remainder;
#pragma omp parallel for private(i, remainder, digit)
for (i = 1; i <= n; ++i) {
remainder = 1;
for (digit = 0; digit < d + 11 && remainder; ++digit) {
long unsigned int div = remainder / i;
long unsigned int mod = remainder % i;
digits[digit] += div;
remainder = mod * 10;
}
}
for (int i = d + 11 - 1; i > 0; --i) {
digits[i - 1] += digits[i] / 10;
digits[i] %= 10;
}
if (digits[d + 1] >= 5) {
++digits[d];
}
for (int i = d; i > 0; --i) {
digits[i - 1] += digits[i] / 10;
digits[i] %= 10;
}
stringstream stringstreamA;
stringstreamA << digits[0] << ",";
for (int i = 1; i <= d; ++i) {
stringstreamA << digits[i];
}
string stringA = stringstreamA.str();
stringA.copy(output, stringA.size());
}
int main() {
//Sequential Method
cout << "Sequential Method: " << endl;
char outputSeguencial[d + 10];
HPSSeguencial(outputSeguencial);
cout << outputSeguencial << endl;
//Cleaning vector
string stringA = "";
stringA.copy(outputSeguencial, stringA.size());
//Parallel Method
cout << "Parallel Method: " << endl;
char outputParallel[d + 10];
HPSParallel(outputParallel);
cout << outputParallel << endl;
system("PAUSE");
return 0;
}
Examples:
Input:
#define d 10
#define n 1000
Output:
Sequential Method:
7,4854708606╠╠╠╠╠╠╠╠╠╠╠╠
Parallel Method:
6,6631705861╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ÇJ^
Input:
#define d 12
#define n 7
Output:
Sequential Method:
2,592857142857╠╠╠╠╠╠╠╠╠╠╠╠╠╠ÀÂ♂ü─¨#
Parallel Method:
2,592857142857╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ÇJJ
Regards
Pastecode
http://pastecode.org/index.php/view/62768285
Your threads step on each other's toes when updating the digits array. Hence some additions are lost, and you get bogus results (different results in different runs, almost certainly).
You must synchronise the writes to digits, e.g. with an atomic (or critical) section:
// ... <snip>
#pragma omp parallel for private(i, remainder, digit)
for (i = 1; i <= n; ++i) {
remainder = 1;
for (digit = 0; digit < d + 11 && remainder; ++digit) {
long unsigned int div = remainder / i;
long unsigned int mod = remainder % i;
#pragma omp atomic // <- HERE, could also be #pragma omp critical
digits[digit] += div;
remainder = mod * 10;
}
}
// <snip> ...
so that only one thread at a time can update the array. For a task like this, that would probably nullify any gains of splitting the task in several threads, though.
As Daniel Fischer pointed out, you have a write conflict, but you can avoid it more elegantly than with an omp critical section, e.g. by giving each thread it's own copy of digits and aggregating them all at the end of the loop.
Related
the code is for reversing the input decimal whether negative or positive .if the value of decimal exceeds as max size of int in 32 bit system then return 0.why my code is not working...help me finding the bug .i have attached the code.
#include<iostream>
#include<stdlib.h>
#include<math.h>
using namespace std;
float reverseint(int x)
{
int digit[10];
int i = 0;
float revnum = 0;
//store digits of number x
while (x != 0)
{
digit[i] = x % 10;
x = x / 10;
i++;
}
i--;
//reversing number x
while (i >= 0)
{
int j = 0;
revnum = (digit[i] * pow(10, j)) + revnum;
j++;
i--;
}
return revnum;
}
int main()
{
int n;
cin >> n;
if (n < 0)
{
if (n < -pow(2, 31))
cout << 0 << endl;
cout << -reverseint(-n);
}
if (n > 0)
{
if (n > (pow(2, 31) - 1))
cout << 0 << endl;
cout << (reverseint(n)) << endl;
}
return 0;
}
You are initializing j variable on every while loop on reverseint function.
float reverseint(int x)
{
int digit[10];
int i = 0;
float revnum = 0;
//store digits of number x
while (x != 0)
{
digit[i] = x % 10;
x = x / 10;
i++;
}
i--;
//reversing number x
int j = 0; /// Correct place.
while (i >= 0)
{
//int j = 0; /// Wrong. j will be always 0 on every loop. revnum will be sum of digits on variable x.
revnum = (digit[i] * pow(10, j)) + revnum;
j++;
i--;
}
return revnum;
}
I need to make a code to switch 2 digits in a number and make it into a new integer
For example
12-->21
123 becomes
213(1,2 switch)
312(1,3 switch)
132 (2,3 switch)
for up to 8 digits of numbers
this is what I came up so far
#include <iostream>
#include <iomanip>
using namespace std;
int digitcount(int n) {
int count=0;
if (n == 0)
return 1;
while (n != 0) {
n = n / 10;
count++;
}
return count;
}
int pow(int num,int n) {
int x = 1;
if (n == 0) {
return 1;
}
for (int i = 0; i < n; i++) {
x = x * num;
}
return x;
}
int a[8];
int main() {
int input;
int newnum = 0;
cout << "Input an integer: ";
cin >> input;
int b = input;
int digit = digitcount(input);
for (int i = digit-1; i>=0; i--) {
a[i] = b % 10;
b = b / 10;
}
for (int i = 0; i < digit - 1; i++) {
newnum = 0;
for (int j = i+1; j < digit; j++) {
if (a[j] == a[i]) {
continue;
}
newnum = a[i] * pow(10, digit - j - 1) + a[i] * pow(10, digit);
}
}
}
I have an infinitely long string "12345678910111213141516171819202122232425..." which is a concatentation of every natural numbers in ascending order. I want to find the kth character in the string. However, my program is giving me incorrect output despite the logic being correct. I suspect an implementation bug somewhere
#include <iostream>
int main() {
using std::cin;
using std::cout;
std::ios::sync_with_stdio(0);
cin.tie(0);
int T;
cin >> T;
while (T--) {
int64_t k;
cin >> k;
int64_t aux = 9;
int digit = 1;
while (k > aux * digit) {
k -= aux * digit;
aux *= 10;
digit++;
}
int64_t ans = 1;
for (int i = 0; i < digit - 1; i++) {
ans *= 10;
}
ans += (k - 1) / digit - 1;
k -= (k - 1) / digit * digit;
int64_t helper = 1;
for (int i = 0; i < digit - k; i++) {
helper *= 10;
}
cout << ans / helper % 10 << '\n';
}
return 0;
}
Input:
3
7
19
12
Expected Output:
7
4
1
My output
6
3
1
It's almost correct but it seems that you do not have to minus 1 in ans += (k - 1) / digit - 1, changing it to ans += (k - 1) / digit should work.
Output:
7
4
1
I was assigned a "project" where I should create a C++ program to find the largest possible sum of two sub sequences. The user inputs N (array length), K (length of each sub sequence) and N numbers representing the array. The two sub sequences can touch but can't override each other e.g. 1 5 20 20 20 15 10 1 1 1 should output 90 ((5+20+20)+(20+15_10)) and not 115 ((20+20+20)+(20+20+15)).
My code until now is:
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int N, K, MaxN;
cin >> N;
cin >> K;
int Pi[N];
MaxN = N - K + 1;
int Word[MaxN];
int MaxSum;
for(int nn=0; nn<N; nn++) {
cin >> Pi[nn];
}
for(int y=0;y<MaxN;y++) {
Word[y] = 0;
}
for(int j=0; j<MaxN; j++) {
for(int l=0; l<K; l++) {
Word[j] = Word[j] + Pi[j+l];
}
}
sort(Word, Word + MaxN);
MaxSum = Word[MaxN-2] + Word[MaxN-1];
cout << MaxSum;
return 0;
}
Which is correct only in the case where the 2 sub sequences don't interfere with each other e.g. in an array such as 2 4 15 12 10 1 1 20 4 10 which outputs 71.
Thank you all in advance.
This is solution:
precalculate prefixes and suffixes
iterate end of the first subarray
iterate begin of the second subarray, but start from the end of first sub. ar. + 1
we have sum of numbers on interval from 0 to *end* = prefix[end], but we are interested only in interval [end - k, k], so simply subtract prefix[end] - prefix[end - k - 1]
[0 .. end-k-1, end-k .. end]
The same approach for the second subarray: sum2 = suffix[begin] - suffix[begin + i + 1]
then compare with the previous answer
So we just brute-force all possible sub-arrays which not intersect and find the max their sum
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int N,K,MaxN;
cin >> N;
cin >> K;
int Pi[N];
MaxN=N-K+1;
int Word[MaxN];
int MaxSum;
for(int nn=0;nn<N;nn++){
cin >> Pi[nn];
}
int prefix[N];
int sufix[N];
for (int i = 0; i < N; i++) {
prefix[i] = sufix[i] = 0;
}
for (int i = 0; i < N; i++) {
if (i == 0)
prefix[i] = Pi[i];
else
prefix[i] = Pi[i] + prefix[i - 1];
}
for (int i = N - 1; i >= 0; i--) {
if (i == N - 1)
sufix[i] = Pi[i];
else
sufix[i] = Pi[i] + sufix[i + 1];
}
int ans = 0;
for (int i = K - 1; i < MaxN; i++) {
for (int j = i + 1; j < MaxN; j++) {
int x = prefix[i] - (i - K >= 0 ? prefix[i - K] : 0);
int y = sufix[j] - (j + K < N ? sufix[j + K] : 0);
ans = max(ans, x + y);
}
}
cout << ans;
return 0;
}
i checked the answer and it's not off by much from my answer, but it is still an error. can someone check my coding to see what mistake caused me to get a value of 1319?
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int k = 0;
int o = 0;
vector<int> n(1,0);
n[0] = 1;
while (k < 1001)
{
for (int l = 0; l < n.size(); l++)
n[l] = n[l] * 2;
for (int l = 0; l < n.size(); l++)
{
if (n[l] >= 1000000)
{
int m;
if (l == n.size() - 1)
n.resize(n.size() + 1);
m = n[l] / 1000000;
n[l] = n[l] % 1000000;
n[l+1] = n[l+1] + m;
}
}
k++;
}
for (int l = 0; l < n.size(); l++)
o = o + int (n[l]/1000000) + int ((n[l] % 1000000) / 100000) + int ((n[l] % 100000) / 10000) + int ((n[l] % 10000) / 1000) + int ((n[l] % 1000) / 100) + int ((n[l] % 100) / 10) + n[l] % 10;
cout << o;
cin >> k;
return 0;
}
Make it
while (k < 1000)
in the outer loop condition.
In the while loop, you start with a representation of 2^k in the vector with the value k has at entering the loop. So you are actually computing 2^1001 and not 2^1000.
Problem of solving this in c++ is datatype limit, "int" is not sufficient to calculate 2^1000.
I have solved a prototype for this i.e. sum of the digits of number 2^4.The power 2^4 is 16 and sum of digits id 7.
Hope the code guides u.
#include<iostream.h>
#include<conio.h>
void main()
{
int count=1;
int power=1;
int sum=0;
while(count<=4)
{ count++;
power=power*2;
}
cout<<"The power is"<<power<<"\t";
while(power!=0)
{
int digit=power%10;
sum=sum+digit;
power=power/10;
}
cout<<"The sum of digits is"<<sum;
getch();
}