Floating Point Error With This Code Can someone help me - c++

i am facing problem with this chinese remainder theoram
i am taking an input.txt file as input
and trying to generate an output.txt file but it says floating point error. when i am running with some specific input at that time it is working but for many test cases it is not working
#include <bits/stdc++.h>
#include <fstream>
#include <iostream>
using namespace std;
int ModInverse(int a, int m)
{
a = a % m;
for(int x = 1; x < m; x++)
if(((a * x) % m) == 1) return x;
}
int findMinX(int num[], int rem[], int k) {
int prod = 1;
for(int i = 1; i <= k; i++) prod *= num[i];
int result = 0;
for(int j = 1; j <= k; j++) {
int y = prod / num[j];
result = result + rem[j] * ModInverse(y, num[j]) * y;
}
return result % prod;
}
int main() {
ifstream infile;
infile.open("input.txt");
int n;
int num[100];
int rem[100];
infile >> n;
for(int i = 0; i < n; i++) infile >> num[i];
for(int i = 0; i < n; i++) infile >> rem[i];
infile.close();
int k = sizeof(num) / sizeof(num[0]);
ofstream myfile;
myfile.open("output.txt");
myfile << findMinX(num, rem, k);
myfile.close();
return 0;
}

These lines:
for(int i = 1; i <= k; i++)
for(int j = 1; j <= k; j++)
will cause i and j to go out of bounds.
Array indexing starts at 0 in C++, so you should use indexes 0 to k-1.
Do this instead:
for(int i = 0; i < k; i++)
for(int j = 0; j < k; j++)
Another thing worth checking up is this function:
int ModInverse(int a, int m)
{
a = a % m;
for(int x = 1; x < m; x++)
if(((a * x) % m) == 1) return x;
}
Given the wrong input, it'll exit the loop and return nothing, which causes undefined behaviour. Validate the input and print an error message if the file contains data you can't handle.
Here's an example of an input.txt that makes it crash for me:
5
1 2 3 4 5
2 3 4 5 6
Another cause for concern is that you use k instead of n in your call to the function:
myfile << findMinX(num, rem, k);
This means the function will always work on 100 values. Some of them may be uninitialized, and again, undefined behaviour.

Related

multiply two negative numbers in c++

when I tried to multiple two negative numbers the value it is zero in c++,
for example -5 * -3
the result is zero,
why?
this is my code
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
void Multiply(const int v_arr[], const int m_arr[][3], int signed
o_arr[], int size)
{
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
o_arr[i] = 0;
for (int k = 0; k < 3; k++)
o_arr[i] += v_arr[k] * m_arr[k][i];
}
}
//End your code here
}
int main()
{
int n;
cin >> n;
int v_array[n];
int m_array[n][3];
int signed o_array[3];
for (int i = 0; i < n; i++) {
cin >> v_array[i];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < 3; j++) {
cin >> m_array[i][j];
}
}
//fuction
Multiply(v_array, m_array, o_array, n);
for (int j = 0; j < 3; j++) {
cout << o_array[j] << " ";
}
return 0;
}
how to fix it to get the correct result?
the input is
2
2 -3
2 -3
2 -4
Your issue is here:
for (int k = 0; k < 3; k++)
o_arr[i] += v_arr[k] * m_arr[k][i];
}
You access elements at indices 0, 1 and 2 in v_arr, but it only has 2 elements. That's Undefined Behaviour.
Assuming this is matrix*vector multiplication code, it should look like this (untested):
for (int k = 0; k < 3; k++)
o_arr[k] += v_arr[i] * m_arr[i][k];
}
Also, your loop based on j is useless. You can remove it:
void Multiply(const int v_arr[], const int m_arr[][3], int signed o_arr[], int size)
{
for(int k = 0; k < 3; k++) { //initialize output array
o_arr[k] = 0;
}
for (int i = 0; i < size; i++) {
for (int k = 0; k < 3; k++)
o_arr[k] += v_arr[i] * m_arr[i][k];
}
}

removing double elements in an array

I am trying to remove double elements in an array. I developed a simple code, but it is still not working. Is it possible to hint for some input maybe I haven't tried. I tried corner and test cases. The following is the problem statement:
A sequence of numbers given. Remove element’s doubles, leaving first copy.
Input: Contains a natural n (n ≤ 100000) – the n quantity numbers in a sequence, then n non-negative numbers – elements of the sequence which module is not greater than 999.
output: changed sequence.
It seems I can't get what might be the problem
#include <iostream>
//#include <cmath>
//#include <climits>
#define SIZE 100000
using namespace std;
int main()
{
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n, k, p;
bool tag; tag = false;
cin >> n;
long long int *a = new long long int[n];
long long int b[SIZE];
for (int i = 0; i < n; i++) { cin >> a[i]; }
for (int i = 0; i < n; i++) { k = 0;
for (int j = i + 1; j < n; j++) {
if (a[i] == a[j]) { b[k] = j-k; k++; tag = true; }
}
if (tag) {
for (int i = 0; i < k; i++) {
p = b[i];
for (int i = p; i < n; i++) { a[i] = a[i + 1]; }
n--;
}
tag = false;
}
}
for (int i = 0; i < n; i++) { cout << a[i] << " "; }
return 0;
}
Input: 6 1 2 2 4 3 4 Output: 1 2 4 3
You can use unordered_set and vector
int n; cin >> n;
long long int x;
unordered_set<long long int>myset;
vector<long long int>v1;
for (int i = 0; i < n; i++)
{
cin>>x;
if(myset.find(x)==myset.end())
{
myset.insert(x);
v1.push_back(x);
}
}
for(int i=0;i<v1.size();i++)
{
cout<<v1[i]<<" ";
}
You could use in you advantage the fact that input values are in the range from 0 to 999.
A simple bool used[1000]{} could be used to flag if the current value has been used already before pushing it to cout, thus ensuring both O(n) complexity and limited memory usage (1000 bytes for the bool[]}.
Here's a sample solution around this idea:
#include<iostream>
#define MAX_VALUE 999
using namespace std;
int main() {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
bool used[MAX_VALUE + 1]{};
size_t n;
cin >> n;
for (size_t num, i = 0; i < n; ++i) {
cin >> num;
if (!used[num]) {
cout << num << " ";
used[num] = true;
}
}
return 0;
}
You could try creating a second array of unique numbers as you go. I will demonstrate with a vector for the sake of simplicity.
std::vector<int> v;
for (int i = 0; i < n; i++) {
if (std::find(v.begin(), v.end(), arr[i]) == v.end()) {
v.push_back(arr[i]);
}
}
Then, you just write the contents of the vector to the output file.
Here is my version of O(n) complexity. Your solution may exceed time-limit ( if it is low )
bool check[2000];
for (int i = 0; i < 2000; i++) check[i] = 0;
for (int i = 0; i < n; i++) {
cin >> a[i];
// +999 to avoid negative numbers
check[a[i] + 999] = 1;
}
bool isPrint = false;
for (int i = 0; i < n; i++) {
if (check[a[i] + 999]) {
// mark false if already printed
check[a[i] + 999] = 0;
if (isPrint) printf(" ");
printf("%d", a[i]);
isPrint = true;
}
}

Can anyone tell me why does this exceed the time limit of 2 seconds ?(short code)

I have been struggling with it for 2 days.Please, could anyone tell me why does it exceed the time limit when i use as input 20000 and 0 and 40000 numbers afterwards ? I tried to make the variables type as large as possible, but that does not seem to help either.
#include <bits/stdc++.h>
using namespace std;
int main()
{
/*freopen("file.in", "r", stdin);
freopen("file.out", "w" , stdout);*/
long long int aux,i, n, k, j, total = 0;
cin >> n >> k;
long long int a[n], b[n], order[n];
signed long long int profit[n];
for(i = 0; i < n; i++)
cin >> a[i];
for(i = 0; i < n; i++)
cin >> b[i];
for(i = 0; i < n; i++)
profit[i] = a[i] - b[i];
for(i = 0; i < n; i++)
order[i] = i;
for(i = 0; i < n; i++)
for(j = i + 1; j < n; j++)
if(profit[order[i]] > profit[order[j]])
{
aux = order[i];
order[i] = order[j];
order[j] = aux;
}
if(k > 0)
for(i = 0; i < k; i++)
{
total += a[order[i]];
}
for(i = k; i < n; i++)
{
if(profit[order[i]] < 0)
total += a[order[i]];
else
total += b[order[i]];
}
cout << total;
return 0;
}
The complexity of your code is O(n^2), which is too much for N=20000. Reduce the complexity, replacing your bubble sort with Qsort. Try std::sort with custom comparison function.

Having trouble implementing pseudocode for Subset Sum

so I am trying to implement the following pseudocode but it will not work as it is supposed to. Here is the problem description in the slide, "Given an integer bound, "W", and a collection of "n" items, each with a positive integer weight "wi", find a subset S of items that: maximizes Sigma sub i where i is an element of S "wi" while keeping this sum less than or equal or to W. I will attach the following slides for where I am getting the problem description and pseudocode from. The problem with my implementation is that it will only find the total max value and not the value that is less than or equal to the weight. So for example, if I had Weight 10 (W = 10) and items 3 (n = 3) with item weights 1, 4, & 8 then the following answer should be 9; however, my solution gives 12. Here are the slides (*Please not, where it says w[j] it is meant to be w[i] - the slide had a typo):
Here is my code that implements the pseudocode:
#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int max(int a, int b, int c) {
if (a >= b)
return a;
else
return b;
}
int optimal_weight(int W, const vector<int> &wt, int n){
vector<vector<int> > M;
M.resize(n+1);
for(int i = 0; i < n+1; ++i){
M[i].resize(W+1);
}
for(int w = 0; w < W+1; w++){
M[0][w] = 0;
}
for(int i = 1; i < n+1; i++){
M[i][0] = 0;
}
for(int i = 1; i < n+1; i++){
for(int w = 0; w < W+1; w++){
if(wt[i] > w){
M[i][w] = M[i-1][w];
}
M[i][w] = max(M[i-1][w], wt[i] + M[i-1][W-wt[i]], W);
}
}
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= W; j++)
printf ("%4d", M[i][j]);
printf("\n");
}
return M[n][W];
}
int main()
{
//int val[] = {1, 1, 1};
int W;
int n;
cin >> W >> n;
vector<int> wt(n);
for(int i = 0; i < n; i++){
cin >> wt[i];
}
cout << optimal_weight(W, wt, n) << endl;
}
Thank you for any help!
I figured it out! Here is my solution:
#include <iostream>
#include <vector>
using namespace std;
using std::vector;
int optimal_weight(int W, const vector<int> &wt) {
//write your code here
int n = wt.size();
vector<vector<int> > matrix;
matrix.resize(W+1);
for(int i = 0; i < W+1; i++){
matrix[i].resize(n);
}
for(int j = 0; j < n; j++){
matrix[0][j] = 0;
}
for(int w = 0; w < W + 1; w++){
matrix[w][0] = 0;
}
for(int i = 1; i < n; i++){
for(int w = 1; w < W+1; w++){
matrix[w][i] = matrix[w][i-1];
if(wt[i] <= w){
//cout << wt[i] << endl;
int val = matrix[w-wt[i]][i-1] + wt[i];
if(matrix[w][i] < val){
matrix[w][i] = val;
}
}
}
}
return matrix[W][n-1];
}
int main() {
int n, W;
std::cin >> W >> n;
vector<int> wt(n+1);
for (int i = 1; i < n+1; i++) {
wt[0]=0;
std::cin >> wt[i];
}
std::cout << optimal_weight(W, wt) << '\n';
}

Usage of multidimensional vectors

I was trying to use multidimensional vector and change the values of row and column.
#include<iostream>
#include<vector>
using namespace std;
void changerow(vector<vector<int> > A, int row, int M, int P){
for(int j = 0; j < M; j++){
(A[row - 1])[j] = ((A[row - 1])[j] + P) % 10;
}
}
void changecolumn(vector<vector<int> > A, int column, int N, int P){
for(int i = 0; i < N; i++){
(A[i])[column - 1] = ((A[i])[column - 1] + P) % 10;
}
}
int main(int argc, char* argv[])
{
int T, N, M;
cin >> T >> N >> M;
if((T >= 1 && T <= 10) && (M >= 1 && M <= 100) && (N >= 1 && N <= 100)){
// Logic of the program
vector<vector<int> > A(N, vector<int>(M));
for(int i = 0; i < N ; i++){
for(int j = 0; j < M; j++){
cin >> (A[i])[j];
}
}
changerow(A,2,M,3);
for(int i = 0; i < N ; i++){
for(int j = 0; j < M; j++){
cout << A[i][j];
}
}
}
return 0;
}
I don't know how would pass the address of the vector in order to change the element, since only the local copy of the vector gets passed. I am currently reading Thinking in C++ Volume 1 but its not elaborate. Kindly let me know a good source for learning the use of vectors in C++.
Currently, you are passing the vector by value, which means that the callee gets a copy of the vector.
If you wish the changes that the callee makes to be visible to the caller, you need to pass the vector by reference. This is done like so:
void changecolumn(vector<vector<int> >& A, int column, int N, int P){
^ THIS
For a discussion, see Pass by Reference / Value in C++