Sorting an array meanwhile entering values - c

i need to sort the array while entering values that means that while the user enters numbers the array needs to sort itself: what i did so far is this:
void MoveRight(int *a,int n, int startIndex)
{
int j,temp;
j=n-1;
for(int i=startIndex;i<n;i++)
{
temp = a[j];
a[j]=a[i];
a[i]=temp;
}
}
void InsertionSort(int *a,int n)
{
int i,number,j;
printf("Enter %d numbers for the array\n",n);
for(i=0;i<n;i++)
{
scanf("%d",&number);
for(j=0;j<=i;j++)
{
if(number<a[j])
{
MoveRight(a,n,j);
a[j]=number;
break;
}
}
}
}
After entering: 1,3,2,4,5
The array i got was : -858993460,-858993460,-858993460,-858993460,-858993460

To apply the selection sort you should at first to enter all elements in the array.
These loops
for(i=0;i<n;i++)
{
scanf("%d",&number);
for(j=0;j<=i;j++)
{
if(number<a[j])
{
MoveRight(a,n,j);
a[j]=number;
break;
}
}
}
already result in undefined behavior because when i and j are equal to 0 then a[j] has indeterminate value. And moreover if the condition number<a[j] is not evaluated to true then nothing will be added to the array.
Function MoveRight does not make sense because in the loop variable j is not changed.
j=n-1;
for(int i=startIndex;i<n;i++)
{
temp = a[j];
a[j]=a[i];
a[i]=temp;
}
Here is a demonstrative program that shows how the task can be done.
#include <stdio.h>
void MoveRight( int *a, int n, int i )
{
for ( ; n != i; --n ) a[n] = a[n-1];
}
#define N 10
int main(void)
{
int a[N];
printf( "Enter %d numbers for the array: ", N );
for ( int i = 0; i < N; i++ )
{
int value;
scanf( "%d", &value );
int j = 0;
while ( j < i && !( value < a[j] ) ) j++;
MoveRight( a, i, j );
a[j] = value;
}
for ( int i = 0; i < N; i++ ) printf( "%d ", a[i] );
printf( "\n" );
return 0;
}
The program output might look the following way
Enter 10 numbers for the array: 5 2 3 9 8 1 6 7 4 0
0 1 2 3 4 5 6 7 8 9
Take into account that for large arrays it is much better to use the binary search instead of the sequential search to find the position where to insert the next value.

Related

Is book's code to find the second largest integer in an array wrong?

This program is supposed to find the second largest integer. I have taken it from a book.
When I enter to find the second largest number among 4 5 1 2 3, it doesn't pick 4 as the second largest. I think on line 16 the code should be arr[0] and not arr[1]. Am I correct or am I missing something?
#include <stdio.h>
int main()
{
int i, n, arr[20], large, second_large;
printf("\n Enter the number of elements in the array : ");
scanf("%d", &n);
printf("\n Enter the elements");
for(i=0;i<n;i++)
scanf("%d",&arr[i]);
large = arr[0];
for(i=1;i<n;i++)
{
if(arr[i]>large)
large = arr[i];
}
second_large = arr[1]; // line 16
for(i=0;i<n;i++)
{
if(arr[i] != large)
{
if(arr[i]>second_large)
second_large = arr[i];
}
}
printf("\n The numbers you entered are : ");
for(i=0;i<n;i++)
printf("\t %d", arr[i]);
printf("\n The largest of these numbers is : %d",large);
printf("\n The second largest of these numbers is : %d",second_large);
return 0;
}
Your code reads like "C", this is C++20 code for the same problem :
(for manual input, use std::cin and values.push_back)
#include <vector>
#include <iostream>
#include <algorithm>
int main()
{
constexpr std::size_t second_largest_index = 1ul;
std::vector<int> values{ 0,2,8,7,5,4,1,3,9,6 };
std::ranges::nth_element(values, values.begin() + 1, std::ranges::greater());
std::cout << "the second largest value = " << values[second_largest_index];
return 0;
}
This statement
second_large = arr[1];
at once selects the largest number in the array { 4, 5, 1, 2, 3 }.
So the expression of the nested if statement within this for loop
for(i=0;i<n;i++)
{
if(arr[i] != large)
{
if(arr[i]>second_large)
second_large = arr[i];
}
}
never evaluates to true. That is the second largest number will always equal to the first largest number.
Pay attention to that in general an array can contain all elements equal each other.
I can suggest the following approach.
large = 0;
second_large = n;
i = 1;
while ( i < n && arr[i] == arr[large] ) ++i;
if ( i < n )
{
if ( arr[large] < arr[i] )
{
large = i;
second_large = 0;
}
else
{
second_large = i;
}
while ( ++i < n )
{
if ( arr[large] < arr[i] )
{
second_large = large;
large = i;
}
else if ( arr[second_large] < arr[i] )
{
second_large = i;
}
}
}
if ( second_large == n )
{
puts( "\nAll elements are equal each other." );
}
else
{
printf("\nThe largest of these numbers is : %d", arr[large] );
printf("\nThe second largest of these numbers is : %d", arr[second_large] );
}
Here is a demonstration C program (It is a C program because the program provided by you in fact has nothing from C++)
#include <stdio.h>
int main( void )
{
int arr[] = { 4, 5, 1, 2, 3 };
const size_t n = sizeof( arr ) / sizeof( *arr );
size_t large = 0;
size_t second_large = n;
size_t i = 1;
while (i < n && arr[i] == arr[large]) ++i;
if (i < n)
{
if (arr[large] < arr[i])
{
large = i;
second_large = 0;
}
else
{
second_large = i;
}
while (++i < n)
{
if (arr[large] < arr[i])
{
second_large = large;
large = i;
}
else if (arr[second_large] < arr[i])
{
second_large = i;
}
}
}
for (i = 0; i < n; i++)
{
printf( "%d ", arr[i] );
}
putchar( '\n' );
if (second_large == n)
{
puts( "All elements are equal each other." );
}
else
{
printf( "The largest of these numbers is : %d\n", arr[large] );
printf( "The second largest of these numbers is : %d\n", arr[second_large] );
}
}
The program output is
4 5 1 2 3
The largest of these numbers is : 5
The second largest of these numbers is : 4
A C++ demonstration program can look the following way
#include <iostream>
#include <functional>
#include <iterator>
#include <algorithm>
int main()
{
int arr[] = { 4, 5, 1, 2, 3 };
const size_t n = sizeof( arr ) / sizeof( *arr );
auto last = std::next( arr, n );
for (auto first = std::begin( arr ); first != last; ++first)
{
std::cout << *first << ' ';
}
std::cout << '\n';
auto it = std::adjacent_find( std::begin( arr ), last,
std::not_equal_to<>() );
if (it == last)
{
std::cout << "All elements are equal each other.\n";
}
else
{
auto [second_large, large] = std::minmax( { it, std::next( it ) },
[]( const auto &it1, const auto &it2 )
{
return *it1 < *it2;
} );
for (auto current = std::next( it, 2 ); current != last; ++current)
{
if (*large < *current)
{
second_large = std::exchange( large, current );
}
else if (*second_large < *current)
{
second_large = current;
}
}
std::cout << "The largest of these numbers is "
<< *large << " that is present at position "
<< std::distance( std::begin( arr ), large )
<< '\n';
std::cout << "The second largest of these numbers is "
<< *second_large << " that is present at position "
<< std::distance( std::begin( arr ), second_large )
<< '\n';
}
}
The program output is
4 5 1 2 3
The largest of these numbers is 5 that is present at position 1
The second largest of these numbers is 4 that is present at position 0
There are some minor errors in the code itself that can cause the problem.
Once, As you know that the array starts at index 0 but in the for loop you did count it from 1. so instead of:
for(i=1;i<n;i++)
{
if(arr[i]>large)
large = arr[i];
}
You should start your for loop also from zero, otherwise, you are not counting one.
Also for more simplicity, you can write your code like this:
#include <iostream>
using namespace std;
int main(){
int n, num[50], biggest, secondBiggest;
cout<<"Enter number of elements in your array: ";
cin>>n;
for(int i=0; i<n; i++){
cout<<"Enter your "<<(i+1)<<" Number: ";
cin>>num[i];
}
if(num[0]<num[1]){
biggest= num[1];
secondBiggest= num[0];
}
else{
biggest= num[0];
secondBiggest= num[1];
}
for (int i = 2; i< n ; i ++) {
if (num[i] > biggest) {
secondBiggest= biggest;
biggest= num[i];
}
else if (num[i] > secondBiggest && num[i] != biggest) {
secondBiggest= num[i];
}
}
cout<<"Second Largest Element in array is: "<<secondBiggest;
return 0;
}

C Bubble sort read access viloation issue

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNING
#endif
#include <stdio.h>
#include <stdlib.h>
void bubbleSort(int matrix[9], int n);
int main(void) {
int matrix[9];
int n = 9;
printf("enter 10 values to the matirx \n");
for (int i = 0; i < 10; i++) {
printf("now %dth componet\n ", i+1);
scanf("%d", &matrix[i]);
}
bubbleSort(matrix[9], n);
return 0;
}
void bubbleSort(int matrix [9], int n) {
//bubble sort the given matrix
int temp = 0;
for (int i=n-1; i > 0; i--) {
// compare two values at j and j+1 and move left when j+1 is smaller than j
for (int j = 0; j < i; j++) {
if (matrix[j] > matrix[j + 1]) {
temp = matrix[j];
matrix[j] = matrix[j + 1];
matrix[j + 1] = temp;
}
}
printf("Check the matrix \n");
for (int i = 0; i < 9; i++) {
printf("%d ", matrix[i]);
}
printf("\n");
}
}
Hi, I am getting a read access violation error at
if (matrix[j] > matrix[j + 1]) {
**temp = matrix[j];**
matrix[j] = matrix[j + 1];
matrix[j + 1] = temp;
}
This part of the code. The code builds right, but when I run the program I get an error. Can anyone help me out to figure out the issue? I searched up a little bit and based on that I assume it has something to do with the pointer but I do not know why there would be an issue with a pointer since I never used it in my code.
For starters you declared an array that contains only 9 elements.
int matrix[9];
On the other hand, you are trying to enter 10 elements.
printf("enter 10 values to the matirx \n");
for (int i = 0; i < 10; i++) {
printf("now %dth componet\n ", i+1);
scanf("%d", &matrix[i]);
}
So the program already has undefined behavior.
In this function declaration
void bubbleSort(int matrix[9], int n);
the magic number 9 used in the declaration of the first parameter does not make a great sense. Just write
void bubbleSort(int matrix[], int n);
or
void bubbleSort(int *matrix, int n);
In this call
bubbleSort(matrix[9], n);
instead of passing the array matrix like
bubbleSort(matrix, n);
you are passing the non-existent element of the array matrix[9]. The compiler should issue a message that you are trying to convert an integer to a pointer.
Within the function you are using the magic number 9 instead of the parameter n in this loop
for (int i = 0; i < 9; i++) {
Pay attention to that it looks strange when a one-dimensional array is named matrix.
Using your approach the program can look the following way.
#include <stdio.h>
void bubbleSort( int matrix[], size_t n )
{
if ( n )
{
for ( size_t i = n - 1; i != 0; i-- )
{
// compare two values at j and j+1 and move left when j+1 is smaller than j
for ( size_t j = 0; j < i; j++ )
{
if ( matrix[j + 1] < matrix[j] )
{
int temp = matrix[j];
matrix[j] = matrix[j + 1];
matrix[j + 1] = temp;
}
}
}
}
}
int main(void)
{
enum { N = 9 };
int matrix[N];
printf( "enter %d values to the matirx \n", N );
for ( int i = 0; i < N; i++ )
{
printf( "now %dth componet\n", i+1 );
scanf( "%d", matrix + i );
}
bubbleSort( matrix, N );
for ( int i = 0; i < N; i++ )
{
printf( "%d", matrix[i] );
}
putchar( '\n' );
return 0;
}
The program output might look
enter 9 values to the matirx
now 1th componet
9
now 2th componet
8
now 3th componet
7
now 4th componet
6
now 5th componet
5
now 6th componet
4
now 7th componet
3
now 8th componet
2
now 9th componet
1
1 2 3 4 5 6 7 8 9
bubbleSort(matrix[9], n);
This passes just the final element of the list (coerced into an address) rather than the actual address of the list, which is what you probably intended.
That won't end well :-)
You should just pass in matrix.
A decent compiler should warn you of this, such as with gcc:
prog.c: In function ‘main’:
prog.c:21:22: warning: passing argument 1 of ‘bubbleSort’
makes pointer from integer without a cast
[-Wint-conversion]
21 | bubbleSort(matrix[9], n);
| ~~~~~~^~~
| |
| int
prog.c:7:21: note: expected ‘int *’ but argument is of
type ‘int’
7 | void bubbleSort(int matrix[9], int n);
| ~~~~^~~~~~~~~

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);
}
}

How can I start with this problem and fix my code?

The question: write a program that gets a list of numbers ( lets say 4 numbers ) and an extra number and checks if the extra number equals to the multiplying of two numbers from the list. If yes return true else return false.
For example a number list is ( 2,4,8,16) an extra number is 32, the program checks if 32 is equal to two numbers of the numbers from the list, and return true, in this example it will, because 32 equals to, my solution is below but its not correct, any help appreciated
int i;
int b;
int listA[4] = {2, 4, 8, 10};
printf("Enter your Extra number value \n");
scanf("%d", &b);
for(i=0; i<4; i++){//?
if(listA[i] * listA[i+] == b){// i+1 ?
printf("True! \n");
}else{
printf("False \n");
}
All you need is to write two nested loops.
You could write a separate function.
I suppose that the original array (list) is not necessary ordered.
For example
#include <stdio.h>
int is_multiplied( const int a[], size_t n, int value )
{
int result = 0;
if ( !( n < 2 ) )
{
for ( size_t i = 0; !result && i < n - 1; i++ )
{
for ( size_t j = i + 1; !result && j < n; j++ )
{
result = a[i] * a[j] == value;
}
}
}
return result;
}
int main(void)
{
int a[] = { 2, 4 , 8 , 10 };
const size_t N = sizeof( a ) / sizeof( *a );
int value = 32;
printf( "%s\n", is_multiplied( a, N, value ) ? "true" : "false" );
return 0;
}
The program output is
true
Since your code doesn't even compile. Id imagine you didn't put a lot of time into this.
int main()
{
int i;
int b;
int listA[4] = {2, 4 , 8 , 10};
bool verified = false;
printf("Enter your Extra number value \n");
scanf("%d" ,&b);
for(i=0; i<4 ; i++ )
{
for(int j=0; j<4; j++ )
{
if(j==i)
{
break;
}
if(listA[i] * listA[j] == b)
{
printf("True! \n");
verified = true;
continue;
}
else
{
//printf("False \n");
}
}
}
if(!verified)
{
printf("False \n");
}
}
To start with approach these sort of problems in the easiest possible method. using nested for loop.
As mentioned in one of the comments add a nested for loop.
int i=0;
int j=0;
int b=0;
int listA[4] = {2, 4 , 8 , 10};
printf("Enter your Extra number value \n");
scanf("%d" ,&b);
for(i=0; i<4 ; i++){//?
for (j=i; j<4; j++) {
if(listA[i] * listA[j] == b)
{
printf("True! \n");
return 0;
}
}
}
printf("False \n");
return 0;
Further optimization:-
for(i=0; i<4 ; i++){
if ((i > b) || ((b % i) != 0))
continue;
k = b/i;
for (j=i; j<4; j++) {
if(listA[j] == k)
{
printf("True! \n");
return 0;
}
}
}

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.

Resources