Sorting array of integers C [closed] - c

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'm a beginner c programmer studying computer science and i'm trying to create a sorting program to sort an array of integers although i keep getting wrong results, this is what i got so far:
#include <stdio.h>
#include <string.h>
#define TAM 9
int sort_array(int num1[],int num2[]);
int main(){
int i=0;
int num1[TAM] = {5,6,2,4,7,1,3,0};
int num2[TAM] = {0};
int * ptr_num2 = num2;
sort_array(num1,num2);
while(*ptr_num2 != '\0'){
printf("%c",*ptr_num2+48);
ptr_num2++;
}
putchar('\n');
return 0;
}
int sort_array(int num1[],int num2[]){
int min=256,max=0,i,j;
int * ptr_num1 = num1;
int * ptr_max = num1;
int * ptr_num2 = num2;
/* check for max */
while(*ptr_max != '\0'){
if(*ptr_max > max) max = *ptr_max;
ptr_max++;
}
for(i=0;i<TAM-1;i++){
/* check for min */
for(j=0;j<TAM-1;j++){
if(*ptr_num1 < min) min = *ptr_num1;
ptr_num1++;
num1[i] = max;
}
*ptr_num2 = min;
ptr_num2++;
}
return 0;
}
I've been banging my head for several hours on this already.
EDIT: Forgot to mention that some of these things might not make sense since i'm just experimenting with a few things.

I understand you do not know about the typical array sorts... Well, let me to introduce you to one of the more simple ones. Allthough it's usually not the most efficient one, it's the easiest one to understand, and considering the fact you are messing with little arrays and not databases, it will be just fine.
I am talking about good old Chum, our Bubble sort.
Bubble sort is a well known simple array sorting algorithm -
The logic is simple. You go over the whole array on pairs of two - I.e, Array[0] with Array[1], Array[1] with Array[2], etc...
Whenever you find that things are not the way they are supposed to be - in your case, The larger index number is bigger than the lower index number - you swap between them, until you reach an iteration where you passed through the whole array and didnt swap at all.
In case you didn't understand well, here's Pseudo code from wikipedia (OMG who the heck uses wikipedia i'm such a n00b):
procedure bubbleSort( A : list of sortable items )
n = length(A)
repeat
swapped = false
for i = 1 to n-1 inclusive do
/* if this pair is out of order */
if A[i-1] > A[i] then
/* swap them and remember something changed */
swap( A[i-1], A[i] )
swapped = true
end if
end for
until not swapped
end procedure
And here's some C code:
#include <stdio.h>
int main()
{
int array[100], n, c, d, swap;
printf("Enter number of elements\n");
scanf("%d", &n);
printf("Enter %d integers\n", n);
for (c = 0; c < n; c++)
scanf("%d", &array[c]);
for (c = 0 ; c < ( n - 1 ); c++)
{
for (d = 0 ; d < n - c - 1; d++)
{
if (array[d] > array[d+1]) /* For decreasing order use < */
{
swap = array[d];
array[d] = array[d+1];
array[d+1] = swap;
}
}
}
printf("Sorted list in ascending order:\n");
for ( c = 0 ; c < n ; c++ )
printf("%d\n", array[c]);
return 0;
}
Here again, btw, the credit is not for me:
http://www.programmingsimplified.com/c/source-code/c-program-bubble-sort
Hope this helped you, and good luck :)

Related

Need help on an algorithm (stack overflow) [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
This is a problem a friend of mine gave me as a challenge. I've managed to come up with a recursive algorithm that works fine for small inputs, however I get segmentation faults for large values. I suppose that's because of a stack overflow. I use the C language for solving the problem.
You are given an array of n numbers. Find and print the maximum length of the subset such that for any two numbers form that subset, the sum of the numbers is not divisible by k.
Input contains on the first line 2 numbers n and k, on the next line there are n numbers a[i] such that:
1 <= n <= 10^5
0 <= a[i] <= 10^9
1 <= k <= 100
# Example input:
4 3
1 7 4 2
# Output:
3
Explanation: (1 7 4) 1 + 7 = 8; 1 + 4 = 5; 7 + 4 = 11; all of them non-divisible by 3.
My solution is based on the following idea: For all numbers in the array check the sum with the others if it is divisible by k. If we find a match then create 2 arrays, one excluding the first term of the sum and one excluding the second one, this way we exclude such pairs from our subsets. Then do the same thing we did to the first array to both of them. If we have checked all the elements from the the array then set the solution to the length of the array and continue applying the "solver" to only the arrays that have a length greater than the solution already found. This algorithm works well for n < 47 , more than that and it gives me a seg fault. I would like to see any solution that solves the problem.
#include <stdio.h>
int n, k;
int * deleteElement(int * a, int n, int j){
int *c = (int*) malloc((n-1) * sizeof(int));
int k = 0;
for(int i = 0; i < n; i++){
if(i == j) continue;
c[k] = a[i];
k++;
}
return c;
}
int sol = 0;
void solver(int *a, int n, int *sol){
int *b, *c;
if(n <= *sol) return;
for(int i = 0; i < n-1; i++){
for(int j = i + 1; j < n; j++){
if((a[i] + a[j]) % k == 0){
c = deleteElement(a, n, i);
b = deleteElement(a, n, j);
solver(c, n-1, sol);
solver(b, n-1, sol);
return;
}
}
}
*sol = n;
}
int main(){
scanf("%d", &n);
scanf("%d", &k);
int a[n];
for(int i = 0; i < n; i++) scanf("%d", &a[i]);
solver(a, n, &sol);
printf("%d\n", sol);
return 0;
}
You could use iteration to get rid of one of your two recursive calls, but that wouldn't help with stack space, since they have the same depth -- one call is as bad as 2.
It's easy enough to write a completely iterative algorithm that actually tests all the valid sets, but that's still an exponential time algorithm. In any case that this would save you from a stack overflow, it would take way too long to run. Since that algorithm would also suck, I don't want to write it.
A reasonable linear-time way to solve this problem is:
Calculate a map MODCOUNTS where MODCOUNTS[m] = the number of elements x such that x%k == m
Since any valid subset can only have one element divisible by k, if MODCOUNTS[0] > 1, then set MODCOUNTS[0]=1
Similarly, if k is even, and MODCOUNTS[k/2] > 1, then set MODCOUNTS[k/2]=1
Now, add up all the values in MODCOUNTS, but leave out a value MODCOUNTS[i] if:
i > 0, i*2 < k, AND MODCOUNTS[i] < MODCOUNTS[k-i]; OR
i*2 > k AND MODCOUNTS[i] <= MODCOUNTS[k-i]
rule 4 reflects that fact that a valid subset cannot include any elements x and y such that (x+y)%k = 0, for the cases that we didn't take care of in rules 2 and 3. The biggest valid subset includes all the elements from in MODCOUNTS[i], or all the elements in MODCOUNTS[k-i], but not elements from both.
If you use sparse data structure like a hash table to implement MODCOUNTS, then the whole thing takes O(N) time.

Function in C that realize the mathematical union of two arrays of int in another one [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
The language is ANSI C. I have 2 arrays of int: A and B. A has an index called m and B an index called n. The assignment says that m MUST BE different from n, so the arrays must have different size. I have coded already this. A is ordered ascending while B is ordered descending. I have to write a function that does the mathematical union of the two arrays in another one called C. If an element is in both the arrays you have to put only one in the array of the union (array C).
My code does not work very well. The last element is not ordered, I receive an output with a very big last number that I do not know from where it comes.
int index_c=index_m+index_n; //the index of array c
// is obtained by the sum of two indexes of the array A and B
int c[index_c];
int k=0;
for (i=0; i < index_m; i++)
{
for (j=0; j < index_n; j++)
{
if (a[i]==b[j])
{
c[k]=a[i]; //put only one time if is repeated more time in the two arrays
}
else
{
c[k]=a[i]; //put the a[i] element in the array c
c[k+1]=b[j]; //the element of the other array next to
}
}
k++;
}
printf("Elements in array C are: \n");
for (i=0; i<index_c; i++)
printf("element %d\n", c[i]);
It doesn't matter if the array C is not sorted, I will sort after the union. Any suggestions?
I am trying the suggestion of put k++ when I add 1 input, and k+2 when I add two input to array C. Now It works a bit well, but it doesn't full work. I mean in output I have not big number values but one of the output value (the 3rd) is the same as the first.
Example: 3 9 3 2 5 The second 3 is wrong and it's missing a number that is covered by the second 3.
Other example 2 4 2 1 9
I spot two immediate logical errors which should be fixed at the very least:
you either store one number in c, when both inputs are the same, and increase k by 1, or you store two numbers into c. You should then increase k with 2 as well. In the code you have now, you only have to add another +1 -- but consider putting these additions inside the if..else test blocks for clarity. Currently, you are overwriting the last one stored.
You print the result from 0 to index_c, the sum of the lengths of the two input arrays. That is not logical because you are throwing out numbers. Hence you get 'random' numbers as output; those are merely uninitialized, i.e. never written to. Print from 0 to k, as that is the valid range of your input.
So far none of the answers exploit the fact that the arrays are both sorted. Here is an implementation which is almost identical to a merge as suggested in the comments. The complexity of the merge is O(m + n).
I have assumed that each array has no duplicates (no [0, 1, 1, 3]), but you could add checks like if (k == 0 || k > 0 && C[k - 1] != A[i]) to fix this if I assumed wrong.
The function returns the length of C.C is sorted in increasing order. To have C be sorted in decreasing order instead change if (A[i] < B[j]) to if (A[i] > B[j]).
int union_merge(const int *A, int m, const int *B, int n, int *C) {
int i = 0, j = n - 1, k = 0;
while (i < m && j >= 0) {
if (A[i] < B[j]) {
C[k++] = A[i++];
} else if (A[i] == B[j]) {
C[k++] = A[i++];
--j;
} else {
C[k++] = B[j--];
}
}
while (j >= 0) {
C[k++] = B[j--];
}
while (i < m) {
C[k++] = A[i++];
}
return k;
}
Let's say that you have two arrays A and B, and union array C. You can input both arrays A and B into one array. Then you can sort that array and after sorting iterate over array and add value to array C(union array) if you didn't already add that value.Total complexity is O( N * log(N) ) Look at code:
#include <stdio.h>
#include <stdlib.h>
#define MAX 100000
int a[2*MAX+3], c[2*MAX+3];
int cmp(const void *a, const void *b) {
if ( *(int*)a < *(int*)b ) return -1;
if ( *(int*)a == *(int*)b ) return 0;
if ( *(int*)a > *(int*)b ) return 1;
}
int main() {
int i, k;
int n, m; scanf("%d%d", &n, &m); // size of the first array and size of the second array
n += m;
for(i = 0; i < n; ++i) // O(N) , input both arrays into one array
scanf("%d", &a[i]);
qsort(a, n, sizeof(int), cmp); // O( N * log(N) ), sort the given array
c[0] = a[0];
for(i = 1, k = 1; i < n; ++i) // O(N)
if(c[k - 1] != a[i]) // if the last element that you added to the union array is different than the current element in first array then add that element to union array
c[k++] = a[i];
for(i = 0; i < k; ++i) // O(K)
printf("%d ", c[i]);
return 0;
}

What are these last lines of code doing in Exercise 1-13 of K & R's The C Programming Language?

I am very new to programming in general, so please bear with my lack of knowledge.
I have spent a couple of hours now on exercise 1-13. I finally decided to look up the answer, which I found at this link https://github.com/ccpalettes/the-c-programming-language-second-edition-solutions/blob/master/Chapter1/Exercise%201-13/word_length.c .
Because I didn't want to copy it completely for the sake of learning, I tried to understand the code and then remake it. (This resulted in almost a complete copy, but I understand it better than I would have otherwise.)
This is what I have so far:
#include <stdio.h>
#define IN 1
#define OUT 0
#define LARGEST 10
main()
{
int c, state, l, i, j;
int length[LARGEST + 1];
for (i = 0; i <= LARGEST; ++i)
length[i] = 0;
state = OUT;
while ((c = getchar()) != EOF) {
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
if (state == OUT) {
l = 0;
state = IN;
}
++l;
}
else
if (state == IN) {
if (l <= LARGEST)
++length[l - 1];
//minus 1 because the nth term of an array is actually array[n-1]
else //if (l > LARGEST)
++length[LARGEST];
state = OUT;
}
if (c == EOF)
break;
}
for (i = 0; i <= LARGEST; ++i) {
if (i != LARGEST) //because array[10] refers to the 11th spot
printf("\t %2d |", i + 1); //plus one because 1st is array [0]
//this actually results in 1-10 because the 0-9 plus one makes the highest 10
else
printf("\t>%2d |", LARGEST);
for (j = 0; j < length[i]; ++j)
putchar('x');
putchar('\n');
}
return 0;
}
Please ignore my comments. They were meant for me, so that I could explain the program to myself.
I am having two issues that I just can't figure out, and they're driving me crazy:
The output always accounts for one word less than in the input, meaning "my name is not bob" results in:
...
2 |xx
3 |x
4 |x
...
Also, I don't understand what is going on at the end of the program. Specifically, I don't understand here why the variable j is being used:
for (j = 0; j < length[i]; ++j)
putchar('x');
Thanks so much for your help, and I'm sorry if this is too beginner for the community.
Well, trying to sum up all the answers since the question is not closed.
First, we need to correct the main() line:
int main(void) {
...
return 0;
}
The int is necessary because you return a value at the end of the function, and the void means that the function doesn't receive any arguments.
I've copied your code and executed on my machine (Ubuntu 12.04) and it worked perfectly. Could you present some examples to generate the error?
As everybody said, j is just a variable to traverse the vector. length[i] is a vector that holds, in each position i the number of words with length i. For instance, if position 3 has a value of 4, e.g. length[3] = 4, it means that there are 4 words
with length 3.
Finally, if I may, I'd like to give you a tip. It is good practice choosing meaningful names for your variables. The code you linked here helped me to understand what the program should do. Variable names such, length, or defines IN, OUT or LARGEST are too vague.
I hope this gather all answers until now and helped you even more.

Changing code to make it parallel [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 8 years ago.
Improve this question
#include <conf.h>
#include <kernel.h>
#include <stdio.h>
#define MAX_ITEMS 50
typedef long double LD;
int run_solve_equ();
void xmain(){
int pid;
pid = create(run_solve_equ, 20*INITSTK, INITPRIO, "B", 0);
resume(pid);
}
int solve_equ(LD b, int n, LD a[], int choosen[] ){
if ( n == 1 )
if (a[0] == b) {
choosen[0] = 1;
return 1;
} /* if */
else if (b == 0) {
choosen[0] = 0;
return 1;
} /* else if*/
else {
choosen[0] = 0;
return 0;
}
else /* n > 1 */
if (solve_equ(b, n-1, a, choosen)) {
choosen[n-1] = 0;
return 1;
} /* if */
else if (solve_equ(b - a[n-1],n-1, a, choosen)) {
choosen[n-1] = 1;
return 1;
} /* else if */
else{
choosen[n-1] = 0;
return 0;
}
} /* solve_equ */
LD a[MAX_ITEMS];
int choosen[MAX_ITEMS];
char pstr[200];
extern long int tod;
int run_solve_equ() {
int n, i, result;
LD b, sum;
printf("How many numbers? No more than %d:", MAX_ITEMS );
scanf("%d",&n);
puts("Enter b:");
scanf("%Lf",&b);
a[0] = 1;
for (i = 1; i < n; i++)
a[i] = a[i-1]*2;
result = 0;
sprintf(pstr, "time = %ld\n", tod);
printf(pstr);
result = solve_equ(b,n, a, choosen);
sprintf(pstr, "time = %ld\n", tod);
printf(pstr);
sprintf(pstr, "Solution for b = %Lf, n = %d, value = %d :\n", b,
n,result);
printf(pstr);
printf("\ni:\n");
for (i = 0; i < n; i++) {
sprintf(pstr, "%-16d",i);
printf(pstr);
} // for
printf("\na[i]:\n");
for (i = 0; i < n; i++) {
sprintf(pstr, "%-16.1Lf", a[i]);
printf(pstr);
} // for
printf("\nchoosen[i]:\n");
for (i = 0; i < n; i++) {
sprintf(pstr, "%-16d", choosen[i]);
printf(pstr);
} // for
printf("\n");
sum = 0;
for (i = 0; i < n; i++)
if (choosen[i]) {
sum += a[i];
sprintf(pstr, " + %-16.1Lf", a[i]);
printf(pstr);
} /* if */
sprintf(pstr, " = %-16.1Lf\n", sum);
printf(pstr);
return 0;
}
I need to change this program so the search will be "parallel" by two processes:
Each will search a n-1, the first user on a [n-1] and the other not.
the problem is to find a number in the array that all the number togother are equal to another number b !
Not an answer, but I do have some constructive comments for you.
Reading the above code hurts. It hurts my eyes and it hurts my brain. Why?
Variable Names are non-descriptive an often one letter (outside of I). b, n, a - I don't know what these are at a glance and I don't want to find out by understanding what you wrote. I bet you won't understand what you wrote next week either. Do everyone a favor and make the names better.
Please, please use a bit of white space between your "code thoughts". Your code looks like one long run-on sentence that also hides what it does.
Don't mix braced and non-braced code - especially when your indentation is not consistent. It is very, very difficult to follow your if logic as-is right now. Go ahead and waste a few bytes of hard disk space and perhaps .25 seconds adding braces or at least fixing your indents.
Write useful comments. /* if */ is a terrible comment and you do similar stuff everywhere. I know what an if is, but perhaps a quick not of what you are checking?
Don't mix globals and extern defines in the middle of your code. Keep them together and it makes it easier to remember what is global and what is not. This is the most minor offense though and others may disagree.
Anyways, a bit off topic for your question, which will more than likely close as you've put little effort into solving it yourself, but my comments may help you with future coding projects and will at least make it easier for others to help you going forward.

function to perform bubble sort in C providing unstable results

I am participating in Harvard's opencourse ware and attempting the homework questions. I wrote (or tried to) write a program in C to sort an array using bubble sort implementation. After I finished it, I tested it with an array of size 5, then 6 then 3 etc. All worked. then, I tried to test it with an array of size 11, and then that's when it started bugging out. The program was written to stop getting numbers for the array after it hits the array size entered by the user. But, when I tested it with array size 11 it would continuously try to get more values from the user, past the size declared. It did that to me consistently for a couple days, then the third day I tried to initialize the array size variable to 0, then all of a sudden it would continue to have the same issues with an array size of 4 or more. I un-did the initialization and it continues to do the same thing for an array size of over 4. I cant figure out why the program would work for some array sizes and not others. I used main to get the array size and values from the keyboard, then I passed it to a function I wrote called sort. Note that this is not homework or anything I need to get credit, It is solely for learning. Any comments will be very much appreciated. Thanks.
/****************************************************************************
* helpers.c
*
* Computer Science 50
* Problem Set 3
*
* Helper functions for Problem Set 3.
***************************************************************************/
#include <cs50.h>
#include <stdio.h>
#include "helpers.h"
void
sort(int values[], int n);
int main(){
printf("Please enter the size of the array \n");
int num = GetInt();
int mystack[num];
for (int z=0; z < num; z++){
mystack[z] = GetInt();
}
sort(mystack, num);
}
/*
* Sorts array of n values.
*/
void
sort(int values[], int n)
{
// this is a bubble sort implementation
bool swapped = false; // initialize variable to check if swap was made
for (int i=0; i < (n-1);){ // loops through all array values
if (values[i + 1] > values [i]){ // checks the neighbor to see if it's bigger
i++; // if bigger do nothing except to move to the next value in the array
}
else{ // if neighbor is not bigger then out of order and needs sorting
int temp = values[i]; // store current array value in temp variable for swapping purposes
values[i] = values[i+1]; //swap with neighbor
values[i+1] = temp; // swap neighbor to current array value
swapped = true; // keep track that swap was made
i++;
}
// if we are at the end of array and swap was made then go back to beginning
// and start process again.
if((i == (n-1) && (swapped == true))){
i = 0;
swapped = false;
}
// if we are at the end and swap was not made then array must be in order so print it
if((i == (n-1) && (swapped == false))){
for (int y =0; y < n; y++){
printf("%d", values[y]);
}
// exit program
break;
}
} // end for
// return;
}
You can easily use 2 nested for loops :
int i, j, temp ;
for ( i = 0 ; i < n - 1 ; i++ )
{
for ( j = 0 ; j <= n - 2 - i ; j++ )
{
if ( arr[j] > arr[j + 1] )
{
temp = arr[j] ;
arr[j] = arr[j + 1] ;
arr[j + 1] = temp ;
}
}
}
also you should now it's a c++ code not a c, because c doesn't have something like :
int mystack[num];
and you should enter a number when you're creating an array and you can't use a variable (like "int num" in your code). This is in C, but in C++ you're doing right.
The first thing to do when debugging a problem like this is ensure that the computer is seeing the data you think it should be seeing. You do that by printing out the data as it is entered. You're having trouble with the inputs; print out what the computer is seeing:
static void dump_array(FILE *fp, const char *tag, const int *array, int size)
{
fprintf(fp, "Array %s (%d items)\n", tag, size);
for (int i = 0; i < size; i++)
fprintf(fp, " %d: %d\n", i, array[i]);
}
int main(void)
{
printf("Please enter the size of the array \n");
int num = GetInt();
printf("num = %d\n", num);
int mystack[num];
for (int z = 0; z < num; z++)
{
mystack[z] = GetInt();
printf("%d: %d\n", z, mystack[z]);
}
dump_array(stdout, "Before", mystack, num);
sort(mystack, num);
dump_array(stdout, "After", mystack, num);
}
This will give you direct indications of what is being entered as it is entered, which will probably help you recognize what is going wrong. Printing out inputs is a very basic debugging technique.
Also, stylistically, having a function that should be called sort_array_and_print() suggests that you do not have the correct division of labour; the sort code should sort, and a separate function (like the dump_array() function I showed) should be used for printing an array.
As it turns out the reason why it was doing this is because when comparing an array's neighbor to itself as in:
if (values[i + 1] > values [i])
The fact that I was just checking that it is greater than, without checking if it is '=' then it was causing it to behave undesirably. So if the array is for example [1, 1, 5, 2, 6, 8] then by 1 being next to a 1, my program did not account for this behavior and acted the way it did.

Resources