practicing the basic - problem with program - arrays

Im new in this site hope its ok to post question like that.
Im trying to learn c language and I got a problem to solve that im stuck with.
-- I need to get 10 number and than print it but with no duplicate number:
like if i get 1 2 3 4 5 6 1 2 3 - I need to print only 1 2 3 4 5 6. --
this is what I did:
#include <stdio.h>
int main()
{
int arr1[10] = {0};
int arr2[10] = {0};
int i, j, c;
printf("Please enter 10 numbers:\n");
for (i=0; i<10; ++i) {
scanf(" %d", &arr1[i]);
}
i = j = c = 0;
for (i=0; i<10; ++i) {
while (arr1[i] != arr2[j], j<10) {
++j;
}
if (j==10) {
arr2[c] = arr1[i];
++c;
}
j=0;
}
for (i=0; i<10; ++i) {
printf("%d ", arr2[i]);
}
return 0;
}
input - 8 1 2 1 2 3 4 5 6 7
output - 8 1 2 1 2 3 4 5 6 7 (I should not print the dupicate numbers)

In this while loop
while (arr1[i] != arr2[j], j<10)
there is used an expression with the comma operator. The value of the first operand arr1[i] != arr2[j] of the comma operator is discarded and the result of the expression is the value of the second operand of the comma operator j<10.
So after the loop the variable j will be always equal to 10. In fact you have the following loop
while ( j < 10 ) {
++j;
}
because the first operand of the comma operator has no side effect.
You have to write
while ( j < c && arr1[i] != arr2[j] )
++j;
}
if (j==c) {
arr2[c] = arr1[i];
++c;
}
That is there is needed to check only c elements of the second array.
Also this for loop
for (i=0; i<10; ++i) {
printf("%d ", arr2[i]);
}
should be rewritten like
for (i=0; i < c; ++i) {
printf("%d ", arr2[i]);
}
Actually to output unique elements of an array there is no need to create a second array. The program can look the following way
#include <stdio.h>
int main( void )
{
enum { N = 10 };
int arr1[N] = {0};
printf( "Please enter %d numbers:\n", N );
for ( size_t i = 0; i < N; ++i )
{
scanf( "%d", &arr1[i] );
}
for ( size_t i = 0; i < N; ++i )
{
size_t j = 0;
while ( j != i && arr1[i] != arr1[j] ) ++j;
if ( j == i ) printf( "%d ", arr1[i] );
}
putchar( '\n' );
}
Pay attention to that you should use named constants instead of magic numbers like 10 and you should declare variables in minimum scopes where they are used.

Related

Pyramid patterns using C

I need to do the following pattern using do-while, while or for.
I tried the following code but it prints the pattern only 1-5
I also tried to alter the n being 10 but then the spacing goes nuts.
#include <stdio.h>
int main(void)
{
int n = 5, i, j, num = 1, gap;
gap = n - 1;
for ( j = 1 ; j <= n ; j++ )
{
num = j;
for ( i = 1 ; i <= gap ; i++ )
printf(" ");
gap --;
for ( i = 1 ; i <= j ; i++ )
{
printf("%d", num);
num++;
}
num--;
num--;
for ( i = 1 ; i < j ; i++)
{
printf("%d", num);
num--;
}
printf("\n");
}
return 0;
}
Try replacing both occurences of:
printf("%d", num);
with
printf("%d", num % 10);
Now only the last digit will be shown.
After the change, for n set to 10 the program produces:
1
232
34543
4567654
567898765
67890109876
7890123210987
890123454321098
90123456765432109
0123456789876543210

How to skip certain numbers in a for-loop?

I started practicing a for loop in C and so far I understand the main principle behind it. But I can't figure out how to get the following output:
1 2 3 5 6 7 9 10 11 ...
I managed to print 1 to 12 with the following for loop but how can I skip 4 and 8 or how to skip any number in general?
for(int i = 1; i < 12; i++)
{
printf("%d", i);
}
Either you can use an if statement inside the body of the loop like
for ( int i = 1; i < 12; i++ )
{
if ( i % 4 != 0 )
{
printf( "%d ", i );
}
}
Or you can avoid the numbers that divisible by 4 in the third expression of the for loop like
for ( int i = 1; i < 12; i += ( i + 1 ) % 4 == 0 ? 2 : 1 )
{
printf( "%d ", i );
}
If you need to output the space character instead of a number divisible by 4 you can use an if-else statement inside the body of the loop. For example
for ( int i = 1; i < 12; i++ )
{
if ( i % 4 != 0 )
{
printf( "%d ", i );
}
else
{
putchar( ' ' );
}
}
the simplest solution would be to check with an if statement for any values that you don't want.
if you have a rule like not printing all numbers that are divisible by 4 you can make your if statement like this
if(i % 4 == 0)
{
//print
}
there is no way to do it specifically with the for loop expression.
if you want to do specific numbers you just add more conditions to the if statement:
for(int i = 1; i < 12; i++)
{
if(i != 11 && i != 5 && i%3 != 0)
{
printf("%d", i);
}
}
The best way to do this, especially for a large amount of irregular exceptions, is the following way.
#include <stdio.h>
int main(int argc, char *argv[])
{
int exceptionsv[] = {4, 8};
int exceptionsc = sizeof(exceptionsv)/sizeof(exceptionsv[0]);
for(int i = 1; i < 12; i++)
{
for(int j = 0; j < exceptionsc; j++)
{
if(exceptionsv[j] == i) i++;
}
printf("%d ", i);
}
}
for (char i=0; i<12; i++) { if (i%4 != 0) printf("%d", i); }
Or you can isolate the pattern and duplicate it using a nested loop :
char patternCount = 3;
for (char i=0; i<patternCount; i++) {
for (char j=1; j<4; j++) printf("%d", i*4 + j);
}

I couldn't handle to write a histogram

My aim is to generate a histogram for repeated numbers. The code works well until the frequency is bigger than 2.
I think I know what is wrong with the code (line 9) but I cannot find an algorithm to solve it. The problem that I have is when it writes the histogram, it separates and then gathers it again.
My Input:
5
5 6 6 6 7
Output:
6:2 6:2 6:3
but the output I need is
6:3
I kind of see the problem but I couldn't solve it.
#include <stdio.h>
int main(){
int array[25];
int i, j, num, count = 1;
scanf("%d", &num);
for (i = 0; i < num; i++) {
scanf("%d", &array[i]);
for (j = 0; j < i ; j++) {
if (array [i] == array[j]) {
count++;
printf("%d:%d ", array[i], count);
}
}
array [i] = array[j];
count = 1;
}
return 0;
}
You are trying to count occurrences before all units have been accepted, which is not possible unless you maintain a separate counter for each value, which in turn is not practical if there is no restriction on the input value range or the range is large.
You need to have obtained all values before you can report any counts. Then for each value in the array, test if the value has occurred earlier, and if not, iterate the whole array to count occurrences:
#include <stdio.h>
#include <stdbool.h>
int main()
{
// Get number of values
int num = 0 ;
scanf("%d", &num);
// Get all values
int array[25];
for( int i = 0; i < num; i++)
{
scanf("%d", &array[i]);
}
// For each value in array...
for( int i = 0; i < num ; i++)
{
// Check value not already counted
bool counted = false ;
for( int j = 0; !counted && j < i; j++ )
{
counted = array[j] == array[i] ;
}
// If current value has not previously been counted...
if( !counted )
{
// Count occurnaces
int count = 0 ;
for( int j = 0; j < num; j++ )
{
if( array[j] == array[i] )
{
count++ ;
}
}
// Report
printf("%d:%d ", array[i], count);
}
}
return 0;
}
For your example input, the result is:
5
5 6 6 6 7
5:1 6:3 7:1
It is possible to merge the two inner loops performing the counted and count evaluation:
// Count occurrences of current value,
bool counted = false ;
int count = 0 ;
for( int j = 0; !counted && j < num; j++ )
{
if( array[j] == array[i] )
{
count++;
// Discard count if value occurs earlier - already counted
counted = j < i ;
}
}
// If current value has not previously been counted...
if( !counted )
{
// Report
printf("%d:%d ", array[i], count);
}
}

Printing Integer array in reverse

This is fairly simple problem to print the integer array in reverse order. Although whenever i try printing, it ends up displaying garbage value. Below is my program.
#include <stdio.h>
#include <conio.h>
int main()
{
int temp = { '\0' };
int num[9];
int i;
int j = 8;
printf("Enter 8 numbers\n");
for (i = 0; i < 8; i++)
{
scanf_s("%d", &num[i], 1);
}
for (i = 0; i <= j; i++, j--)
{
temp = num[i];
num[i] = num[j];
num[j] = temp;
}
printf("\nThe numbers in reverse are\n");
for (i = 0; i <=8; i++)
{
printf("%d\n", num[i]);
}
_getch();
return 0;
}
Let just say i input numbers from 1 to 8, it does print the number in reverse but the first value it prints is a garbage value. I know i can use and If statement to counter the situation but is there a way to counter this problem without using if?
You've made two mistakes here:
With 8 numbers, the index of the highest item is 7, not 8. Set j to 7 on initialization to fix this.
When you iterate 8 numbers from index zero, use operator < or !=, not <= to avoid an off-by-one error. Your first loop does it right, but the last loop is broken.
In addition, you may want to reduce the size of the array to 8, because the ninth element is unused.
If you want to print the integers in your array in reverse, simply start at the last index, then work up to the top.
The third loop should look more like this:
int j = 7; // an array of size 8 starts at the 0th and ends at the 7th index.
while(j >= 0)
{
printf("%d", num[j]);
j--;
}
There are several logical inconsistences in your program,
You defined the array as having 9 elements
int num[9];
but enter only 8 elements
for (i = 0; i < 8; i++)
{
scanf_s("%d", &num[i], 1);
}
Thus the last element of the array with insex 8 is not initialized. Nevertheless in the loop that swaps elements of the array you access this uninitialized element
int j = 8;
//...
for (i = 0; i <= j; i++, j--)
{
temp = num[i];
num[i] = num[j];
num[j] = temp;
}
There is also no need to use function scanf_s instead of scanf
Take into account that to output an array in the reverse order you need not to swap its elements.
The program that outputs an array in the reverse order without swapping its elements can look the following way
#include <stdio.h>
#include <conio.h>
#define N 9
int main( void )
{
int num[N];
int i;
printf( "Enter %d numbers\n", N );
i = 0;
while ( i < N && scanf( "%d", &num[i] ) == 1 ) i++;
printf( "\nThe numbers in reverse are\n" );
while ( i-- ) printf( "%d ", num[i] );
printf( "\n" );
_getch();
return 0;
}
If to enter a sequence of numbers
1 2 3 4 5 6 7 8 9
then the output will look like
9 8 7 6 5 4 3 2 1
If you want to swap elements of the array then the program can look like
#include <stdio.h>
#include <conio.h>
#define N 9
int main( void )
{
int num[N];
int n;
int i;
printf( "Enter %d numbers\n", N );
n = 0;
while ( n < N && scanf( "%d", &num[n] ) == 1 ) n++;
for ( i = 0; i < n / 2; i++ )
{
int tmp = num[i];
num[i] = num[n - i - 1];
num[n - i - 1] = tmp;
}
printf( "\nThe numbers in reverse are\n" );
for ( i = 0; i < n; i++ ) printf( "%d ", num[i] );
printf( "\n" );
_getch();
return 0;
}
If the input is the same as above then output will be
9 8 7 6 5 4 3 2 1
You can also keep the for loop the same and change the indexing
#define ARRAY_SIZE 8
// print in reverse order
for (i = 0; i < ARRAY_SIZE; i++)
{
printf("%d\n", num[ARRAY_SIZE - i - 1]);
}
I used a #define to make it easier to change the program when you need a different array size: just change at one place rather than the 5 you currently need.

What is wrong with this insertion sort in C?

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include <stddef.h>
void insertionSort(int ar_size, int* ar) {
int i, j;
int temp = 0;
for (i = 1; i < ar_size; i++) {
j = i;
while (j > 0 && ar[i - 1] > ar[i]) {
temp = ar[i - 1];
ar[i - 1] = ar[i];
ar[i] = temp;
j--;
}
}
for (j = 0; j < ar_size; j++) {
printf("%d", ar[j]);
printf(" ");
}
}
int main(void) {
int _ar_size;
scanf("%d", &_ar_size);
int _ar[_ar_size], _ar_i;
for (_ar_i = 0; _ar_i < _ar_size; _ar_i++) {
scanf("%d", &_ar[_ar_i]);
}
insertionSort(_ar_size, _ar);
return 0;
}
I have been trying to look for the error. I cannot see any. What is wrong with this code?
For input as 6 and 4 1 3 5 6 2 , it gives output as 1 3 4 5 2 6. There is one less iteration of the loop but I cannot see why? Please help. Thanks.
You are using index i instead of index j in the internal loop of the function.
while(j>0 && ar[i-1]>ar[i])
{
temp = ar[i-1];
ar[i-1] = ar[i];
ar[i] = temp;
j--;
}
Here everywhere index j has to be used.
Also it is a bad idea that the function also outputs the sorted array. It should do only sorting.
The other bad idea is to use identifiers that start with undescores.
It is better when the first parameter is an array and the second parameter is the size of the array.
The code could look the following way
#include <stdio.h>
void InsertionSort( int *a, int n )
{
int i;
for ( i = 1; i < n; i++ )
{
int j = i;
while ( j > 0 && a[j-1] > a[j] )
{
int tmp = a[j-1];
a[j-1] = a[j];
a[j] = tmp;
--j;
}
}
}
int main(void)
{
int size;
scanf( "%d", &size );
int a[size];
int i;
for ( i = 0; i < size; i++ ) scanf( "%d", &a[i] );
for ( i = 0; i < size; i++ )
{
printf( "%d ", a[i] );
}
puts( "" );
InsertionSort( a, size );
for ( i = 0; i < size; i++ )
{
printf( "%d ", a[i] );
}
puts( "" );
return 0;
}
If the input is
10
2 7 5 4 9 1 4 8 3 5
then output is
2 7 5 4 9 1 4 8 3 5
1 2 3 4 4 5 5 7 8 9
You seem to be using the wrong iterator when pushing the value to the front.
while(j>0 && ar[j-1]>ar[j]) {
temp = ar[j-1];
ar[j-1] = ar[j];
ar[j] = temp;
j--;
}
Try performing a dry run on a piece of paper, it's easy to spot the problem.
for (i = 1; i < ar_size; i++) {
j = i;
while (j > 0 && ar[i-1] > ar[i]) { // problem begins here
temp = ar[i-1];
ar[i-1] = ar[i];
ar[i] = temp;
j--;
}
}
i does not change in the inner loop.
At some point your program swaps 6 with 2 and your sample input list becomes 1 3 4 5 2 6, a[i-1] is 2 and a[i] is 6 and because of ar[i-1] > ar[i] condition the program's flow does not go into the inner loop.
Try this fix:
for (i = 1; i < ar_size; i++) {
j = i;
while (j > 0 && ar[j-1] > ar[j]) {
temp = ar[j-1];
ar[j-1] = ar[j];
ar[j] = temp;
j--;
}
}
The problem with your insertion-sort is you have your j indexes replaced with i indexes in the following code:
while(j>0 && ar[j-1]>ar[j])
{
temp = ar[j];
ar[j] = ar[j-1];
ar[j-1] = temp;
j--;
}
Just a note, when requesting input, it is good practice to print a brief statement describing the input expected. (yes, quick a dirty testing is an exception) It makes if much easier to avoid mistakes with something like:
printf ("enter array size: ");
scanf ("%d", &_ar_size);
int _ar[_ar_size], _ar_i;
for (_ar_i = 0; _ar_i < _ar_size; _ar_i++) {
printf ("enter array element[%d] : ", _ar_i);
scanf ("%d", &_ar[_ar_i]);
}

Resources