I have to solve it in C language. I have arrays with n integers. L and U are lower and upper bound. I have to reverse numbers in array which is in [L,U]. I tried it by this way, but in some cases the answer is wrong. What mist be changed in the code? Or is there any other logic to complete the task?
#include <stdio.h>
int main() {
int x, arr[100], n, l, u, a, temp, temp1;
scanf("%d%d%d", &n, &l, &u);
for (int i = 0; i < n; i++) {
scanf("%d", &x); // read elements of an array
arr[i] = x;
}
a = n / 2;
for (int i = 0; i < a; i++) {
for (int j = a; j < n; j++) {
if (arr[i] >= l && arr[i] <= u) {
if (arr[j] >=l && arr[j] < u) {
temp = arr[j];
temp1 = arr[i];
arr[i] = temp;
arr[j] = temp1;
}
}
}
}
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
}
sample input:
10(number of integers) -7(lower bound) 5(upper bound)
-10 -9 5 -2 -3 7 10 6 -8 -5
sample output:
-10 -9 -5 -3 -2 7 10 6 -8 5
my output:
-10 -9 -5 -2 -3 7 10 6 -8 5
There is an O(N) solution that does not require nesting of loops.
First, with the code as you as you have it, declare an additional array and some other helper variables that keeps track of what indices need to be swapped.
int left, right;
int swaplist[100] = {0};
int swapcount = 0;
Your can keep your initial intake loop exactly as you have it, but amended to append the index of the newly scanned value to the swaplist array if the value is between the lower and upper bounds.
for (int i = 0; i < n; i++) {
scanf("%d", &x); // read elements of an array
arr[i] = x;
if ((x >= l) && (x <= u)) {
swaplist[swapcount++] = i;
}
}
Then a single loop to iterate over "swaplist" and do the swaps against the original array.
left = 0;
right = swapcount-1;
while (left < right) {
int leftindex = table[left];
int rightindex = table[right];
int tmp = arr[leftindex];
arr[leftindex] = arr[rightindex];
arr[rightindex] = tmp;
left++; right--;
}
You made a valiant attempt. Your nested for() loops are appropriate for some kinds of sorting algorithms, but not for what seems to be the purpose of this task.
From the sample input and desired output, you really want to establish a 'bracket' at either end of the array, then shift both toward the centre, swapping elements whose value happens to satisfy low <= n <= high value. (In this case, -7 <= n <= 5).
Here's a solution:
#include <stdio.h>
int swap( int arr[], size_t l, size_t r ) { // conventional swap algorithm
int t = arr[l];
arr[l] = arr[r];
arr[r] = t;
return 1;
}
int main() {
int arr[] = { -10, -9, 5, -2, -3, 7, 10, 6, -8, -5, }; // your data
size_t i, sz = sizeof arr/sizeof arr[0];
for( i = 0; i < sz; i++ ) // showing original version
printf( "%d ", arr[i] );
putchar( '\n' );
#define inRange( x ) ( -7 <= arr[x] && arr[x] <= 5 ) // a good time for a macro
size_t L = 0, R = sz - 1; // 'L'eft and 'R'ight "brackets"
do {
while( L < R && !inRange( L ) ) L++; // scan from left to find a target
while( L < R && !inRange( R ) ) R--; // scan from right to find a target
} while( L < R && swap( arr, L, R ) && (L+=1) > 0 && (R-=1) > 0 );
for( i = 0; i < sz; i++ ) // showing results
printf( "%d ", arr[i] );
putchar( '\n' );
return 0;
}
-10 -9 5 -2 -3 7 10 6 -8 -5
-10 -9 -5 -3 -2 7 10 6 -8 5
If I have understood the assignment correctly you need to reverse elements of an array that satisfy some condition.
If so then these nested for loops
for (int i = 0; i < a; i++) {
for (int j = a; j < n; j++) {
if (arr[i] >= l && arr[i] <= u) {
if (arr[j] >=l && arr[j] < u) {
temp = arr[j];
temp1 = arr[i];
arr[i] = temp;
arr[j] = temp1;
}
}
}
}
do not make sense.
It is enough to use only one for loop as shown in the demonstration program below.
#include <stdio.h>
int main( void )
{
int a[] = { 1, 10, 2, 3, 20, 4, 30, 5, 40, 6, 7, 50, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
int l = 10, u = 50;
for (size_t i = 0, j = N; i < j; i++ )
{
while (i < j && !( l <= a[i] && a[i] <= u )) ++i;
if (i < j)
{
while (i < --j && !( l <= a[j] && a[j] <= u ));
if (i < j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
}
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
The program output is
1 10 2 3 20 4 30 5 40 6 7 50 9
1 50 2 3 40 4 30 5 20 6 7 10 9
You could write a separate function as for example
#include <stdio.h>
void reverse_in_range( int a[], size_t n, int low, int upper )
{
for (size_t i = 0, j = n; i < j; )
{
while (i < j && !( low <= a[i] && a[i] <= upper )) ++i;
if (i < j)
{
while (i < --j && !( low <= a[j] && a[j] <= upper ));
if (i < j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
++i;
}
}
}
}
int main( void )
{
int a[] = { 1, 10, 2, 3, 20, 4, 30, 5, 40, 6, 7, 50, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
reverse_in_range( a, N, 10,50 );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
Thanks for everyone help. I read all of them, but I found another way to solve this problem. I will write it just in case. (some variable names are random, so in case of questions, comment).
#include <stdio.h>
int main() {
int x, main[100], n, l, u, a = 0, arr[100], temp, m = 0,f=0,c,d;
scanf("%d%d%d", &n, &l, &u);
for (int i = 0; i < n; i++) {
scanf("%d", &x); // read elements of an array
main[i] = x;
if (x >= l && x <= u) {
a++; //check if element is in range [l,u] and increasing a. later "a" will be used a length of the array "arr". this array cootains elements, which in in [u,l].
}
}
//add [u,l] elements in new array "arr"
for (int i = 0; i < n; i++) {
if (main[i] >= l && main[i] <= u) {
arr[m] = main[i];
m++; //index counter of "arr",
}
}
d=0;
for(int i=0;i<n;i++){
if(main[i]==arr[d]){
c=arr[a-d-1];
main[i]=c;
d++;
}
}
for(int i=0;i<n;i++){
printf("%d ",main[i]);
}
}
My best guess is that scanf is very annoying, on top of that, your format is ambiguous.
How will %d%d%d read 1234? Will it give you 12 3 and 4? 1 23 and 4? ...
try to do
scanf("%d %d %d" ...); // or
scanf("%d, %d, %d" ...);
something like that. Note that scanf is not recommended to be used, getc is a neat alternative, though also annoying when you want to read numbers with more than one digit, but you could create a function read_number, which, based on getc, will read a number as a string and return the int value with stoi.
Related
/**
#brief Move all negative elements to end
EX: Given an unsorted array arr[] of size N having both negative and positive integers.
The task is place all negative element at the end of array
without changing the order of positive element and negative element.
Example 1:
Input :
N = 8
arr[] = {1, -1, 3, 2, -7, -5, 11, 6 }
Output :
1 3 2 11 6 -1 -7 -5
Example 2:
Input :
N=8
arr[] = {-5, 7, -3, -4, 9, 10, -1, 11}
Output :
7 9 10 11 -5 -3 -4 -1
*/
#include<stdio.h>
void shortArray(int array[], int stack[]){
int size = 8;
int left = 0;
int right = size;
for(int i=0; i<size; i++){
if(left = right) break;
volatile int value = array[i];
if(array[i] > 0){
stack[left] = value;
left ++;
}
if(array[i] < 0){
stack[right] = value;
right--;
}
}
}
//printarray
void printArray(int array[], int size){
for(int i=0; i<size; i++){
printf(" %d", array[i]);
}
}
int main(){
int array[] = {-5, 7, -3, -4, 9, 10, -1, 11};
int size = 8;
int stack[size];
shortArray(array, stack);
printArray(stack, size);
return 0;
}
my output:
0 0 0 0 0 0 0 0
i try to assign value to stack[] but it don't work right.
i dont know what wrong with it? can you tell me why? thank you!
sorry for my bad english :<
For starters the assignment sounds like
The task is place all negative element at the end of array
It means that you need to change the source array in place not to build a new array.
In this if statement
if(left = right) break;
there is used the assignment operator = instead of the equality operator ==. So if right initially is not equal to 0 then the loop breaks at once.
Using the qualifier volatile in this declaration
volatile int value = array[i];
has no any sense.
If the first element of the source array is negative then this if statement
if(array[i] < 0){
stack[right] = value;
right--;
}
invokes undefined behavior because the index right points to memory after the last element of the array stack.
And moreover with this approach the order of negative values will be broken
And the function shall not use the magic number 8. It should be able to deal with arrays of various sizes. So the function must accept the number of elements in the passed to it array.
The function can be defined for example the following way as it is shown in the demonstration program below
#include <stdio.h>
void partition( int a[], size_t n )
{
for (size_t i = 0, j = 0; i < n; )
{
while (j != n && !( a[j] < 0 )) j++;
if (!( j < i )) i = j;
while (i != n && a[i] < 0) i++;
if (i != n)
{
int tmp = a[i];
for ( size_t k = i; k != j; --k )
{
a[k] = a[k - 1];
}
a[j] = tmp;
i++, j++;
}
}
}
int main( void )
{
int a[] = { 1, -1, 3, 2, -7, -5, 11, 6 };
const size_t N = sizeof( a ) / sizeof( *a );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
partition( a, N );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
The program output is
1 -1 3 2 -7 -5 11 6
1 3 2 11 6 -1 -7 -5
#include <stdio.h>
void main()
{
int maj, count, n = 6;
int arr[] = {1, 2, 2, 2, 2, 3, 4};
for (int i = 0; i < n; i++) {
maj = arr[i];
count = 0;
for (int j = 9; j < n; j++) {
if (arr[j] == maj) count++;
}
if (count > n / 2) {
break; /* I think some problem is here ,if majority element not found then it takes last element as the majority element */
}
}
printf("%d", maj);
}
It is giving correct output if majority ellement is there but incorrect output if no majority element is there for example if array is {1,2,3,4} it is giving output as 4. please help!!
#include <stdio.h>
int main() {
int maj, count, n = 7; //n is size of arr
int arr[] = {1, 2, 2, 2, 2, 3, 4};
int isFound = 0; //0 -> false, 1 -> true
for (int i = 0; i < n; i++) {
maj = arr[i];
count = 1; //first elements is itself
isFound = 0; //by default we assume that no major elements is found
for (int j = i+1; j < n; j++) { //iterate from next elements onwards to right in array
if (arr[j] == maj) count++;
}
if (count > n / 2) {
isFound = 1;
break; //major elements found; no need to iterator further; just break the loop now
}
}
if(isFound) printf("%d ", maj);
else printf("no major element");
return 0;
}
For starters according to the C Standard function main without parameters shall be declared like
int main( void )
Try not to use magic numbers. Usually as in your program they are a reason for program bugs. For example you declared the array arr as having 7 elements however the variable n that should keep the number of elements in the array is initialized with the value 6. Another magic number 9 is used in the loop
for (int j = 9; j < n; j++) {
^^^
There is no need to write the outer loop that travers the whole array. Also the program does not report the case when the majority number does not exist in the array.
Using your approach with two loops the program can look the following way
#include <stdio.h>
int main( void )
{
int a[] = { 1, 2, 2, 2, 2, 3, 4 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t i = 0;
for ( ; i < ( N + 1 ) / 2; i++ )
{
size_t count = 1;
for ( size_t j = i + 1; count < N / 2 + 1 && j < N; j++ )
{
if ( a[i] == a[j] ) ++count;
}
if ( !( count < N / 2 + 1) ) break;
}
if ( i != ( N + 1 ) / 2 )
{
printf( "The majority is %d\n", a[i] );
}
else
{
puts( "There is no majority element" );
}
return 0;
}
Its output is
The majority is 2
I need to sort the elements in the odd positions in the descending order and elements in the even position in ascending order. Here is my code, I'm unable to break the first loop.
#include<stdio.h>
int main()
{
int n, t;
printf("Enter the size of the array\n");
scanf("%d", &n);
int i, a[n];
if ((n > 20) || (n <= 0))
printf("Invalid Size");
else
{
printf("Enter the values\n");
for (i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
for (i = 0; i < n; i + 2)
{
if (a[i] > a[i + 2])
{
t = a[i];
a[i] = a[i + 2];
a[i + 2] = t;
}
}
for (i = 1; i < n; i + 2)
{
if (a[i] < a[i + 2])
{
t = a[i];
a[i] = a[i + 2];
a[i + 2] = t;
}
}
for (i = 0; i < n; i++)
{
printf("%d\n", a[i]);
}
}
}
For starters according to the C Standard the function main without parameters shall be declared like
int main( void )
There is no great sense to declare the variable n as having the type int that after that to check whether its value is less than zero. It is much better to declare it as having the type size_t.
And the array should be declared after the check
if ((n > 20) || (n <= 0))
printf("Invalid Size");
else
{
int a[n];
//...
In loops like this
for (i = 0; i < n; i + 2)
the variable i is not increased. It is obvious that you mean i += 2.
And the loops only moves the first minimum even and the first maximum odd elements to the end of the array. You need additional loops that will do the same operation for other elements of the array. That is the implementation of the bubble sort algorithm is incorrect.
Here is a demonstrative program that shows how the array can be sorted according to the requirements for even and odd elements of the array.
#include <stdio.h>
#define N 20
int main(void)
{
int a[N] = { 18, 1, 16, 3, 14, 5, 12, 7, 10, 9, 8, 11, 6, 13, 4, 15, 2, 17, 0, 19 };
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
for ( size_t n = N, last; !( n < 3 ); n = last )
{
for ( size_t i = last = 2; i < n; i++ )
{
if ( ( i % 2 == 0 && a[i] < a[i - 2] ) ||
( i % 2 == 1 && a[i - 2] < a[i] ) )
{
int tmp = a[i];
a[i] = a[i - 2];
a[i - 2] = tmp;
last = i;
}
}
}
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
The program output is
18 1 16 3 14 5 12 7 10 9 8 11 6 13 4 15 2 17 0 19
0 19 2 17 4 15 6 13 8 11 10 9 12 7 14 5 16 3 18 1
The most obvious problem is that your for never ends because i is never actually updated. The i+2 in for (i = 0; i < n; i + 2) does not update i which keeps its initia value forever.
Try something like for (i = 0; i < n; i=i+2) instead.
A second problem is that you are not really performing a sorting.
I guess that you are trying to implement some sort of bubble sort.
It sorts using comparison. It is impossible to sort an array using less than n logn operation (when sorting using comparison). You are sorting the array in linear time and this should look as a red flag to you.
Try adding another for as follows:
for (i = 0; i < n; i+= 2)
for (j = i+2; j < n; j+= 2)
if (a[i] > a[j])
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
and most importantly then read about why you need it.
And if you feel brave you can swap the intgers without using an intermediate variable t as follows (read more on the topic here: XOR swap):
if (a[i] > a[j])
{
a[i] = a[i]^a[j];
a[j] = a[j]^a[i];
a[i] = a[i]^a[j];
}
Hope it helps.
I should make new array out of existing one (ex. 1 0 4 5 4 3 1) so that the new one contains digits already in existing array and the number of their appearances.
So, the new one would look like this: 1 2 0 1 4 2 5 1 3 1 (1 appears 2 times, 0 appears 1 time.... 3 appears 1 time; the order in which they appear in first array should be kept in new one also); I know how to count no. of times a value appears in an array, but how do I insert the no.of appearances? (C language)
#include <stdio.h>
#define max 100
int main() {
int b, n, s, i, a[max], j, k;
printf("Enter the number of array elements:\n");
scanf("%d", &n);
if ((n > max) || (n <= 0)) exit();
printf("Enter the array:\n");
for (i = 0; i < n; i++)
scanf("%d", a[i]);
for (i = 0; i < n; i++) {
for (j = i + 1; j < n;) {
if (a[j] == a[i]) {
for (k = j; k < n; k++) {
a[k] = a[k + 1];
}}}}
//in the last 5 rows i've tried to compare elements, and if they are same, to increment the counter, and I've stopped here since I realised I don't know how to do that for every digit/integer that appears in array//
If you know that the existing array consists of digits between 0 and 9, then you can use the index of the array to indicate the value that you are incrementing.
int in[12] = {1,5,2,5,6,5,3,2,1,5,6,3};
int out[10] = {0,0,0,0,0,0,0,0,0,0};
for (int i = 0; i < 12; ++i)
{
++out[ in[i] ];
}
If you provide any code snippet, its easy for the community to help you.
Try this, even you optimize the no.of loops :)
#include <stdio.h>
void func(int in[], int in_length, int *out[], int *out_length) {
int temp[10] = {0}, i = 0, j = 0, value;
//scan the input
for(i=0; i< in_length; ++i) {
value = in[i];
if(value >= 0 && value <= 9) { //hope all the values are single digits
temp[value]++;
}
}
// Find no.of unique digits
int unique_digits = 0;
for(i = 0; i < 10; ++i) {
if(temp[i] > 0)
unique_digits++;
}
// Allocate memory for output
*out_length = 2 * unique_digits ;
printf("digits: %d out_length: %d \n",unique_digits, *out_length );
*out = malloc(2 * unique_digits * sizeof(int));
//Fill the output
for(i = 0, j = 0; i<in_length && j < *out_length; ++i) {
//printf("\n i:%d, j:%d val:%d cout:%d ", i, j, in[i], temp[in[i]] );
if(temp[in[i]] > 0 ) {
(*out)[j] = in[i];
(*out)[j+1] = temp[in[i]];
temp[in[i]] = 0; //Reset the occurrences of this digit, as we already pushed this digit into output
j += 2;
}
}
}
int main(void) {
int input[100] = {1, 0, 4, 5, 4, 3, 1};
int *output = NULL, output_length = 0, i = 0;
func(input, 7, &output, &output_length );
for(i=0; i < output_length; i+=2) {
printf("\n %d : %d ", output[i], output[i+1]);
}
return 0;
}
I get a message when I try to run the program. Why?
Segmentation fault
my code:
#include <stdio.h>
void sort_array(int *arr, int s);
int main() {
int arrx[] = { 6, 3, 6, 8, 4, 2, 5, 7 };
sort_array(arrx, 8);
for (int r = 0; r < 8; r++) {
printf("index[%d] = %d\n", r, arrx[r]);
}
return(0);
}
sort_array(int *arr, int s) {
int i, x, temp_x, temp;
x = 0;
i = s-1;
while (x < s) {
temp_x = x;
while (i >= 0) {
if (arr[x] > arr[i]) {
temp = arr[x];
arr[x] = arr[i];
arr[i] = temp;
x++;
}
i++;
}
x = temp_x + 1;
i = x;
}
}
I think that the problem is in the if statement.
What do you think? Why does it happen? I think that I use in positive way with the pointer to the array.
Thank you!
This loop in your program
while (i >= 0) {
//...
i++;
}
does not make sense because i is increased unconditionly.
The program can look the following way
#include <stdio.h>
void bubble_sort( int a[], size_t n )
{
while ( !( n < 2 ) )
{
size_t i = 0, last = 1;
while ( ++i < n )
{
if ( a[i] < a[i-1] )
{
int tmp = a[i];
a[i] = a[i-1];
a[i-1] = tmp;
last = i;
}
}
n = last;
}
}
int main( void )
{
int a[] = { 6, 3, 6, 8, 4, 2, 5, 7 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
printf( "\n" );
bubble_sort( a, N );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
printf( "\n" );
return 0;
}
The program output is
6 3 6 8 4 2 5 7
2 3 4 5 6 6 7 8
If you want that the sorting function had only one while loop then you can implement it the following way
void bubble_sort( int a[], size_t n )
{
size_t i = 0;
while ( ++i < n )
{
if ( a[i] < a[i-1] )
{
int tmp = a[i];
a[i] = a[i-1];
a[i-1] = tmp;
i = 0;
}
}
}
In your inner loop, you increment i beyond the size of the array. Your algorithm should require you to decrement i instead, but I am not sure this would be enough to fix the sorting algorithm.
You should first try to implement Bubble sort with a single while loop where you compare adjacent items and step back whenever you swap them.