I have a file containing data as follows
10 20 30 40 70
20 30 70
30 40 10 20
29 70
80 90 20 30 40
40 45 65 10 20 80
45 65 20
I want to remove all subset transaction from this file.
output file should be like follows
10 20 30 40 70
29 70
80 90 20 30 40
40 45 65 10 20 80
Where records like
20 30 70
30 40 10 20
45 65 20
are removed because of they are subset of other records.
the algorithm could be like this:
sets = list()
f = open("data.txt")
for line in f:
currentSet = set()
for item in line.split():
currentSet.add(int(item))
printIt = True
for s in sets:
if currentSet.issubset(s):
printIt = False
break
if printIt:
print line,
sets.append(currentSet)
Incidentally, this is also a Python program :) Also I believe that an algorithm with better effeciency could be made.
Your next step: rewrite this to C/C++. Good luck :)
Related
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.
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) "
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...
I am Getting WA in the Question GCD Condition from Codechef March Long Contest.
Kindly tell me what I've done wrong or some test case where the code produces Wrong answer.
Link for the Question
I Have used RMQ(Range maximum Query) for every prime number
for(i=0;i<limit;i++)
{
int sz=b[i].size();
if(!sz)continue;
int level=0;
cc[i].resize(sz);
for(j=0;j<sz;j++)cc[i][j].push_back(b[i][j]);//level 0
for(level=1;(1<<level)<=sz;level++)
{
for(j=0;j+(1<<level)<=sz;j++)
{
int c1=cc[i][j][level-1];
int c2=cc[i][j+(1<<(level-1))][level-1];
int mx=(a[c1]<a[c2])?c2:c1;
cc[i][j].push_back(mx);
}
}
}
firstly i have converted to a structure like the following:-
Example input:- 10 6 20 15 8
(b[i]-->stores the indices of factors of i)
b[2]--> 1,2,3,5
b[3]--> 2,4
b[5]--> 1,3,4
Now after implementing RMQ, it will be as follow:-
(cc[i][j][k] stores index of the largest element between b[i][j] and b[i][j+(2^k)-1])
cc[2][0]-->1,2,3,5
cc[2][1]-->1,3,3
cc[2][2]-->3
cc[3][0]-->2,4
cc[3][1]-->4
cc[5][0]-->1,3,4
cc[5][1]-->3
My Code
100 1
88 33 23 56 97 54 8 74 43 95 91 63 38 13 7 7 52 29 6 85 70 15 52 18 78 9 85 51 28 43 4 68 75 78 75 23 32 34 48 74 28 90 36 66 2 95 24 54 23 29 90 45 96 93 14 73 2 99 75 81 93 31 100 19 8 75 93 39 60 41 64 88 30 100 5 84 46 28 89 20 56 30 64 3 22 78 75 75 76 2 8 20 32 7 38 39 33 82 30 93
95 95 97
The output is -1 -1, but gcd(38, 95) = 19, so ans should be 38 1.
Replacing 'break' by 'continue' on line 75 gave AC :)
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
im trying to fill an array with random 200 numbers that can very from 0-100. I get it populated except the last couple number are very odd.
here my code.
for (int i = 0; i < NUM_LIST_ELEMENTS; i++)
{
int j = rand() % 100;
list[i] = j;
}
my output comes out at follows
Original Arrays:
41 67 34 0 69 24 78 58 62 64 5 45 81 27 61 91 95 42 27 36 91 4 2 53 92 82 21 16 18
95 47 26 71 38 69 12 67 99 35 94 3 11 22 33 73 64 41 11 53 68 47 44 62 57 37 59 23 41
29 78 16 35 90 42 88 6 40 42 64 48 46 5 90 29 70 50 6 1 93 48 29 23 84 54 56 40 66
76 31 8 44 39 26 23 37 38 18 82 29 41 33 15 39 58 4 30 77 6 73 86 21 45 24 72 70 29
77 73 97 12 86 90 61 36 55 67 55 74 31 52 50 50 41 24 66 30 7 91 7 37 57 87 53 83 45
9 9 58 21 88 22 46 6 30 13 68 0 91 62 55 10 59 24 37 48 83 95 41 2 50 91 36 74 20
96 21 48 99 68 84 81 34 53 99 18 38 0 88 27 67 28 93 48 83 7 21 10 17 13 14-858993460
9 16 35 51 0 49 19 56 98 3 24 8 44 9 89 2 95 85 93 43 23 87 14 3 48 0 58 18 80
96 98 81 89 98 9 57 72 22 38 92 38 79 90 57 58 91 15 88 56 11 2 34 72 55 28 46 62 86
75 33 69 42 44 16 81 98 22 51 21 99 57 76 92 89 75 12 0 10 3 69 61 88 1 89 55 23 2
85 82 85 88 26 17 57 32 32 69 54 21 89 76 29 68 92 25 55 34 49 41 12 45 60 18 53 39 23
79 96 87 29 49 37 66 49 93 95 97 16 86 5 88 82 55 34 14 1 16 71 86 63 13 55 85 53 12
8 32 45 13 56 21 58 46 82 81 44 96 22 29 61 35 50 73 66 44 59 92 39 53 24 54 10 45 49
86 13 74 22 68 18 87 5 58 91 2 25 77 14 14 24 34 74 72 59 33 70 87 97 18 77-33686019
notice that last number in each array is really weird. Is there anything I can do to avoid this? btw this is two different arrays.
Thanks everyone that posted! I got it working!
You are reading one beyond the end of the array.
e.g. if you populate an array with 200 elements, you should write to and read from 0 to 199 not 0 to 200 or 1 to 200.
By the way - rand() % 100 will not make numbers from 0 to 100. It will make numbers from 0 to 99 only.
Also, as Randy Howard says (thanks), you can get a more even random generation by following the advice at http://www.azillionmonkeys.com/qed/random.html .
This is probably because there is something wrong with your code that prints the result. You might be looping from index 0 to 200, which has 201 items.
I counted your outputs and found there is 201 items, if the last 77-33686019 are actually 2 separate numbers.
If it's not that, you might have some printf/cout somewhere further down your code that actually prints some other value. To confirm this you can probably try printf ("\n"); right after your loop that outputs the array. If your negative number ends up on a different line, you'll know it's some other printf further down your code.
You might want to use int j = rand() % 101; instead so that you get 0 to 100. Your original code gives you the random range from 0 to 99.