Can somebody please help me with the mistake in algorithm [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Problem Link: https://www.codechef.com/problems/PERMUT2
Problem : Getting non ambiguous for all test cases. There is absolutely no problem in executing the program, no errors.
Can you please point out the mistake in my code/algorithm:
#include <stdio.h>
#include <stdlib.h>
int index_func(int number, int *array, int x);
int main(){
int n;
scanf("%d", &n);
int *nums = (int*)malloc(n*sizeof(int));
int i;
for(i=0; i<n; i++){
scanf("%d", &nums[i]);
}
int j;
int counter = 0;
for(j=0; j<n; j++){
if(nums[j] != index_func(j+1, nums, n)){
counter = 1;
break;
}
}
if(counter == 0){
printf("ambiguous\n");
}else{
printf("non ambiguous\n");
}
return 0;
}
int index_func(int number, int *array, int x){
int z, index;
for(z=0; z<x; z++){
if(number == array[z]){
index = z;
return z;
}
}
}

The numbers in the array start with one, but the indices in C arrays start with 0. A quick fix to your program would be to add one to the returned index when you compare it to the current number:
if (nums[j] != index_func(j + 1, nums, n) + 1) ...
An alternative solution is to adjust the array data by subtracting one after you scan it, so that the array contains zero-based numbers.
A problem may arise with larger arrays, because every call to index_func scans the whole array from the beginning and will traverse half of it on average. The solution will be correct, but very slow.
But you don't have to determine the index to do the comparison. It is sufficient to check whether the number at the index of the current number is the current index. That leads to this function:
int is_ambiguous(const int *array, int n)
{
int i;
for (i = 0; i < n; i++) {
if (array[array[i] - 1] != i + 1) return 0;
}
return 1;
}
Some notes on your original code:
You should return an invalid index, probably −1, from index_funct when the nuber isn't in the array. I know, this shouldn't happen here, but next time you copy and paste the code and the missing return value might bite you.
You don't really need the variable index in index_funct. Separating pieces of code into small functions can make the program control easier. Compare the above function is_ambiguous with your inline solution with a counter variable and a break.
When you allocate, you must also free, which you don't.

try this solution:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int index_func(int number, int *array, int x);
int main(){
int n;
scanf("%d", &n);
int *nums = (int*)malloc(n*sizeof(int));
int i;
for(i=0; i<n; i++) {
scanf("%d", &nums[i]);
}
int j;
int counter = 0;
for(j=0; j<n-1; j++){
if((abs(nums[j+1] - nums[j]) != abs(n-1)) && (abs((nums[j+1] - nums[j]) != 1)))
{
counter = 0;
}
else
{
counter = 1;
}
}
if(counter == 0){
printf("ambiguous\n");
}else{
printf("non ambiguous\n");
}
free(nums);
return 0;
}

Related

The count of duplicate elements is double what it should be

I am working on an old exam and the problems states that a given array (int zahlen[]={1,4,5,1,5,7,9,2,3,4}) has values that are the same. The task is to replace the values that are the same with '-1'. After each replacement, a given variable, count, has to be increased by one.
My problem is that the variable count is two-times higher than normal (In this case there are only 3 of the same numbers and the variable shows 6.)
The function is called array_unique. I am would be grateful for a brief explanation of my mistake.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
system("chcp 1252");
int zahlen[]={1,4,5,1,5,7,9,2,3,4};
int len = sizeof(zahlen)/sizeof(int);
int erg = array_unique(zahlen,len);
printf("Es wurden %d doppelte Zahlen gelöscht: \n",erg);
printf("Das Array hat nun folgende Werte: ");
printArrayUnique(zahlen,len);
return 0;
}
void printArrayUnique(int *array, int len){
for(int i=0; i<len; i++){
if(array[i]!=-1){
printf("%d ",array[i]);
}
}
}
int array_unique(int *array, int len){
int count=0;
for(int i=0; i<len;i++){
for(int j=i+1; j<len;j++){
if(array[i]==array[j]){
array[j] = -1;
count++;
}
}
}
return count;
}
I have not figured out any other solution to fix the faulty value of count.
The issue is due to the fact that your are counting duplicates more than once; so, when you have found a duplicate entry, you correctly replace that with -1 but then, later in the loops, you will be (potentially, at least) comparing two or more of those -1 values.
Just add a check that either value is not -1 (along with the test for equality) before incrementing the count variable:
int array_unique(int* array, int len)
{
int count = 0;
for (int i = 0; i < len; i++) {
for (int j = i + 1; j < len; j++) {
if (array[i] == array[j] && array[j] != -1) {
array[j] = -1;
count++;
}
}
}
return count;
}
Note also that, as mentioned in the comments, you really do need declarations of your functions before you use them. Add the following two lines before the main function:
void printArrayUnique(int* array, int len);
int array_unique(int* array, int len);

C buggy program [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 4 years ago.
Improve this question
I don't know why this program says that 5 was not found in the array when clearly there is a 5 in the array. Also, rarely it won't output any printf message. Apart from this, it correctly identifies if the specified number is present.
Thank you for your time.
Number 5 present but wrong output message and no output message displayed-
#include <stdio.h>
#include <stdlib.h>
void print_array(int a[], int num_elements);
int findNumber(int array[], int array_size, int value);
void main()
{
srand(time(NULL)); //Produce random numbers
int randomNums[10]; //Array of 1000 ints
int index, value;
//Populate the array with random ints from 1 to 10
int i; //Merely for looping purposes
for (i = 0; i < 10; i++) {
randomNums[i] = rand() % 10 + 1; //Random range from 1 to 10
}
print_array(randomNums, 10);
findNumber(randomNums, 10, 5);
}
void print_array(int anarray[], int num_elements)
{
int i;
for (i = 0; i < num_elements; i++)
{
printf("Element %d: %d \n", i, anarray[i]);
}
printf("\n");
}
int findNumber(int array[], int array_size, int value)
{
int i;
for (i = 0; i < array_size; i++)
{
if(array[i] == value)
{
//Number found
printf("%d found at element %d \n", value, i);
break;
}
if(array[i] == array_size && array[i] != value)
{
//Number not found
printf("%d not found \n", value);
break;
}
}
}
In the loop in findNumber, the statement:
if(array[i] == array_size && array[i] != value)
causes the loop to print a message and stop if array[i] equals array_size. In this, array[i] is an element in the array. You likely intended to test i == array_size instead. However, that is also incorrect, because, inside the loop, i will never equal array_size. The controlling condition in the for statement is i < array_size, which means, if i is not less than array_size, the loop will not do another iteration.
You need to both correct the test to i == array_size and put it after the loop, not in the loop.
Additionally, remove the array[i] != value from that if statement. If i equals array_size, it will refer to an element outside the array.

Code to find max number from array [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 5 years ago.
Improve this question
I wrote the following code to find the max number from a array of numbers. Apparently there is an error in my code.It is a segmentation error. Please help me identify it.
#include <stdio.h>
void max(int n,int A[n]);
int main()
{
int n;
int A[n];
max(n,A[n]);
}
void max(int n,int A[n])
{
printf("Enter the number of elements you want in your array\n");
scanf("%d",&n);
int i;
printf("Enter the elements in your array\n");
for(i=0;i<n;i++)
{
scanf("%d",&A[i]);
}
int max=A[0];
for(i=1;i<n;i++)
{
if(A[i]>max)
{
max=A[i];
}
}
printf("%d",max);
}
int n;
int A[n];
You have to initialize n otherwise it contains garbage value. And now after this point you run into undefined behavior.
Correct code would be
#include <stdio.h>
#include <stdlib.h>
void printMax(int n,int A[]);
int main()
{
size_t n;
printf("Enter the number of elements you want in your array\n");
if( scanf("%zu",&n) != 1){
fprintf(stderr,"Error in input");
}
if( n <= 0){
fprintf(stderr, "%s\n", "Error in input : Enter number >= 0 .");
}
int a[n];
printf("Enter the elements in your array\n");
for(size_t i = 0; i < n; i++)
{
if( scanf("%d",&a[i]) != 1){
fprintf(stderr,"%s\n","Error in input");
exit(1);
}
}
printMax(n,a);
return 0;
}
void printMax(size_t n,int A[])
{
int max=A[0];
for(size_t i = 1; i < n; i++)
if(A[i] > max)
max = A[i];
printf("%d",max);
}
In main() you declare n but it has no value, so likely defaults to 0. You then declare and define an array A and give it size n, which as I say is likely zero.
Within max() you then read in a value and assign it to n but your array A is size zero.
So change main() to
/* Get the number of items to store in the array */
int n;
printf("Enter the number of elements you want in your array\n");
scanf("%d",&n);
/* Create the array of the given size */
int A[n];
/* Now find the max value in that array */
max(n,A);
And remove the setting of n from max().

How to read space-separated integers representing the array's elements and sum them up in C

How to read space-separated integers representing the array's elements and sum them up in C?
I used the below code but it reads all the elements in a new line:
#include <math.h>
#include <stdio.h>
int main() {
int i = 0, N, sum = 0, ar[i];
scanf("%d" , &N);
for (i = 0; i < N; i++) {
scanf("%d", &ar[i]);
}
for (i = 0; i < N; i++) {
sum = sum + ar[i];
}
printf("%d\n", sum);
return 0;
}
Your array ar is defined with a size of 0: the code invokes undefined behavior if the user enters a non zero number for the number of items.
Furthermore, you should check the return value of scanf(): if the user enters something not recognized as a number, your program will invoke undefined behavior instead of failing gracefully.
Here is a corrected version:
#include <stdio.h>
int main(void) {
int i, N, sum;
if (scanf("%d", &N) != 1 || N <= 0) {
fprintf(stderr, "invalid number\n");
return 1;
}
int ar[N];
for (i = 0; i < N; i++) {
if (scanf("%d", &ar[i]) != 1) {
fprintf(stderr, "invalid or missing number for entry %d\n", i);
return 1;
}
}
sum = 0;
for (i = 0; i < N; i++) {
sum += ar[i];
}
printf("%d\n", sum);
return 0;
}
Note that the program will still fail for a sufficiently large value of N as there is no standard way to check if you are allocating too much data with automatic storage. It will invoke undefined behavior (aka stack overflow).
You should allocate the array with malloc() to avoid this:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i, N, sum;
int *ar;
if (scanf("%d", &N) != 1 || N <= 0) {
fprintf(stderr, "invalid number\n");
return 1;
}
ar = malloc(sizeof(*ar) * N);
if (ar == NULL) {
fprintf(stderr, "cannot allocate array for %d items\n", N);
return 1;
}
for (i = 0; i < N; i++) {
if (scanf("%d", &ar[i]) != 1) {
fprintf(stderr, "invalid or missing number for entry %d\n", i);
return 1;
}
}
sum = 0;
for (i = 0; i < N; i++) {
sum += ar[i];
}
printf("%d\n", sum);
free(ar);
return 0;
}
Finally, there is still a possibility for undefined behavior if the sum of the numbers exceeds the range of type int. Very few programmers care to detect such errors, but it can be done this way:
#include <limits.h>
...
sum = 0;
for (i = 0; i < N; i++) {
if ((sum >= 0 && arr[i] > INT_MAX - sum)
|| (sum < 0 && arr[i] < INT_MIN - sum)) {
fprintf(stderr, "integer overflow for entry %d\n", i);
return 1;
}
sum += ar[i];
}
#include <math.h>
#include <stdio.h>
int main()
{
int i=0,N,sum=0;
scanf("%d" ,&N);
int ar[N];
for(i=0; i<N; i++)
scanf("%d",&ar[i]);
for(i=0; i<N; i++)
sum=sum+ar[i];
printf("%d\n", sum);
return 0;
}
This should be the code.
You have initially declared the array of size 0 (because i=0).
Even though you declared the array of size 0, when I ran it on my machine, it actually executed successfully with the correct output.
This is generally due to undefined behavior which means that we can only guess the output when the code is correct. If the code has undefined behavior, then it can do whatever it wants (and in the worst case the code will execute successfully giving the impression that it's actually correct).
Declaring a Variable Size Array (VLA) is optional in C11 standard. Thus, it depends on the implementation of the compiler whether it will support VLA or not. As pointed out by #DavidBowling in comments, if the compiler does support, then declaring a VLA of size 0 can invoke undefined behavior (which you should avoid in all cases). If it doesn't support, then this will simply give a compilation error and you'll have to declare the array size as some integer constant (example, int arr[100];).
#include <math.h>
#include <stdio.h>
int main()
{
int i=0,N,sum=0;
scanf("%d" ,&N);
int ar[N];
for(i=0; i<N; i++)
{
scanf("%d",&ar[i]);
}
for(i=0; i<N; i++)
{
sum=sum+ar[i];
}
printf("%d\n", sum);
return 0;
}
You should declare the array after accepting the value of N.
#include <math.h>
#include <stdio.h>
int main()
{
int i=0,N,sum=0;
scanf("%d" ,&N);
int ar[N];
for(i=0; i<N; i++)
{
scanf("%d",&ar[i]);
sum=sum+ar[i];
}
printf("%d\n", sum);
return 0;
}
As this is a very simple question I'll expand it a bit to include some good programming practices.
1. Analyze the problem
We have to complete two tasks here:
Read and store the numbers to array.
Sum the array elements.
Of course you can both read and calculate the same time, but we ❤ the SoC design principle. This will help you later with bigger programs.
2. Create the program structure
In this state we have to consider what function to use, as we already solved the data structure problem (we use array).
Of course, we always can put the whole procedure in main function but this would break the SoC principle.
The main principle here is:
I create a function for a separate procedure.
So we'll have to build two functions. Let's consider the following example:
ReadArrayData will be used to read the data from the standard input (your keyboard in other words) to array. But what will declare as parameters? We surely have to pass the array and the array size. The return type of this function will be void (we don't have to return something).
Keep in mind that if you pass array to function you can manipulate it as you please and keep these changes in your main program. This is because the arrays are passed always by reference to a function.
In the end this will be your function prototype:
void ReadArrayData(int arraySize, int array[]);
CalculateArraySum will be used to calculate the sum of the array elements. The function prototype will be the same as for ReadArrayData with the difference that the returning type will be int (we return the sum).
int CalculateArraySum(int arraySize, int array[]);
3. Write your program
#include <stdio.h>
void ReadArrayData(int arraySize, int array[]);
int CalculateArraySum(int arraySize, int array[]);
int main(void) {
int N;
printf("Give the array size: ");
scanf("%d", &N);
int array[N];
ReadArrayData(N, array);
int sumOfArrayElements = CalculateArraySum(N, array);
printf("The sum of array elements is %d.\n", sumOfArrayElements);
return 0;
}
void ReadArrayData(int arraySize, int array[]) {
printf("Give %d elements: ", arraySize);
for (int i = 0; i < arraySize; ++i) {
scanf("%d", &array[i]);
}
}
int CalculateArraySum(int arraySize, int array[]) {
int sum = 0;
for (int i = 0; i < arraySize; ++i) {
sum += array[i];
}
return sum;
}
I know this was a large scaled answer, but I saw you are new to computer programing. I just wanted to present you the main functionality to solve all kinds of problems. This was just a small introduction. In the end, you have to remember what steps we take to solve a problem. With time and as you solve many problems you will learn many many other things.

Radix Sorting Algorithm in c [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 have been tried to write radix sort in c.when i run my code with the static array it works well. but when i am trying to take random inputs from file it gives me an "Segmentation fault" at run time.help Please just help to modify this code
here is my code:
#include <stdio.h>
#include <stdlib.h>
#include<math.h>
#include<string.h>
int getMax(int arr[], int n)
{
int mx = arr[0];
int i;
for (i = 1; i < n; i++)
if (arr[i] > mx)
mx = arr[i];
return mx;
}
void countSort(int arr[], int n, int exp,int base)
{
int output[n];
int i;
int count[base];
memset(count, 0, sizeof count);
for (i = 0; i < n; i++)
count[ (arr[i]/exp)%base]++;
for (i = 1; i < base; i++)
count[i] += count[i - 1];
for (i = n - 1; i >= 0; i--)
{
output[count[ (arr[i]/exp)%base ] - 1] = arr[i];
count[ (arr[i]/exp)%base ]--;
}
for (i = 0; i < n; i++)
arr[i] = output[i];
}
void radixsort(int arr[], int n,int base)
{
int m = getMax(arr, n);
int exp;
for (exp = 1; m/exp > 0; exp *= 10)
countSort(arr, n, exp , base);
}
void print(int arr[], int n)
{
int i;
for (i = 0; i < n; i++)
printf("%d ",arr[i]);
}
int main(int argc,int argv[])
{
int base=atoi(argv[1]);
int num,i;
FILE *fp1=fopen("myFile1.txt","r");
int arr[50];
while(fscanf(fp1,"%d",&num)==1)
{
arr[i]=num;
i++;
}
int n = sizeof(arr)/sizeof(arr[0]);
radixsort(arr, n ,base);
print(arr, n);
fclose(fp1);
return 0;
}
You are assuming that the compiler has set the initial value of i to 0. However, this is not guaranteed. While many compilers reset variables to 0, many others just leave the contents of memory set at whatever it happened to be at compile time or at load time. You need to initialize the value before using it.
Additionally, you do not test to ensure that you are not overrunning the arr buffer. For example consider what would happen to arr[] if you happen to open a file that has 51 entries. You would attempt to add an entry to arr[50] which overruns the buffer.
You need to initialize i to 0 and make sure to break out if i becomes too great.
The calculation of n is always 50 because arr is 50 ints. You should use i as the count of how many entries have been read in.
int main(int argc,int argv[])
{
int base=atoi(argv[1]);
// int num,i; // This is the line that causes the error
int num;
int i = 0; // This needs to be initialized before use.
FILE *fp1=fopen("myFile1.txt","r");
int arr[50];
// You need to ensure that i does not overrrun the buffer.
while(fscanf(fp1,"%d",&num)==1 && (i < 49))
{
arr[i]=num;
i++;
}
// Since i was defined before the while, it should have the correct count
// This calculation of n is wrong if fewer than a full buffer is read
int n = sizeof(arr)/sizeof(arr[0]);
radixsort(arr, n, base);
print(arr, n);
fclose(fp1);
return 0;
}

Resources