Hello everyone,
I wrote an code which is remove duplicates from sorted array. I know that there are lots of people have a good know how about clean code in this platform. I want to write code especially clean code. So I wanna hear some suggestion this about. If yo critise my code I am glad.
#include <stdio.h>
int main()
{
int arr[]={1,2,2,2,3,4,4,4,5,6,7,7,7,8,8};
int arr_size = *(&arr + 1) - arr;
printf("length of array %d\n",arr_size);
int result[arr_size];
int last_item= result[0];
for (int i=0; i<arr_size;i++)
{
if(arr[i]!=last_item)
{
last_item= arr[i];
result[i]= last_item;
printf("result : %d\n", result[i]);
}
}
return 1;
}
For starters it is unclear why main returns 1 instead of 0.
Secondly you are not removing duplicate elements from an array. You are trying to copy unique elements from one array into another array.
Also it is unclear why the result array has arr_size elements as the source array.
This declaration
int last_item= result[0];
is invalid because the result array is not initialized. So it contains indeterminate values.
Also in the for loop you are using the invalid index i for the result array. So again some elements of the result array will have indeterminate values.
result[i]= last_item;
And within the for loop there should not be any call of printf. If you want to output the result array (it is already another task) then you need to use a separate loop or function.
And at last you should write a separate function that performs the task of copying unique or removing duplicate elements..
I would write a function that indeed removes duplicates from an array the following way as shown in the demonstration program below.
#include <stdio.h>
size_t remove_duplicates( int a[], size_t n )
{
size_t m = 0;
for (size_t i = 0; i < n; i++)
{
if ( i == 0 || a[i] != a[m-1])
{
if (i != m)
{
a[m] = a[i];
}
++m;
}
}
return m;
}
int main( void )
{
int arr[] = { 1,2,2,2,3,4,4,4,5,6,7,7,7,8,8 };
const size_t N = sizeof( arr ) / sizeof( *arr );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", arr[i] );
}
putchar( '\n' );
size_t m = remove_duplicates( arr, N );
for (size_t i = 0; i < m; i++)
{
printf( "%d ", arr[i] );
}
putchar( '\n' );
}
The program output is
1 2 2 2 3 4 4 4 5 6 7 7 7 8 8
1 2 3 4 5 6 7 8
Related
For some reason, the first output my program is giving, is garbage value, while the second output is correct.
This is a problem from HackerRank.
I know this question has already been asked by someone else. I just want to know what the problem is in my code.
#include <stdio.h>
int main()
{
int index,query;
int count1 = 0;
scanf("%d%d",&index,&query);
for(int i=0;i<index;i++)
{
int b;
scanf("%d",&b);
int A[index][b];
for(int j=0;j<b;j++)
{
scanf("%d",&A[i][j]);
}
count1++;
if(count1<index)
{
continue;
}
int count2=0;
while(count2<query)
{
int d,e;
scanf("%d%d",&d,&e);
printf("%d\n",A[d][e]);
count2++;
}
}
return 0;
}
If the input is:
2 2
3 1 5 4
5 1 2 8 9 3
0 1
1 3
Then the output should be:
5
9
But instead, my output is:
garbage
9
Disclaimer
I didn't even click the link, so I do not know if the solution is correct, but assuming that you got the logic right..
The problem
is that you populate in stages a local to the body of the for loop 2D array, which at the end of your processing, you expect to have it accessible (I mean the complete matrix, populated from every single iteration of the for loop).
Instead, you get only the last's iteration declared array, that's why you get only the A[1][3] element right, and not the A[0][1], since the 2nd row is populated in the last (2nd iteration), while the 1st row is populated in the first iteration (of the firstly declared A), which goes out of scope as soon as the first iteration terminates.
The fix
So, what you need to fix this is to dynamically allocate memory for your matrix, and every time a new dimension for the columns is inputed, resize it with realloc().
I believe that the explanation I have in 2D dynamic array (C) will help you, since what you want is the number of rows fixed, and the number of columns adjustable on every iteration.
Below is an illustration based on the link I shared above, which visualizes what exactly is your matrix (a 1D array of pointers), and shows how the code below manipulates it:
Full code example:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int index,query;
int count1 = 0;
scanf("%d%d",&index,&query);
// An array of `index` (e.g. 2) pointers to integers
int *A[index];
// Initialize all the pointers to NULL
for(int k = 0; k < index; ++k)
A[k] = NULL;
for(int i=0;i<index;i++)
{
int b;
scanf("%d",&b);
// Replaced your 'int A[index][b];' with the following:
// Every time a new number of columns (that's 'b') is read,
// we need to adjust the numbers of columns our matrix ('A') has.
// That means, that for every pointer (row), we need to re-allocate
// the number of columns it points to, which is basically a 1D array, of dimension 'b'
for(int k = 0; k < index; ++k)
A[k] = realloc(A[k], b * sizeof(int) );
for(int j=0;j<b;j++)
{
scanf("%d",&A[i][j]);
}
count1 ++;
if(count1<index)
{
continue;
}
int count2=0;
while(count2<query)
{
int d,e;
scanf("%d%d",&d,&e);
printf("%d\n",A[d][e]);
count2++;
}
}
// Free the dynamically allocated memory
for(int k = 0; k < index; ++k)
free(A[k]);
return 0;
}
Output (for the input provided):
5
9
Pro-tip: The typical methodology of calling realloc() is to use a specific pointer for the reallocation, test that pointer and, if everything worked out ok, change the old pointer, as explained in Does realloc overwrite old contents?, which I didn't do in that post for the sake of being "laconic".
The C VLA is not suitable here. It seems you need to allocate memory dynamically. The only VLA that can be used is an array of pointers to other arrays. All other arrays should be allocated dynamically.
Something like the following.
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
size_t number_of_arrays;
size_t number_of_queries;
scanf( "%zu%zu", &number_of_arrays, &number_of_queries );
int **a = malloc( number_of_arrays * sizeof( int * ) );
for ( size_t i = 0; i < number_of_arrays; i++ )
{
size_t size;
scanf( "%zu", &size );
a[i] = malloc( size * sizeof( int ) );
for ( size_t j = 0; j < size; j++ ) scanf( "%d", &a[i][j] );
}
for ( size_t i = 0; i < number_of_queries; i++ )
{
size_t array_index;
size_t element_index;
scanf( "%zu%zu", &array_index, &element_index );
printf( "%d\n", a[array_index][element_index] );
}
for ( size_t i = 0; i < number_of_arrays; i++ ) free( a[i] );
free( a );
}
If to input
2 2
3 1 5 4
5 1 2 8 9 3
0 1
1 3
then the program output will be
5
9
As for your code then it is invalid. For example the variable b is not initialized so the declaration of the array has undefined behavior.
int b;
scanf("%d",&b);
int A[index][b];
^^^
Hint : Variable sized arrays need to be dynamically allocated, here's how to it in C
int rows;
scanf("%d",&rows);
//2D array
int**A = malloc(sizeof(int*)*rows); //allocate number of rows
//for each row allocate number of colums
for(int i = 0; i < rows; i++)
{
int cols;
scanf("%d",&cols);
A[i] = malloc(sizeof(int)*cols);
}
I've made a little program where i input a dimension of an array and then i fill it with values, then i tried to add a function where the first value of the array gets swapped with the biggest one, the problem i have is that all the other values (if we are considering that they are bigger than the first one) get swapped aswell in the process of the cycle, how do i avoid that?
void maxVectorSwap(int *v, int dim){
int i;
int app;
int max=0;
for(i=0;i<dim;i++){
max=v[0];
if(v[i]>max){
app=v[0];
v[0]=v[i];
v[i]=app;
}
}
printf("----------\n");
for(i=0;i<dim;i++){
printf("v[%d]=%d\n",i,v[i]);
}
printf("----------\n");
}
Let's say i input the dimension of the array to be 5 and the values to be:
3 5 1 7 2
The result i get with this function is:
7 3 1 5 2
Which gives away that there more swaps, what i want instead is just to see 7 and 3 swapped so it would look like this:
7 5 1 3 2
To Solve this problem, lets look back at what our approach should be.
Problem: Swapping the maximum and the first indexed number.
Algorithm: To find where the maximum number is located and then swap the values using their indices.
Thus try to find the index first and then try swapping.
Updated Code:
void maxVectorSwap(int *v, int dim)
{
int i;
int app;
//Lets assume the first element is the largerst number i.e index=0
int indexOfMax=0;
for(i=0;i<dim;i++)
{
if(v[i]>v[indexOfMax])
{
indexOfMax=i;
// store the updated maximum index in m
}
}
// now indexOfMax stores the location of the maximum number
//Thus swapping now
int temp=v[0];
v[0]=v[indexOfMax];
v[indexOfMax]=temp;
printf("----------\n");
for(i=0;i<dim;i++){
printf("v[%d]=%d\n",i,v[i]);
}
printf("----------\n");
}
Here you are.
#include <stdio.h>
void maxVectorSwap( int *v, size_t dim )
{
size_t max_i = 0;
for ( size_t i = 1; i < dim; i++ )
{
if ( v[max_i] < v[i] ) max_i = i;
}
if ( max_i != 0 )
{
int tmp = v[0];
v[0] = v[max_i];
v[max_i] = tmp;
}
}
int main(void)
{
int a[] = { 3, 5, 1, 7, 2 };
size_t n = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < n; i++ ) printf( "%d ", a[i] );
putchar( '\n' );
maxVectorSwap( a, n );
for ( size_t i = 0; i < n; i++ ) printf( "%d ", a[i] );
putchar( '\n' );
return 0;
}
The program output is
3 5 1 7 2
7 5 1 3 2
I want to make a lines of stars, each line containing more then the previous one. The point of my problem is that I don´t know how to multiply strings in C.
#include<stdio.h>
#include<conio.h>
main()
{
int max = 10
for (int i = 1; i <= max; ++i){
printf("*"*(2 * i - 1);
}
}
You can just repeat printing the desired number of strings.
#include<stdio.h>
#include<conio.h>
main()
{
int max = 10; // a semicolon is added to make it compile
for (int i = 1; i <= max; ++i){
for (int j = 0; j < (2 * i - 1); j++){ // repeat (2 * i - 1) times
printf("*");
}
printf("\n"); // separate lines
}
}
I respect the original code, so some points that are not good (meaningless including of non-standard conio.h and non-standard definition of main() (instead of int main(void))) remains.
The language semantics do not support what you are trying to do. In C a string is not a first class type in any case - it is simply an array of char, so all string handling is performed through functions; you cannot perform direct operations on them; and even if you could I doubt multiply would be one of them - it has a very limited use case easily implemented using simpler operations.
In this case you do not in fact need repeated string replication (or multiply as you refer to it) since you are outputting the string directly so have no need to store the string and the associated memory allocation issues that entails. Rather you simply need repeated string output.
#include <stdio.h>
void printRepeatString( const char* str, int n )
{
for( int i = 0; i < n; n++ )
{
printf( "%s", str ) ;
}
}
int main( void )
{
const int max = 10
for (int i = 1; i <= max; i++ )
{
printRepeatString( "*", (2 * i) - 1 ) ;
putchar( '\n' ) ;
}
return 0 ;
}
An alternative to "multiplying" a string of '*' is to create the longest one and then print a truncated portion of it.
Use "%.*s", n, s to print a character array s up to n characters.
#include<stdio.h>
#define MAX 10
int main(void) {
char s[2 * MAX] = {0};
memset(s, '*', 2 * MAX - 1);
for (int i = 1; i <= MAX; ++i) {
printf("%.*s\n", 2 * i - 1, s);
}
}
Output
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
I have an array of data, arr, and an array of indexes, index. My goal is to use a for loop to create new arrays of data partitioned at each of the indexes and to further find the minimum in each partitioned array. I am using malloc to create a dynamic array which I then free at the end of each loop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int j;
int arr[] = {1,3,4,6,7,8,12,87,89,12,34,43,54,67,81,2,0,10,23,45,81,23,89,23,56,81,28,79};
int index[] = {1,5,9,13,19,24};
int h = 27;
int k;
int c;
for(j = 0;j < h - 1;++j)
{
int *temp_arr = malloc(10*sizeof(int));
for(k = index[j];k<(index[j+1]);++k )
{
temp_arr[k] = arr[k];
}
int local_min ;
local_min = temp_arr[0];
for ( c = 1 ; c < sizeof(temp_arr) / sizeof(temp_arr[0]) ; c++ )
{ printf("Temp array %d ", temp_arr[c]);
if ( temp_arr[c] < local_min)
{
local_min = temp_arr[c];
printf("Local min in loop %d ", local_min );
}
}
free(temp_arr);
printf("\n");
}
return 0;
}
Unfortunately, the program is crashing without giving me any error messages. I think that I may have done something fundamentally wrong using malloc. Any suggestions on how to correctly do this would be greatly appreciated.
for(j = 0;j < h - 1;++j) // Where h = 27
It means j can be max 25
for(k = index[j];k<(index[j+1]);++k ) // If j = 25
You are touching index[26], while index has 6 elements.
for ( c = 1 ; c < sizeof(temp_arr) / sizeof(temp_arr[0]) ; c++ ) // Where int *temp_arr
temp_arr is pointer and sizeof(pointer) is always 8 on 64bit or 4 on 32bit system.
for(k = index[j];k<(index[j+1]);++k )
{
temp_arr[k] = arr[k]; // Where int index[] = {1,5,9,13,19,24};
}
If k is 13 or 19 or 24 you are ouside of bounds.
You should take a look at valgrind, and debug your code, step by step, expression by expression.
It appears that you forgot to inspect the output from Valgrind, which shows exactly where you use uninitialized values and where you run off the end of temp_arr.
Note also that temp_arr is a pointer type, and sizeof temp_arr is the size of that pointer, not the size of the array it points to.
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);
}