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.
Im a beginner programmer and i needed some help with making the result of the following exercise look a bit better.
As i said in the title i want to make the exercise look nicer by removing the 0-s from the array and leaving just the numbers.
The exercise goes like this:
We enter an array of integers and we copy into the 2nd array the integers that are positive and negative and multiples of 3 and in the 3rd array the negative elements that are odd and not multiples of 3. This is the code that I did:
#include <stdio.h>
#include <stdlib.h>
#define N 5
int main()
{
int v[N];
int v2[N] = {0, };
int v3[N] = {0, };
int i;
printf("Please enter the elements of the 1st array: ");
for (i = 0; i < N; i++)
{
scanf("%d", &v[i]);
}
printf("\nThe elements of the 2nd array are: ");
for (i = 0; i < N; i++)
{
if ((v[i] >= 0 || v[i] <= 0) && v[i] % 3 == 0)
{
v2[i] = v[i];
}
}
for (i = 0; i < N; i++)
{
printf("%d ", v2[i]);
}
printf("\nThe value of the 3rd array are : ");
for (i = 0; i < N; i++)
{
if (v[i] <= 0 && v[i] % 2 != 0 && v[i] % 3 != 0)
{
v3[i] = v[i];
}
}
for (i = 0; i < N; i++)
{
printf("%d ", v3[i]);
}
return 0;
}
For future use if possible how to do I post a code copied for code blocks directly into here without using space 4 times on every line?
Thanks in advance
Another option is to insert a condition in the output loop:
for (i = 0; i < N; i++)
{
if (v2[i] != 0)
{
printf("%d ",v2[i]);
}
}
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);
}
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);
}
}
I'm writing a program that reads integers from keyboard input and find the occurrence then sort them in descending order.
I got the occurrence and the descending but when I type same integers, they are repeated if I type 8 7 8
it's like
8 2
8 2
7 1
help please??
This is my code
#pragma warning (disable :4996)
#include <stdio.h>
#include <stdlib.h>
int main(){
int input;
int inputarr[50], count[50] = {0};
int i=0, j;
int last = 0;
printf("Enter numbers \n");
///getting int
while (scanf("%d", &input) > 0)
{
inputarr[i] = input;
i++;
}
last = i;
printf(" N Count\n");
printf("----- -----\n");
int a;
/// increment count
for (i = 0; i < last; i++){
count[inputarr[i]] = count[inputarr[i]] + 1;
}
/////ascending
for (i = 0; i < last; i++)
{
for (j = 0; j < last; j++){
if (inputarr[j]<inputarr[j + 1])
{
int temp = inputarr[j];
inputarr[j] = inputarr[j + 1];
inputarr[j + 1] = temp;
}
}
printf(" %d %d\n", inputarr[i], count[inputarr[i]]);
}
return 0;
}
The problem with this code is that you are printing the array while it's being sorted. Inputing numbers 1 2 3 4 would result in numbers 2 1 4 1 2 1 1 1 being outputed. To accomplish what you wanted you should move the printing part out of the sorting loop. Even then when a number is appearing multiple times in the input the output won't contain it only once (ex. 8 7 8 -> 8 2 8 2 7 2). To do that you should not output the number if it is the same as the previous number you outputed.
Another thing, in the sorting loop you are potentially accessing non existing array elements at the line
for (j = 0; j < last; j++){
When j = last-1 you are accessing last element which might not exsist.
After fixing all this problems code might look like this:
for (i = 0; i < last; i++)
{
for (j = 0; j < last-1; j++){
if (inputarr[j]<inputarr[j + 1])
{
int temp = inputarr[j];
inputarr[j] = inputarr[j + 1];
inputarr[j + 1] = temp;
}
}
}
if (last == 0)
return 0;
printf(" %d %d\n", inputarr[0], count[inputarr[0]]);
for(i = 1; i < last; i++)
if (inputarr[i] != inputarr[i-1])
printf(" %d %d\n", inputarr[i], count[inputarr[i]]);