To answer everyone's first question: Yes, this is for school.
That being said, I feel like I'm pretty close to getting this to work, at least partially. Seems to sort most of the data, but I can't see any pattern to what is not being sorted.
#include <stdio.h>
#include <stdlib.h>
void quicksort(int *values, int size);
void printout(int[], int size);
void main(){
printf("starting");
int size=20;
int values[size];
int i;
for (i=0;i<size;i++){
values[i]=(rand()%113);
}
printf("\nBefore Sort:\n");
printout(values,size);
quicksort(values, size);
printf("\nAfter Sort:\n");
printout(values,size);
}
void printout(int values[],int size){
int i;
for (i=0;i<size;i++){
if (i % 20 == 0){
printf("\n");
}
printf("%3i ", values[i]);
}
}
void quicksort(int *values, int size){
if (size < 2){
return;
}
int pivot=values[size];
int left[size];
int right[size];
int center[size];
int i,lc,rc,cc; //counters for left, right and center arrays
lc=rc=cc=0; //initially 0
for (i=0; i<size-1; i++){
if (values[i] < pivot){
left[lc]=values[i];
lc++;
}
else if (values[i] > pivot){
right[rc]=values[i];
rc++;
}
else{
center[cc]=values[i];
cc++;
}
}
quicksort(left, lc);
quicksort(right, rc);
int lc2,rc2,cc2;
lc2=rc2=cc2=0; //note the first variable is lowercase L, not 1
while (lc2+cc2+rc2 < size-1){ // here we recombine our arrays
while (lc2 < lc){
values[lc2+rc2+cc2] = left[lc2];
lc2+=1;
}
while (cc2 < cc){
values[lc2+rc2+cc2] = center[cc2];
cc2+=1;
}
while (rc2 < rc){
values[lc2+rc2+cc2] = right[rc2];
rc2+=1;
}
}
}
My output for this is as follows:
Before Sort:
41 48 6 58 72 17 65 91 68 56 55 8 3 103 17 39 57 77 81 12
After Sort:
6 8 17 41 48 58 72 65 68 56 55 3 17 39 91 57 77 103 81 12
It's definitely doing something... Anybody have any ideas as to what the heck I'm missing here?
I've included tips on debugging that you can apply in the future to find problems like these.
Problem 1
int pivot=values[size];
size is past the end of the range being sorted. At the top level when the range is the entire array that means it's outside the array. And at the other levels it's either outside the array or the pivot value is from a different range.
Discovering this defect may require either careful code review or a tool designed to catch this sort of error such as is built into some compilers.
A more difficult method involves inspecting the runtime behavior, either with print statements or a debugger, and recognizing that the first pivot is not a value in the array. Testing with known input instead of random input helps with this method because it makes it more likely that you'll notice anything unexpected.
Problem 2
You also do not move the pivot into the correct location.
One technique for discovering this would be to check post-conditions. For example at the end of quicksort() the range should be sorted. So if you insert printout(values,size); at the end of that function then might notice in a few short cases where just the last element is out of order. Additional print statements can help you trace what's causing this.
Problem 3
main() must return int, not void.
Using a stricter compiler will catch this for you.
You're choosing the pivot wrong - values[size] lies outside of the range. If you want to use the last element, use values[size - 1].
Related
I've written this program to calculate the prime numbers up to len using Eratosthenes method. The program works fine and I can even calculate up to very large numbers like 999,999 and so on and I get a fine output. But the issue is that valgrind always shows me errors, no matter how small or how big len is.
Program:
#include <stdio.h>
#include <stdlib.h>
int main(){
size_t len=100;
int *array=malloc(len * sizeof(*array));
// initialize all elements to 1
for(int i=0;i<len;i++)
array[i]=1;
//set multiples of array[a] to 0
for(int a=2;a<len;a++){
for(int b=2;b<len;b++){
if(a*b>len)
break;
array[a*b]=0;
}
}
//print the index of "1"s in the array
for(int a=2;a<=len;a++){
if(array[a]==1)
printf("%d ", a);
}
printf("\n");
free(array);
return 0;
}
Errors:
I compile using: gcc -std=c99 -Wall -g test.c -o test
Output: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
gdb shows no errors or malfunction
valgrind ./test shows:
==10134== Invalid write of size 4
==10134== at 0x400695: main (...)
==10134== Address 0x52041d0 is 0 bytes after a block of size 400 alloc'd
==10134== at 0x4C2DB8F: malloc (...)
==10134== by 0x400625: main (...)
==10134==
==10134== Invalid read of size 4
==10134== at 0x4006D9: main (...)
==10134== Address 0x52041d0 is 0 bytes after a block of size 400 alloc'd
==10134== at 0x4C2DB8F: malloc (...)
==10134== by 0x400625: main (...)
==10134==
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
==10134==
==10134== HEAP SUMMARY:
==10134== in use at exit: 0 bytes in 0 blocks
==10134== total heap usage: 2 allocs, 2 frees, 1,424 bytes allocated
==10134==
==10134== All heap blocks were freed -- no leaks are possible
==10134==
==10134== For counts of detected and suppressed errors, rerun with: -v
==10134== ERROR SUMMARY: 8 errors from 2 contexts (suppressed: 0 from 0)
As you can see in the code, I am declaring my array as int *array=malloc(len * sizeof(*array)); which seems to me to be the problem. If I declare it like this: int array[len];, valgrind doesn't show me error for small numbers of len, which is also something that fascinates me. Higher numbers of len with VLA declaration causes some unexpected behavior. So what is happening here? Is there anything wrong with the code or can I simply ignore the valgrind errors, since the output is ok? Also, as I said earlier, the program works fine for very large numbers like 999,999 but running valgrind for that len gives exactly 999,999 errors in valgrind. Any explanation is highly appreciated :)
Your malloc is correct, sizeof(*array) is the same as sizeof(int), because *array is an int.
for(int a=2;a<=len;a++) overflows array because array[len-1] is the last element in the array and eventually you do
if(array[a]==1)
printf("%d ", a);
with a==100 which is out of bounds.
It should be
for(int a=2;a<len;a++)
if(array[a] == 1)
printf("%d ", a);
Edit
As Jonathan Leffler has pointed out in the comments,
if(a*b>len)
break;
if also wrong. For a==2 and b==50 you have a*b==100 which is not greater
than len and you are accessing out of bounds again. The condition should be
if(a*b >= len)
break;
Just two comments about your code:
The algorithm implemented here is not exactly the algorithm known as The sieve of Erathostenes, because if you analyse your code you'll see that you have two loops, running all possible values of a and b and marking them as compound. Yes, you finish with a sieve... but that was not the efficient one from Erathostenes. The sieve of Erathostenes consists in getting the next unmarked element, and mark all elements that are multiples of it (until you reach the maximum index, at len) this is something like:
#include <stdio.h>
#include <stdlib.h>
#define N 10000
#define sqrt_N 100
int array[N];
int main(){
int a, b;
/* better to leave them at 0 and marking with ones */
// initialize all elements to 1
//for(int i=0;i<len;i++)
//array[i]=1;
//set multiples of a to 1
/* We only need to do this upto sqrt_N because if a unmarked number
* is discovered above sqrt_N it will be marked (as compund) because
* it was the product of a number less than sqrt_N or be prime (because
* it cannot be the product of two numbers greater than the sqrt(N)
* or it would be greater than N. */
for(a = 2; a < sqrt_N; a++){
if (array[a] == 0) { /* do the inner loop only if a is a prime */
for(b = 2; a * b < N; b++)
array[a * b] = 1;
}
}
//print the index of "0"s in the array
for(a = 2; a <= N; a++){
if(!array[a])
printf("%s%d", a == 2 ? "" : ", ", a);
}
printf("\n");
//free(array); /* array is no more dynamic */
return 0;
}
just check the computation time and you'll see it runs faster than yours.
The problem you are having with a declaration like this:
int sieve[999999];
is that, if you put that as a local variable on main() (as you do) it is going to be stored in the stack, so that means you need at least one million integers (of size 4, most probably) and this is four megabytes in the stack. I don't actually know the operating system you are using, but it is common that the stack size is limited (in the order of 4-10 Mb) so you can overflow the stack if you are not careful with the size of your automatic variables.
The invalid write message from valgrind(1) comes from the fact that you have written the following code:
if (a*b > len) break;
and that means that, in the possible case that a*b results exactly len, you are writing in the array cell array[len] which is outside of the bounds of array (by one, they go from 0 to len - 1) You have to change that line to read:
if (a*b >= len) break;
or
if (a*b < len) {
array[a*b] = 0;
}
This program takes as an input the following lines:
23 12 33 19 10 8
5
23 19 8 12 60 18
14 60 12 44 54 10
8 3 12 19 33 10
33 15 7 60 12 10
22 12 19 23 33 11
23 12 33 19 10 8 ( The first line ) are the lottery results.
n ( in this specific case, 5 ) informs how many lines will follow below.
Each line has 6 numbers. The number order doesn't matter.
The rules are: numbers range from 1 to 60 ( including 1 and 60 ) and they never repeat themselves in the same line.
The variable "quadra" stores how many lines have got 4 numbers right.
The variable "quina" stores how many lines have got 5 numbers right.
The variable "sena" stores how many lines have got 6 numbers right.
So, a computer program is running some tests over my code below and it's claiming that it goes wrong for most of them, but I can't see what's the problem here. Does anybody have a clue? Is this code wrong, or is there something wrong with the software that's testing this code?
#include <stdio.h>
int main(){
int mega[6];
int v[50500][6];
int n,swap;
int i,j,k; //counters
int quadra,quina,sena;
quadra = 0;
quina = 0;
sena = 0;
for(i=0;i<6;++i) scanf("%i",&mega[i]); //first line, lottery results
scanf("%i",&n);
for(i=0;i<n;++i){
for(j=0;j<6;++j){
scanf("%i",&v[i][j]);
}
}
for(i=0;i<n;++i){
for(j=0;j<6;++j){
for(k=0;k<6;++k){
if(v[i][j] == mega[k]){
v[i][j] = 61;
}
}
}
}
//reverse bubble sort
for(i=0;i<n;++i){
for(j=0;j<6;++j){
for(k=j+1;k<6;++k){
if(v[i][j] < v[i][k]){
swap = v[i][k];
v[i][k] = v[i][j];
v[i][j] = swap;
}
}
}
}
for(i=0;i<n;++i){
for(j=0;v[i][j] == 61 && j<6;++j);
if(j == 4) ++quadra;
else if(j == 5) ++quina;
else if(j == 6) ++sena;
}
return 0;
}
Your code is true, I understood and tried the flow of it. Looks fine but if you dont need to sort everyline (and use j as a counter in this loop for(j=0;v[i][j] == 61 && j<6;++j); ), you can use simpler ifstatements to compare real lottery results with the ones that entered. What I mean is that your algorithm is a little complex. Try a simple one and see how it works.
Yes, there are a couple of noteworthy issues with your code:
Compile time indicates possibility of uninitialized variable:
But, run-time results in fatal run-time at unknown source location. Stack overflow. It is likely due to this line:
int v[50500][6];
Increase your stack size. It needs to be about 2.5Mbytes for v alone.
Also, this line may not be what you intended:
for(i=0;i<6;++i) scanf("%i",&mega[i]); //first line, lottery results
^
If you meant to loop around the remainder of the code, remove the ; after the for() statement, and use curly braces:
for(i=0;i<6;++i) scanf("%i",&mega[i]) //first line, lottery results
{
scanf("%i",&n);
....
Thing is, we have N pairs of integers, as an example:
23 65
45 66
22 65
80 20
30 11
11 20
We say one pair is bigger than another one if both numbers from one pair are greater than the other two, or if the first number is equal and the other one is bigger, or vice-versa. Otherwise, if you can't compare them that way, then you can't establish which one is bigger.
The idea is to know, for each pair, how many pairs it is bigger to (in the example, the first pair is bigger than the third and the last one, therefore the answer for the first is 2).
The trivial solution would be O(n2), which is simply comparing every pair to every other one and adding one to a counter for each positive match.
Can anybody come up with a faster idea?
I have implemented the simple solution (N2), works reading from "sumos.in":
#include <iostream>
#include <fstream>
#define forn(i, x, N) for(i=x; i<N; i++)
using namespace std;
ifstream fin("sumos.in");
ofstream fout("sumos.out");
struct sumo{
int peso, altura;
};
bool operator < (sumo A, sumo B) {
if( A.altura == B.altura )
if( A.peso < B.peso )
return true;
else
return false;
else
if( A.peso == B.peso )
if( A.altura < B.altura )
return true;
else
return false;
else
if( (A.altura < B.altura) && (A.peso < B.peso) )
return true;
else
return false;
}
int L;
sumo T[100000];
int C[100000];
int main()
{
int i, j;
fin >> L;
forn(i, 0, L)
fin >> T[i].peso >> T[i].altura;
forn(i, 0, L)
forn(j, 0, L)
if( j!=i )
if( T[j]<T[i] )
C[i]++;
forn(i, 0, L)
fout << C[i] << endl;
return 0;
}
Example of input:
10
300 1500
320 1500
299 1580
330 1690
330 1540
339 1500
298 1700
344 1570
276 1678
289 1499
Outputs:
1
2
1
6
3
3
2
5
0
0
I solved this problem by using a segment tree. If you wish to see the implementation: http://pastebin.com/Q3AEF1WY
I think I came up with a solution to this but it is rather complex. The basic idea is that there are these groups where the pairs can be arranged in dominated order for example:
11 20 30 11
22 65 80 20
23 65
45 65
If you start thinking about taking your pairs and trying to create these groupings you realize you will end up with a tree structure. For example imagine we added the pair 81 19 to the list and add a pair (-∞, -∞)
(-∞, -∞)
/ \
11 20 30 11 ---\
22 65 80 20 81 19
23 65
45 65
If you follow the path from a node to the root you will count how many pairs the current pair dominates. From this example it kind of looks like you can use binary search to figure out where to insert a pair into the structure. This is where the complexity troubles start. You can't do a binary search/insertion on a linked list. However there is a very neat data structure called a skip list you might use. You can basically search and insert in O(logn) time.
There's still one problem. What if there are tons of these groupings? Imagine a list like
11 20
12 19
13 18
14 17
You're tree structure will look like:
(-∞, -∞)
/ / \ \
11 20 12 19 13 18 14 17
Again use skip lists to order these nodes. I think this will require two different kinds of nodes in the tree, a horizontal type like above and a vertical type like in the first examples. When you are done constructing the tree, do a iterate the tree with DFS while recording the current depth to associate each pair with the number of nodes it dominates.
If the above algorithm is correct you could insert a the pair into the tree in O(logn) time and thus all the pairs in O(nlogn) time. The DFS part will take O(n) time thus constructing the tree and associating a pair with the number it dominates will take O(nlogn) time. You can sort the pairs based on the number of dominations in O(nlogn) time so the whole process will take O(nlogn) time.
Again there is probably a simpler way to do this. Good luck!
You can use. A sort. like this
int z = {23,65,45, 66,22,65,80,20,30,11,11, 20};
int i, j, k, tmp;
for (i=1; i<n; i++){
j= n-i-1;
for (k=0; k<=j; k++)
//Put attention on this block.
if (z[k]>z[k+1]){
tmp= z[k];
z[k]= z[k+1];
z[k+1]= tmp;
}
}
I'm actually working on a projecteuler.com problem (#12 specifically) and I thought I had this nailed when I wasn't getting any compile errors.
It runs and gives me several results that appear to be correct, but it's not finishing. I haven't been using C all that long so I am probably overlooking something I'm just not familiar with. Can someone tell me why it's stopping? It is giving me correct triangle numbers up to 12.5M. I would also gladly accept optimization suggestions in the comments.
The results are first, even after a few hours it didn't move on past the first number with 30 factors, which it found rather quickly.
It gives me this, from the code following it:
$ ./euler12
Current= 1
Factors= 1
Current= 3
Factors= 2
Current= 6
Factors= 4
Current= 28
Factors= 6
Current= 36
Factors= 9
Current= 120
Factors= 16
Current= 300
Factors= 18
Current= 528
Factors= 20
Current= 630
Factors= 24
Current= 1008
Factors= 30
where Current gives me the number it got the factors from and obviously then Factors is the number of factors. I doesn't give me any errors and the only warning from -Wall is that I don't actually use the "useless" variable for anything.
#include <stdio.h>
#include <time.h>
/*
Tristen
euler12.c
December 23, 2013
What's the value of the first triangle number to have over 500 divisors?
*/
int main(void)
{
/*---------Variables----------*/
time_t t1 = time(NULL);
int g,l,i,j,k,t,number,val,flag1,flag2;
int h=1,x=0,p=0,n=5000,m=500,m2=600,twitch=0
int answer=0,count=0,useless=0,linlen=0; /*modify n to change size*/
/*----------Arrays------------*/
int numtocheck[n];
int factors[m2];
/*find triangle numbers*/
for(i=0;i<=n+1;i++){
x+=i;
if(x!=0){
numtocheck[i]=x;
}
else{
useless=0;
}
}
/*begin checking for factors*/
while(twitch!=1){
count=0;
for(l=1;l<m2;l++){
factors[l]=0;
}
number=numtocheck[h];
for(j=0;j<=number;j++){
for(k=0;k<=number;k++){
val=j*k;
if(val==number){
flag1=0,flag2=0;
for(g=0;g<m2;g++){
if(factors[g]==j){
flag1=1;
}
else if(factors[g]==k){
flag2=1;
}
else{
useless=0;
}
}
if(flag1==0){
factors[p]=j;
p+=1;
}
else if(flag2==0){
factors[p]=k;
p+=1;
}
else{
useless=0;
}
}
}
}
for(l=0;l<m2;l++){
if(factors[l]!=0){
count+=1;
}
}
if(count>=m){
answer=number;
printf("Current= %d\n",number);
printf("Factors= %d\n",linlen);
twitch=1;
}
else{
if(count>linlen){
linlen=count;
printf("Current= %d\n",number);
printf("Factors= %d\n",linlen);
}
else{
useless=0;
}
}
h+=1;
}
time_t t2 = time(NULL);
t=t2-t1;
printf("Survey says %d\n", answer);
printf("time %d\n", t);
getchar();
return 0;
}
Here are some points to consider (point 5 is the big problem):
1) you forgot a semicolon so this code won't compile, based on this, I'm a little concerned you don't have everything in here verbatim to how you have it...
int h=1,x=0,p=0,n=5000,m=500,m2=600,twitch=0 //<- ; needed
2) as noted in the comments your first for loop overflows the array:
int n=5000;
int numtocheck[n];
/* so numtocheck[] goes from 0 to 4999 */
/*find triangle numbers*/
for(i=0;i<=n+1;i++){ // this loops from 0 to 5001
So this needs to be:
for(i=0;i<n;i++){
3) since you don't initialize the 0th element of numtocheck that means there is garbage data in numtocheck[0]. Same thing later for factors[0], the latter is OK since you over write it, but it's just something to be careful about.
4) You use useless to avoid empty else cases... this is, as you aptly named it, useless. If you don't have anything to do, don't do anything.
For example instead of writing this:
if(count>linlen){
linlen=count;
printf("Current= %d\n",number);
printf("Factors= %d\n",linlen);
}
else{
useless=0;
}
Just remove the else, a if can be paired with an else, it does not need to be.
5) OK, here's the big problem:
if(flag1==0){
factors[p]=j;
p+=1;
}
else if(flag2==0){
factors[p]=k;
p+=1;
}
factors[] is an array of 600 elements, and you access using p a value that's initially 0 but is incremented every time it enters either of these checks. By the time your number is around 2346 p more than overflows the 600 elements in factors[] and you start doing bad things. This causes undefined behavior. On one implantation in Linux this caused a very nice setfault. On a different one in Windows this simply over wrote the values in numtocheck basically making you go into an infinite loop.
int count;
int main(){
count=0;
printf("%6d\t %6d\t %6d\t ",i+1,multiFib(i),count);
}
int multiFib(int x){
if (x<2){
return 1;
count++;
}}
In this code, count always gives 0 result. I made it a global variable, not to define it in the function again. How can I increase that variable?
It outputs in order; that is not problem. It gives the result:
1 1 0
-
2 1 0
-
3 2 0
So, count is not increasing — but why?
Although order of evaluation is not guaranteed (see multiple other answers), there is another, more fundamental problem (actually, two of them):
int multiFib(int x)
{
if (x<2){
return 1;
count++;
}
}
You attempt to increment count after you've returned from your function. Your compiler should be warning about unreachable code.
You don't return a value from multiFib() when the input is bigger than 2.
The fragment of main() that you show references an undefined variable i. I assume that is because you deleted a for (i = 0; i < 40; i++) loop from before the printf() statement. To fix the 'order of evaluation' problem, you might want to use:
int count;
int main(void)
{
for (int i = 0; i < 40; i++)
{
count = 0;
int fib = multiFib(i);
printf("%3d %10d %10d\n", i+1, fib, count);
}
return(0);
}
This evaluates the number of calls to multiFib() for each top-level call to the function.
For the multiFib() function itself, you probably need:
int multiFib(int x)
{
count++;
if (x < 2)
return x;
else
return multiFib(x-1) + multiFib(x-2);
}
Though this is an appallingly slow implementation of Fibonacci numbers so you shouldn't use this as an answer to your homework (but it does make a 'working' function).
Example output:
1 0 1
2 1 1
3 1 3
4 2 5
5 3 9
6 5 15
7 8 25
8 13 41
9 21 67
10 34 109
11 55 177
12 89 287
13 144 465
14 233 753
15 377 1219
16 610 1973
17 987 3193
18 1597 5167
19 2584 8361
20 4181 13529
21 6765 21891
22 10946 35421
23 17711 57313
24 28657 92735
25 46368 150049
26 75025 242785
27 121393 392835
28 196418 635621
29 317811 1028457
30 514229 1664079
31 832040 2692537
32 1346269 4356617
33 2178309 7049155
34 3524578 11405773
35 5702887 18454929
36 9227465 29860703
37 14930352 48315633
38 24157817 78176337
39 39088169 126491971
40 63245986 204668309
Note that if you go much beyond 40, you start getting arithmetic overflow. It also gets to be very (very, very) slow.
This:
if (x<2){
return 1;
count++;
}
You return from the function before you increment count. So it's never incremented.
Return doesn't just set the returned value. It actually exits the function at that point.
Just swap the order of those two lines. Also, you should keep an eye on your compiler warnings. Any decent compiler will warn you that the count++; line is unreachable.
printf("%6d\t %6d\t %6d\t ",i+1,multiFib(i),count);
The order of function argument evaluation is unspecified in C. multiFib can be evaluated before or after count in the printf function call.
The order of evaluation of function arguments is not specified.
In your code,
printf("%6d\t %6d\t %6d\t ",i+1,multiFib(i),count);
The argument to printf function multiFib(i) might be getting called after printing count.
Try this,
printf("%6d\t",multiFib(i));
printf("%6d\t %6d\t ",i+1,count);
to check the result.
As it was said in another answers, problem is that order of evaluation of function arguments is not specified, so in your example:
printf("%6d\t %6d\t %6d\t ",i+1,multiFib(i),count);
You can not be sure if count will be evaluated before or after passing multiFib(i) to the printf() function.
Please look here for more detailed information about evaluation order in C++, or here for evaluation order in C.
You might also find useful to force evaluation order by separating your printf into two calls:
printf("%6d\t",multiFib(i));
printf("%6d\t %6d\t ",i+1,count);
like Nishith Jain M R suggested in his answer.