My program just reads half an array c++ - c++

I need my program to read an array from txt. file, It apperantly does, but when I paid attention to the numbers, I discovered that only half array is correct, the rest are random.
Furthermore, if I read 2 diferent arrays, the random numbers are the same.
There is the code:
//List of Biblio.
#include <cstdlib>
#include<stdio.h>
#include <time.h>
#include <iostream>
#include <vector>
using namespace std;
FILE *fp;
//Functiotns declaration.
//
void dimensions(int &,int &,int &);
//
void rTime (int** ,int,int,int &); // The first int, it's an Array!
//
void rTimeprint (int** ,int,int,int);
//
void spt (int**,vector<int> & ,int,int); // The first int it's an Array!
//
int block (int, int,int, int,int,int);
//
int neh (int,int,int,int,int,int,int);
//
static int swap (int, int,int,int,int,int,int,int,double,double,float);
//
//A inserta, hi ha una matriu (1st int) i vector (3rd int)
static int inserta (int,int,int,int,int,int,int,int, double,double,float );
//
static int sa (double,double,float);
//Array varaibles;
int column, row, nombreProblemes;
int main() {
// Open the file where's the array;
fp = fopen("entrada.txt", "r");
dimensions(column, row, nombreProblemes);
// Create the Array:
int *matriuTemps[column];
for (int i= 0; i<column;i++){
matriuTemps[i] = new int [row];
}//end of loop Array[][] creator
// Function read time (array)
rTime(matriuTemps, column, row,problema);
//Function print the Array
rTimePrint(matriuTemps, column,row,problema);
}//End of main
And there is the function rTime:
void rTime(int *matriuTemps [],int column, int row, int &Problema){
fscanf(fp, "%d",&Problema);
for (int i= 0; i<row; i++){//Outter loop (row)
for (int j=0; j<column;j++){//inner loop (column))
matriuTemps[i][j]=0;
fscanf(fp,"%d",&matriuTemps [i][j]);
}//inner loop
}//outer loop
If it is more infor for you i put the function which prints the array:
void rTimeprint (int *matriuTemps[20] ,int column,int row,int problema){
cout<<"\nAquest és la matriu de temps del problema: "<< problema <<endl<<endl;
for (int i= 0; i<row; i++){//Outter loop (row)
for (int j=0; j<column;j++){//inner loop (column))
cout<< matriuTemps[i][j]<<"\t";
}//inner loop
cout << endl;
}//outer loop
}
And finally the Output: (i mark with x x, the column here the values start to be random, From there to the right are all random)
first Array
x
x
54 83 15 71 77 36 53 38 27 87 76 91 14 29 12 77 32 87 68 94
79 3 11 99 56 70 99 60 16 89 49 15 89 45 60 23 66 58 31 68
16 89 49 15 89 45 60 23 66 58 31 68 78 91 13 59 58 56 20 85
66 58 31 68 78 91 13 59 58 56 20 85 53 35 53 41 69 13 86 72
58 56 20 85 53 35 53 41 69 13 86 72 8 49 47 87 58 18 68 28
Second Array:
x
x
0 0 0 0 0 0 0 0 0 87 76 91 14 29 12 77 32 87 68 94
45 33 11 99 56 0 87 60 16 89 49 15 89 45 60 23 66 58 31 68
12 89 40 15 89 45 60 23 66 58 31 68 78 91 13 59 58 56 20 85
46 57 1 68 78 95 78 53 58 56 20 85 53 35 53 41 15 13 86 72
52 56 20 95 3 15 78 42 15 13 86 72 8 49 47 87 58 18 68 28

You seem to have got your row and column dimensions mixed up - this part:
int *matriuTemps[column];
for (int i= 0; i<column;i++){
matriuTemps[i] = new int [row];
}
should be:
int *matriuTemps[row]; // allocate `row` rows
for (int i= 0; i<row;i++){ // for each row
matriuTemps[i] = new int [column];
} // allocate `column` elements

In the main functionyou declarematriuTempsto be an array ofcolumnelements, each element being a pointer toint`.
But in in e.g. rTime you treat the array as an array of row elements, each element being an array of column integers. So you mix up the indexes, and unless both row and column are equal you will have problems.
Also note that C++ doesn't actually have variable-length arrays, making your definition of matriuTemps not proper C++.
Instead, if you want dynamic arrays, you should use std::vector. Maybe something like
std::vector<std::vector<int>> matriuTemps(column, std::vector<int>(row));
The above line defined matriuTemps to be a vector or vectors of integers, and set the size of both "dimensions".

Related

Code is showing showing wrong output in 'fractional knapsack' problem even when answer is properly typecasted

I am solving question called fractional knapsack on geeks for geeks but I don't know why it is giving wrong output for a particular test case. I am not able to find any error in it.
// { Driver Code Starts
#include <bits/stdc++.h>
using namespace std;
struct Item{
int value;
int weight;
};
// } Driver Code Ends
//class implemented
/*
struct Item{
int value;
int weight;
};
*/
static bool compare(Item i1,Item i2)
{
double v1=i1.value/i1.weight;
double v2=i2.value/i2.weight;
return v1>v2;
}
class Solution
{
public:
//Function to get the maximum total value in the knapsack.
double fractionalKnapsack(int W, Item arr[], int n)
{
// Your code here
sort(arr,arr+n,compare);
double ans=0.0;
long long int i=0;
while(i<n)
{
if(arr[i].weight<=W)
{
ans+=arr[i].value;
W-=arr[i].weight;
}
else
{
double partialvalue=(double)((double)arr[i].value/(double)arr[i].weight)*(double)W;
ans+=partialvalue;
break;
}
i++;
}
return ans;
}
};
// { Driver Code Starts.
int main()
{
int t;
//taking testcases
cin>>t;
cout<<setprecision(2)<<fixed;
while(t--){
//size of array and weight
int n, W;
cin>>n>>W;
Item arr[n];
//value and weight of each item
for(int i=0;i<n;i++){
cin>>arr[i].value>>arr[i].weight;
}
//function call
Solution ob;
cout<<ob.fractionalKnapsack(W, arr, n)<<endl;
}
return 0;
} // } Driver Code Ends
RESULT:
Wrong Answer. !!!Wrong Answer
Possibly your code doesn't work correctly for multiple test-cases (TCs).
The first test case where your code failed:
Input:
84 87
78 16 94 36 87 43 50 22 63 28 91 10 64 27 41 27 73 37 12 19 68 30 83 31 63 24 68 36 30 3 23 9 70 18 94 7 12 43 30 24 22 20 85 38 99 25 16 21 14 27 92 31 57 24 63 21 97 32 6 26 85 28 37 6 47 30 14 8 25 46 83 46 15 18 35 15 44 1 88 9 77 29 89 35 4 2 55 50 33 11 77 19 40 13 27 37 95 40 96 21 35 29 68 2 98 3 18 43 53 7 2 31 87 42 66 40 45 20 41 30 32 18 98 22 82 26 10 28 68 7 98 4 87 16 7 34 20 25 29 22 33 30 4 20 71 19 9 16 41 50 97 24 19 46 47 2 22 6 80 39 65 29 42 1 94 1 35 15
Its Correct output is:
1078.00
And Your Code's output is:
1075.57
You forgot casts in your comparison function:
static bool compare(Item i1,Item i2)
{
double v1=i1.value/i1.weight;
double v2=i2.value/i2.weight;
return v1>v2;
}
should be
static bool compare(Item i1,Item i2)
{
double v1=(double)i1.value/(double)i1.weight;
double v2=(double)i2.value/(double)i2.weight;
return v1>v2;
}
There may be other issues, but this is the one that jumps out!

boost::multi_index insertion function for "other" indices

Here is a container of ints with a hashed index and a sequence index:
#include <iostream>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/sequenced_index.hpp>
int main()
{
boost::multi_index_container<
int,
boost::multi_index::indexed_by<
boost::multi_index::hashed_unique<boost::multi_index::identity<int>>,
boost::multi_index::sequenced<>
>
> c;
for (int i=99; i>=0; --i) c.get<0>().insert(i);
for (int j : c.get<0>()) std::cout << " " << j;
std::cout << std::endl;
for (int k : c.get<1>()) std::cout << " " << k;
std::cout << std::endl;
return 0;
}
When I run this I get:
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 2 1 0
99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
The first line shows the elements are "scattered" via the hash index, as expected. The second line shows the elements are in insertion order via the sequenced index. But the elements were inserted via the hash index; what can we expect for the elements of the sequenced index? That is, when insert is called for one index, are the insertion functions used for "other" indices defined?
Specifically: When a multi-index container has a hashed index and a sequenced index, and elements are only inserted via the hashed index, will the elements always be in insertion order via the ordered index?
As for sequenced indices, docs say:
Elements in a sequenced index are by default sorted according to their order of insertion: this means that new elements inserted through a different index of the multi_index_container are appended to the end of the sequenced index.

Problem Copying Values to Multidimensional Array

I'm trying to make write a program that can take 81 integers from a text file, and add them to a multidimensional array.
I'm reading from a text file containing these integers:
1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18
19 20 21 22 23 24 25 26 27
28 29 30 31 32 33 34 35 36
37 38 39 40 41 42 43 44 45
46 47 48 49 50 51 52 53 54
55 56 57 58 59 60 61 62 63
64 65 66 67 68 69 70 71 72
73 74 75 76 77 78 79 80 81
This is the code that I'm using to do this
int main()
{
ifstream myFile; //ifstream object
int num[8][8]; //multidimensional array
int TempStorage[80]; //temporary storage for reading numbers off of text file
int maybe; //no clue what this one does
int i=0; //used for temp storage input
int x=0; //used to copy values to multidimensional array
myFile.open("numbers.txt"); //open document
if(myFile.is_open()) //check if document is open
{
while(myFile >> maybe) //while numbers are still on document
{
TempStorage[i] = maybe; //input numbers into temporary array
i++; //index
}
myFile.close(); //close document
for(int n=0;n<9;n++) //first loop to control first index n
{
for(int q=0;q<9;q++) //second loop to control second index q
{
num[n][q] = TempStorage[x];//read numbers into multidimensional array
x++;
}
}
}
return 0;
}
However, when I output all the values stored in the multidimensional array, I get the following output. For some reason, it seems that the value of a previous index and the value of the first new index are equal.
1 2 3 4 5 6 7 8 10
10 11 12 13 14 15 16 17 19
19 20 21 22 23 24 25 26 28
28 29 30 31 32 33 34 35 37
37 38 39 40 41 42 43 44 46
46 47 48 49 50 51 52 53 55
55 56 57 58 59 60 61 62 64
64 65 66 67 68 69 70 71 73
73 74 75 76 77 78 79 80 1
I have changed the conditions on my for loops to just about everything that I could think of. Is this just some woefully simple problem that I am overlooking or is it something else?
for(int n=0;n<9;n++)
Your multidimensional array has an [8] size, which means it can get from 0 to 7.

call and print function which return array in c++

I have this functions which return a random array in c++:
int* randomArray(int countOfRows){
int test1 [countOfRows] = {};
int insertValue;
int check;
for (int n=0; n < countOfRows; ++n){
srand(time (NULL) );
while (test1[n] == NULL){
insertValue = (rand () %100 + 1 );
for(int i = 0; i < countOfRows; i++){
if (test1[i] == insertValue){
check = 1;
break;
}
else{
check = 0;
}
}
if (check == 0){
test1[n] = insertValue;
}
}
}
return test1;
}
How can I call that array?
what is the difference between int* and int[]
thank you :)
Your code has four significant problems, one of them critical, one non-standard and implementation dependent, and two general algorithmic problems.
First, the most important, you're returning the address of an automatic variable, which means it is both useless and will invoke undefined behavior to dereference by the caller. Declared at the top of your function is:
int test1 [countOfRows] = {};
which itself brings up the second point, this non-standard for two reasons: variable-length arrays are not supported by the C++ standard, and by inference, initialization of said-same is likewise not supported. Then later...
return test1;
The caller of your function will receive an address, but that address is useless. It no longer addresses anything concrete, as test1 no longer exists once the function returns. This is remedied a number of ways, and considering this is C++, the easiest is using a std::vector<int>, which supports value-return.
The two significant algorithm problems are
Your seeding of srand should not be in the for loop. In fact, if you're using srand and rand, the seeding should be done once in your entire process.
The process of exhaustive searching to see if a current random pick has already been used to avoid duplicates is needless if you simply use a different algorithm, which I'll cover later.
Therefore, the simplest fix for your code will be to do this:
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
std::vector<int> randomArray(int countOfRows)
{
std::vector<int> test1(countOfRows);
int check = 0;
for (int n=0; n < countOfRows; ++n)
{
while (test1[n] == 0)
{
int insertValue = (rand () %100 + 1 );
for(int i = 0; i < countOfRows; i++)
{
if (test1[i] == insertValue){
check = 1;
break;
}
else{
check = 0;
}
}
if (check == 0){
test1[n] = insertValue;
}
}
}
return test1;
}
int main()
{
std::srand(static_cast<unsigned>(std::time(NULL)));
std::vector<int> vec = randomArray(20);
for (auto x : vec)
std::cout << x << ' ';
std::cout.put('\n');
}
Output (varies, obviously)
8 50 74 59 31 73 45 79 24 10 41 66 93 43 88 4 28 30 13 70
A Finite Set Algorithm
What you're really trying to generate here is a finite set of integers in the range of 1..100. I.e., there are no duplicate values used, and the number of items being returned could be anything from 1..100 as well. To do this, consider this algorithm:
Generate a sequence of 1..100 in a std::vector<int>
Using a pseudorandom generator from the standard library, shuffle the sequence using std::shuffle
Resize the resulting vector to be the number of elements you want to return.
Regarding #3 from above, consider a small example, suppose you wanted just ten elements. Initially you build a sequence vector that looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13... ...99 100
Now you shuffle this vector using a std::shuffle and a pseudorandom generator like std::mt19937 : (the first twenty elements shown for brevity):
48 39 31 44 68 84 98 40 57 76 70 16 30 93 9 51 63 65 45 81...
Now, you simply resize the vector down to the size you want, in this case ten elements:
48 39 31 44 68 84 98 40 57
And that is your result. If this sounds complicated, you may be surprised to see how little code it actually takes:
Code
#include <iostream>
#include <algorithm>
#include <vector>
#include <numeric>
#include <random>
std::vector<int> randomSequence100(std::size_t count)
{
if (count > 100)
count = 100;
static std::random_device rd;
std::vector<int> result(100);
std::iota(result.begin(), result.end(), 1);
std::shuffle(result.begin(), result.end(), std::mt19937(rd()));
result.resize(count);
return result;
}
int main()
{
// run twenty tests of random shuffles.
for (int i=0; i<20; ++i)
{
auto res = randomSequence100(20);
for (auto x : res)
std::cout << x << ' ';
std::cout.put('\n');
}
}
Output
27 71 58 6 74 65 56 37 53 44 25 91 10 86 51 75 31 79 18 46
6 61 92 74 30 20 91 89 64 55 19 12 28 13 5 80 62 71 29 43
92 42 2 1 78 89 65 39 37 64 96 20 62 33 6 12 85 34 29 19
46 63 8 44 42 80 70 2 68 56 86 84 45 85 91 33 20 83 16 93
100 99 4 20 47 32 58 57 11 35 39 43 87 55 77 51 80 7 46 83
48 39 31 44 68 84 98 40 57 76 70 16 30 93 9 51 63 65 45 81
32 73 97 83 56 49 39 29 3 59 45 89 43 78 61 5 57 51 82 8
21 46 25 29 48 37 77 74 32 56 87 91 94 86 57 67 33 9 23 36
27 46 66 40 1 72 41 64 53 26 31 77 42 38 81 47 58 73 4 11
79 77 46 48 70 82 62 87 8 97 51 99 53 43 47 91 98 81 64 26
27 55 28 12 49 5 70 94 77 29 84 23 52 3 25 56 18 45 74 48
95 33 25 80 81 53 55 11 70 2 38 77 65 13 27 48 40 57 87 93
70 95 66 84 15 87 94 43 73 1 13 89 44 96 10 58 39 2 23 72
43 53 93 7 95 6 19 89 37 71 26 4 17 39 30 79 54 44 60 98
63 26 92 64 83 84 30 19 12 71 95 4 81 18 42 38 87 45 62 70
78 80 95 64 71 17 14 57 54 37 51 26 12 16 56 6 98 45 92 85
89 73 2 15 43 65 21 55 14 27 67 31 54 52 25 72 41 6 85 33
4 87 19 95 78 97 27 13 15 49 3 17 47 10 84 48 37 2 94 81
15 98 77 64 99 68 34 79 95 48 49 4 59 32 17 24 36 53 75 56
78 46 20 30 29 35 87 53 84 61 65 85 54 94 68 75 43 91 95 52
Each row above was a set of twenty elements take from the sequence of 1..100. No single row has duplicates (check if you want).
Caveat
This technique works wonderfully for either small domains or large result sets from larger domains. But it has its limits to consider.
For example: Once your potential domain reaches the point significant size (say, numbers in 1...1000000) and you want only small result sets (say, no larger than 100 elements), you're better off using a std::unordered_set and iterative probing similar to what you're doing now. The technique you use depends entirely on your performance goals and your usage patterns.
Counterexample: If you wanted a half-million unique elements shuffled from a million-element domain, the load/shuffle/resize technique will work well.
Ultimately you have to decide, and measure to confirm.
Some useful links about some of the things used here (bookmark this site, as it is absolute gold for information about C++):
std::vector
std::iota
std::random_device
std::mt19937
std::shuffle
From my view this function has problems.
It return the point of test1, which is allocated in the stack, which is invalid out of the scope of randomArray.
So if you change to malloc, this is allocated in heap, then it still valid when out of the scope of randomArray.
int *test1 = (int*) malloc(countOfRows* sizeof(int));
And you can using test1[x] to get the value of each int, for sure you should know the length of test1 is countOfRows.
Please don't forget to delete this point when it is not used...
Call this array is simple
int* values = randomArray(1000);
printf("%d\r\n",values[0]);
In the function randomArray() declare test1[] as a static int[].
return the array using pointers,
" return test1 "
in the main function use a pointer to access the return value
" int *ptr=randomArray(n) "

looking for the most accurate to sort double numbers [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I need to sort small float number.
When I use std::sort() //algorithm library,
I found that it's inaccurate in case of very very small numbers.
How can I sort this array in most accurate way?
edit : my friend suggested to me this lines of code which i don't understand them and they seemed don't work properly for the second items in pair
bool is_smaller(pair<double,int> a, pair <double , int> b)
{
return (b.first - a.first) > 1e9;
}
sort(a.begin(), a.end(), is_smaller);
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s;
cin >> s;
vector <pair<double,int> > a;
double x = 0, y = 1, k, d;
for(int i = 0;i < s.size();i++)
{
k = (x + y)/2;
d = abs(k - y);
//printf("[%.3lf %0.3lf] %.3lf %.3lf \n",x, y, k, d);
a.push_back({k,i+1});
if(s[i] == 'l')
y = k, x = k - d;
else
y = k + d, x = k;
}
sort(a.begin(), a.end());
for (int i =0;i < a.size();i++)
printf("%d\n",a[i].second);
return 0;
}
input : rrlllrrrlrrlrrrlllrlrlrrrlllrllrrllrllrrlrlrrllllrlrrrrlrlllrlrrrlrlrllrlrlrrlrrllrrrlrlrlllrrllllrl
code's output :
1
2
6
7
8
10
11
13
14
15
19
21
23
24
25
29
32
33
36
39
40
42
44
45
50
52
53
51
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
49
48
47
46
43
41
38
37
35
34
31
30
28
27
26
22
20
18
17
16
12
9
5
4
3
expected output :
1
2
6
7
8
10
11
13
14
15
19
21
23
24
25
29
32
33
36
39
40
42
44
45
50
52
53
54
55
57
61
63
64
65
67
69
72
74
76
77
79
80
83
84
85
87
89
93
94
99
100
98
97
96
95
92
91
90
88
86
82
81
78
75
73
71
70
68
66
62
60
59
58
56
51
49
48
47
46
43
41
38
37
35
34
31
30
28
27
26
22
20
18
17
16
12
9
5
4
3
comment :wrong answer 28th numbers differ - expected: '54', found: '51'
Floating point arithmetic has limited precision, although this precision is high with doubles, but it is still limited.
You algorithm generates a sequence of numbers, K(i), where
|K(i+1) - k(i)| = 2^(-i).
The |difference| above is a geometric sequence, so it decreases exponentially. Therefore, at some value of ì, the difference will become so small that it cannot be reported into the floating-point representation.
I ran your code with exactly the same input, but I also printed the numbers deside the indices, and I did not apply the sorting. I printed the numbers up to 50 decimal digits (%.50f, just to see!). What did I observe?
The numbers for positions i > 53 are all equal (within the precision that the double could achieve). Therefore, the numbers indexed above 53 will be sorted somehow randomly, because they are equal.
If you print the floats with enough precision:
printf("%03d %.18f\n",a[i].second,a[i].first);
then you'll see that the computations lead to the same floating point value for the rank 51 to 100...