Bubble sort takes a long time then segfaults - c

Given an integer n, write a C program to count the number of digits that are in the same position after forming an integer m with the digits in n but in ascending order of digits. For example, if the value of n is 351462987 then value of m will be 123456789 and digits 4 and 8 will be in the same position.
This is my code:
#include<stdio.h>
void bubble(int a[],int length)
{
for (int i=0;i<length;i++)
{
for (int j=0;j<length;j++)
{
if (a[j]>a[j+1])
{
int t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
}
int check(int a[],int b[],int length)
{
int count=0;
for (int i=0;i<length;i++)
{
if (a[i]==b[i])
{
count=i;
break;
}
}
return count;
}
int length(int n)
{
int l;
while (n!=0)
{
n=n/10;
l++;
}
return l;
}
void main()
{
int n,arrn[100],temp[100];
scanf("%d",&n);
int l=length(n);
for (int i=0;i<l;i++)
{
arrn[l-i-1]=n%10;
temp[l-i-1]=arrn[l-i-1];
n=n/10;
}
bubble(temp,l);
int c=check(arrn,temp,l);
printf("%d",c);
}
I am able to compile the code but when I execute it it takes a long time only to show segmentation fault.

Easy answer, use a debugger.
Here are some problem with your code:
In length function, l is not initialized and as such can have an arbitrary initial value. In your case, you probably want to start at 0.
int l = 0;
Your check function probably don't do what you want. As written count is not a count but the index of a position where numbers match. As there is a break statement in the block, the loop will exit after the first match so the return value would be the position of the first match or 0 if no match was found.
Your bubble function goes one item too far when i is equal to length - 1 as you access item a[j + 1] in the inner loop which is out of bound. In that case, it is simpler to start at 1 instead of 0 and compare item at index i - 1 with item at index i.
Some extra notes:
It is recommended to add whitespace around operators and after a comma separating multiple declarations to improve readability. Here are some example of lines with improved readability.
int n, arrn[100], temp[100];
int count = 0;
for (int i = 0; i < length; i++)…
if (a[i] == b[i])…
arrn[l - i - 1] =n % 10;
temp[l - i - 1] = arrn[l - i - 1];
int check(int a[], int b[], int length)
Instead of writing multiple functions at once, you should write one function and ensure it works properly. By the way, the loop that split a number into digits could also be a function.
Try the function with small number (ex. 12 or 21)
Use better name for your variable. arrn and temp are not very clear. original and sorted might be better.

Your length function has a very obvious bug in it. What value does l start with? You don't initialise it so it could start with any value and cause undefined behaviour. You should set it to 0.
int length(int n)
{
int l = 0;
while (n!=0)
{
n=n/10;
l++;
}
return l;
}

Personally, I wouldn't be sorting or reading it into an int - to enable handling leading zeros in the digit string. For example:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAXNUMLEN 200
int main(void)
{
int i, j, l, x=0;
char numin[MAXNUMLEN], numout[MAXNUMLEN];
int digits[10]={0};
printf("enter a string of digits: " );
fgets(numin, sizeof(numin), stdin);
printf("\nsaw : %s", numin );
// walk string once, counting num of each digit present
l=strlen(numin);
for(i=0; i<l; i++) {
if( isdigit(numin[i]) ) {
int d = numin[i] - '0'; // char digit to int digit
digits[d]++;
}
}
// for each digit present, write the number of instances of the digit to numout
for( i=0; i<10; i++ ) {
for(j=0; j<digits[i]; j++)
numout[x++] = '0'+i; // int digit back to char digit
}
numout[x]='\0'; // terminate string
printf("sorted: %s\n", numout );
}
Sample run:
watson:digsort john$ ./ds
enter a string of digits: 002342123492738234610
saw : 002342123492738234610
sorted: 000112222233334446789
watson:digsort john$

Related

Double arrays in C

Im in the process of learning C and the basis of the class is C primer plus(6th edition). We use Eclipse as an IDE.
For an project we have to create to arrays. One array that takes numbers in a loop and another array that display the cumulative value. So if array 1 has values 1, 5 and 3(out of 10 inputs total) then the resulting input in array 2 should be 9(on the 3th input because of the 3 inputs in array 1).
Im having trouble getting started the right way - anyone here has ideas how I could proceed?
So far I have this for starters but forgive me for it it very weak:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
void doublearrays (double usernumber);
int main(void)
{
double usernumbers = 0.0;
int loop1 = 1;
while(loop1)
{
printf("Type numbers as doubles. \n");
fflush(stdout);
loop1 = scanf("%lf", &usernumber);
if(loop1)
{
doublearrays(usernumber);
}
}
return 0;
}
All the text in a homework assignment shall be read:
For a project we have to create two arrays... 10 inputs total...
Why on earth do not you declare them?... You already have defined SIZE so
double usernumbers[SIZE];
double cumulnumbers[SIZE];
Next do yourself a favour and handle one problem at a time:
One array that takes numbers in a loop...
Ok, so write a loop up to 10 reading floats directly into the array and note how many numbers were received
int n;
for(n=0; n<SIZE; n++) {
if (scanf("%lf", &usernumbers[n]) != 1) break;
}
// ok we now have n number in the first array
Let us go on
and another array that display the cumulative value.
Ok cumul is initially 0. and is incremented on each value from the first array:
double cumul = 0.;
for(int i=0; i<n; i++) {
cumul += usernumbers[i];
cumulnumbers[i] = cumul;
}
(your current code isn't what you need... delete it and then...)
anyone here has ideas how I could proceed?
Well the first step would be to actually define some arrays.
double input[SIZE];
double cum[SIZE];
The next step would be a loop to read input.
for (int i = 0; i < SIZE; ++i)
{
if (scanf("%lf", &input[i]) != 1)
{
// Input error - add error handling - or just exit
exit(1);
}
}
The next step is to add code for calculating the the cumulative value.
I'll leave that for you as an exercise.
The last step is to print the array which I also will leave to you as an exercise.
The straight forward way of doing this, which would also use two arrays and a loop construct would be to create something like this.. I've changed the doubles to integers. (and i am also ignoring any errors from scanf()).
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
static void
print_array(int *arr, const char *arr_name)
{
int i;
printf("%s = [");
for (i = 0; i < SIZE; i++)
printf("%d%s", arr[i], i < SIZE -1 ? ",":"");
printf("]\n");
}
int main(int argc, char **argv)
{
int i;
int input[SIZE];
int cumsum[SIZE];
for (i = 0; i < SIZE; i++)
{
int _input;
printf("Give me numbers!\n");
fflush(stdout);
scanf("%d", &_input); /* assuming integer */
input[i] = _input;
cumsum[i] = i > 0 ? cumsum[i-1] + _input : _input;
}
print_array(input, "input");
print_array(cumsum, "cumulative");
return 0;
}
or If you'd like to play around with pointers and have a bit more compact version.. perhaps this could be something to study to help you understand pointers, it does the same thing as my code above
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
static int data[SIZE*2];
int main(int argc, char *argv[])
{
int *input_p = &data[0];
int *cumsum_p = &data[0] + SIZE;
for (; input_p != &data[0] + SIZE; input_p++, cumsum_p++)
{
printf("Give me numbers!\n");
scanf("%d", input_p);
*cumsum_p = input_p == &data[0] ? *input_p : *(cumsum_p-1) + *input_p;
}
}

prime factorization of factorial in C

I'm trying to write a program that will print the factorial of a given number in the form:
10!=2^8 * 3^4 * 5^2 * 7
To make it quick lets say the given number is 10 and we have the prime numbers beforehand. I don't want to calculate the factorial first. Because if the given number is larger, it will eventually go beyond the the range for int type. So the algorithm i follow is:
First compute two’s power. There are five numbers between one and ten that two divides into. These numbers are given 2*1, 2*2, …, 2*5. Further, two also divides two numbers in the set {1,2,3,4,5}. These numbers are 2*1 and 2*2. Continuing in this pattern, there is one number between one and two that two divides into. Then a=5+2+1=8.
Now look at finding three’s power. There are three numbers from one to ten that three divides into, and then one number between one and three that three divides into. Thus b=3+1=4. In a similar fashion c=2. Then the set R={8,4,2,1}. The final answer is:
10!=2^8*3^4*5^2*7
So what i wrote is:
#include <stdio.h>
main()
{
int i, n, count;
int ara[]={2, 3, 5, 7};
for(i=0; i<4; i++)
{
count=0;
for(n=10; n>0; n--)
{
while(n%ara[i]==0)
{
count++;
n=n/ara[i];
}
}
printf("(%d^%d)" , ara[i], count);
}
return 0;
}
and the output is (2^3) (3^2) (5^1) (7^1).
I can't understand what's wrong with my code. Can anyone help me, please?
Much simpler approach:
#include <stdio.h>
int main(int argc, char const *argv[])
{
const int n = 10;
const int primes[] = {2,3,5,7};
for(int i = 0; i < 4; i++){
int cur = primes[i];
int total = 0;
while(cur <= n){
total += (n/cur);
cur = cur*primes[i];
}
printf("(%d^%d)\n", primes[i], total);
}
return 0;
}
Your code divides n when it is divisible for some prime number, making the n jumps.
e.g. when n = 10 and i = 0, you get into while loop, n is divisible by 2 (arr[0]), resulting in n = 5. So you skipped n = [9..5)
What you should do is you should use temp when dividing, as follows:
#include <stdio.h>
main()
{
int i, n, count;
int ara[]={2, 3, 5, 7};
for(i=0; i<4; i++)
{
count=0;
for(n=10; n>0; n--)
{
int temp = n;
while(temp%ara[i]==0)
{
count++;
temp=temp/ara[i];
}
}
printf("(%d^%d)" , ara[i], count);
}
return 0;
}
For finding factorial of a no pl. try this code:
#include <stdio.h>
int main()
{
int c, n, fact = 1;
printf("Enter a number to calculate it's factorial\n");
scanf("%d", &n);
for (c = 1; c <= n; c++)
fact = fact * c;
printf("Factorial of %d = %d\n", n, fact);
return 0;
}

Modify any element of the array

Given an array of integers , you can modify any of a number of arbitrary positive integer , and ultimately makes the entire array is strictly increasing and are positive integers , and asked at least need to change a few numbers
input: 5 1 2 2 3 4
output: 3
and there is what i have tried ,Each number in order to reduce more a ( first number minus one , then the second number minus two ,the third number minus three)
#include <stdio.h>
int Modify_the_array(int B[],int n);
int max(int a,int b);
int main(int argc,char *argv) {
int before_array[]={1,2,3,4,1,2,3,4,5};
int len=sizeof(before_array[0])/sizeof(before_array);
int b;
b=Modify_the_array(before_array,len);
printf("%d\n",b);
return 0;
}
int max(int a,int b){
return a>b?a:b;
}
int Modify_the_array(int B[],int len) {
int i,b=0,n=1;
int maxsofar,tmp,j;
for (i=0;i<len;i++){
B[i]=B[i]-n;
n++;
}
maxsofar=0;
tmp=0;
for(i=0;i<len;i++) {
for (j=i+1;j<len;j++) {
if (B[j]==B[i]&&B[i]>1) {
maxsofar=max(maxsofar,++tmp);
b=len-maxsofar;
}
}
}
return b;
}
somebody recommend there is another solution for this question,more efficently ,can anyone give me some advice,thank in advance
I came across the same problem recently. To make clear:
Problem Statement
You are given a sequence of integers a1,a2,a3.....an. You are free to replace any integer with any other positive integer. How many integers must be replaced to make the resulting sequence strictly increasing?
Input Format
The first line of the test case contains an integer N - the number of entries in the sequence.
The next line contains N space separated integers where the ith integer is ai.
Output Format
Output the minimal number of integers that should be replaced to make the sequence strictly increasing.
Given your input, len = 5, arr = [1 2 2 3 4], after minus index+1, get [0 0 -1 -1 -1].
Ignoring negative elements(these must be changed), compute Longest Increasing Subsequence(nondecreasing for this problem), which is a classic Dynamic Programming problem.
Denote the length of LIS = n(these elements will not be changed). So the final answer(the part doesn't belong to the increasing subsequence and the ignored negative part) is len-n(5-2=3).
We can compute LIS in O(nlogn) time with O(n) space.
int solve(vector<int> &arr) {
int len = arr.size();
for(int i = 0; i < len; i++) {
arr[i] -= i+1;
}
vector<int> lis(len,0);
int n = 0;
for(int i = 0; i < len; i++) {
if(arr[i] >= 0) {
int pos = binarysearchPos(lis,n,arr[i]);
lis[pos] = arr[i];
if(n == pos)
n++;
}
}
return len-n;
}
int binarysearchPos(vector<int> &arr, int n, int target) {
if(n == 0)
return 0;
if(arr[n-1] <= target)
return n;
int low = 0, high = n-1;
while(low < high) {
int mid = (low+high)/2;
if(arr[mid] > target) {
high = mid;
} else {
low = mid+1;
}
}
return low;
}

regarding scope of variable in C

#include<stdio.h>
int countdigits(int n);
int main(void)
{
int t,k;
scanf("%d %d",&t,&k);
long long N[t];
int i;
for (i=0;i<t;i++)
{
scanf("%lld",&N[i]);
}
int j,main_count=0;
for (j=0;j<t;j++)
{
int counter=0;
while (N[j] !=0)
{
if (N[j]%10 <=k)
{
counter++;
}
else
;
N[j]=N[j]/10;
}
if (counter==countdigits(N[j]))
main_count+=1;
}
printf("%d",main_count);
return 0;
}
int countdigits(int n)
{
int num,counter=0;
num=n;
for(;num !=0;num=num/10)
{
counter++;
}
return counter;
}
i am sure about the algo , the question is here
Let's call a number k-good if it contains all digits not exceeding k (0, ..., k).
You've got a number k and an array a containing n numbers.
Find out how many k-good numbers are in a (count each number every time it occurs in array a).
Input
The first line contains integers n and k (1 ≤ n ≤ 100, 0 ≤ k ≤ 9). The i-th of the following n lines contains integer ai without leading zeroes (1 ≤ ai ≤ 109).
Output
Print a single integer — the number of k-good numbers in a.
can somebody tell me where am i going wrong ?
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s;
int n, k, count = 0;
cin >> n >> k;
while (n--)
{
cin >> s;
int f[10] = {0};
bool good = true;
for (int i=0;i<s.size();i++)
f[s[i]-'0']=1;
for (int i=0;i<=k;i++)
if (f[i]==0)
good = false;
if (good)
count ++;
}
cout << count << endl;
return 0;
}
Accepted code on site. Trick was in "contains all digits not exceeding". problem description says that all numbers <= k must all be included. the problem didn't say that the numbers > k shouldn't be included. the fact that a digit greater than k exist or does not exist doesn't matter.

Find missing number between 1 to 100

This question has been asked here on SO before with below code
find3missing(int* array)
{
int newarray[100] = {0};
For i = 0 to 99
++newarray[array[i]] ;
For i = 0 to 99
If newarray[i] != 1
Cout << “the missing number is ” << i+1 << endl ;
}
But when I checked this code, it doesn't seem to work. Suppose I have an array of {1,2,6}. The output should be 3,4,5 but with the code above I get 1,4,5,6 instead. Below is my implementation of pseudo code with array size 6.
main()
{
int a[6]={1,2,6};
int tmp[6]={0},i;
for(i=0;i<6;i++)
{
++tmp[a[i]];
}
for(i=0;i<6;i++)
{
if(tmp[i]!=1)
{
printf("%d",i+1);
}
}
}
Is this the right code?
This ++newarray[array[i]] should be ++newarray[array[i] - 1]. This because you are interested in a sequence of 1-100 numbers, so no 0, but C arrays are 0 based. If you then look at the cout: the missing number is ” << i+1 here you "unshift" the number by adding 1.
There is another problem: you should pass the number of elements of the array, something like:
find3missing(int* array, int length) {
int newarray[100] = {0};
for (int i = 0; i < length; i++) {
++newarray[array[i] - 1] ;
}
C/C++ arrays are zero based, as A[i] is equivalent to *(A+i). So change ++newarray[array[i]] to ++newarray[array[i]-1]. Also use malloc, free and memset to use an array of dynamic size.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void find3missing(int* pArray, size_t size, int min, int max){
int* newarray;
int i;
unsigned int j;
int range = max - min;
if(range < 0)
return;
newarray = (int*) malloc(range*sizeof(int)); // allocate enough memory
memset(newarray,0,range*sizeof(int)); // set that block to zero
for(j = 0; j < size; ++j){
++newarray[pArray[j]-min];
}
for(i = 0; i < range; ++i){
if(!newarray[i])
printf("%d is missing!\n",min+i);
}
free(newarray);
}
int main(){
int test[] = {1,3,6};
find3missing(test,sizeof(test)/sizeof(int),1,6);
return 0;
}
Please note that this solution is very inefficient if your array is sorted. In this case have a look at Jimmy Gustafsson's answer.
This algoritm will be quite simple, since you're using a sorted array. Simply check if the current value +1 equals the nextvalue like below:
find3missing(){
int array[arraySize]; // the array with integers
for(i=0;i<arraySize;i++)
if(array[i]+1 != array[i+1]) // if value array[i]+1 is not equal the next index
// value, then it's a missing number
printf("A missing number: %i", i+1);
}

Resources