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.
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
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);
}
}
My for loops seems not working properly. First number which tells me how many task do I want my program to do is n. When I input 1 or 2, it works, but when I input 3 and more, it starts to struggle. Every row has 3 numbers separated by a space as you can see in the code. I am not getting all outputs. Algorithm in this program works perfect so no problem there.
Please ignore comments in the code. And sorry for my english.
#include <stdio.h>
int n;
int i;
int s;
int d;
int p;
int k;
int A;
int x;
int r[];
int koniec;
main()
{
scanf("%d", &n);
while( !(n >= 1 && n <=1000) )
{
//printf ( "max 1000 uloh min 1 \n");
return 1;//scanf("%d", &n);
}
for( i=1; i < n; i++)
{
scanf("%d %d %d", &s, &p, &d);
while((s < 1) || (s > 15000) || (p < 1) || (p > 4000) || (d < 1) || (d > 15000)) {
//printf ("prekroceny limit \n");
return 1; // scanf("%d %d %d", &s, &p, &d);
}
k = s / d;
A = s - ( k * d );
if ( A == 0 )
{
r[i] == 0;
}
else
{
//s = k * d + A ;
x = ( A * p ) / d ;
r[i] = p - x ;
}
}
for ( koniec = 0 ; koniec < i+1 ; koniec++ )
{
printf ( "%d", r[koniec] ) ;
printf ( "\n");
}
system("pause");
}
Example input so you can understand better:
4
5 4 4
6 100 3
500 5 1000
314 159 26
and output:
3
0
3
147
EDIT>
5
3434 234 2345
14455 345 12
134 145 1345
9242 2455 13455
83 34 133
output:
126
144
141
769
13
or something shorter>
input:
2
15000 1 1
1 4000 1
output:
0
0
Im getting return value 1 in both examples
My final code edit:
#include <stdio.h>
#include <stdlib.h>
int n;
int i;
int s;
int d;
int p;
int k;
int A;
int x;
int *r;
int koniec;
main()
{
scanf("%d", &n);
while( !(n >= 1 && n <=1000) )
{
return 0;//printf ( "max 1000 uloh min 1 \n");
//scanf("%d", &n);
}
r = (int *)malloc(n*sizeof(int));
for(i=0; i < n; i++)
{
scanf("%d %d %d", &s, &p, &d);
while((s < 1) || (s > 15000) || (p < 1) || (p > 4000) || (d < 1) || (d > 15000))
{
//printf ("prekroceny limit \n");
return 0; //scanf("%d %d %d", &s, &p, &d);
}
k = s / d;
A = s - ( k * d );
if ( A == 0 )
{
r[i] = 0;
}
else
{
//s = k * d + A ;
x = ( A * p ) / d ;
r[i] = p - x ;
}
}
for ( koniec = 0 ; koniec < n ; koniec++ )
{
printf ( "%d", r[koniec] ) ;
printf ( "\n");
}
free(r);
return 0;
}
You need to use malloc() to allocate memory dynamically. (Also #include stdlib.h)
For instance, add the following line after the first while loop :
//Note - at the top, change int r[] to the below:
int *r; //Instead of int r[]
//End note
while( !(n >= 1 && n <=1000) )
{
printf ( "max 1000 uloh min 1 \n");
scanf("%d", &n);
}
r = (int *) malloc(n*sizeof(int)); //Allocate "n" integers to your 'array r'
It should also be noted that once you are done using the array r, you must free() this memory like so:
free(r);
In addition, there are some other coding problems:
Be sure for( i=1; i < n; i++) is what you want. You use "i" to index your array, but arrays in C start from 0. So it (likely) should read for( i=0; i < n; i++).
r[i] == 0; is used falsely as an assignment. Use a single = to assign a value to a variable. Use the double equals == to compare two values.
for ( koniec = 0 ; koniec < i+1 ; koniec++ ) will likely through an error. Your i will be one less than n from the for-loop above it. So trying to iterate to i+1 or n will result in an array out of bounds problem -- aka a Segmentation Fault.
Edit - This should do what you want:
#include <stdio.h>
#include <stdlib.h>
int n;
int i;
int s;
int d;
int p;
int k;
int A;
int x;
int *r;
int koniec;
main()
{
scanf("%d", &n);
while( !(n >= 1 && n <=1000) )
{
//printf ( "max 1000 uloh min 1 \n");
//scanf("%d", &n);
return 1;
}
r = (int *)malloc(n*sizeof(int));
for(i=0; i < n; i++)
{
scanf("%d %d %d", &s, &p, &d);
while((s < 1) || (s > 15000) || (p < 1) || (p > 4000) || (d < 1) || (d > 15000))
{
//printf ("prekroceny limit \n");
//scanf("%d %d %d", &s, &p, &d);
return 1;
}
k = s / d;
A = s - ( k * d );
if ( A == 0 )
{
r[i] = 0;
}
else
{
s = k * d + A ; //This line does nothing... Just so you know
x = ( A * p ) / d ;
r[i] = p - x ;
}
}
for ( koniec = 0 ; koniec < n ; koniec++ )
{
printf ( "%d", r[koniec] ) ;
printf ( "\n");
}
free(r);
system("pause");
return 0;
}
Input:
4
5 4 4
6 100 3
500 5 1000
314 159 26
Output:
3
0
3
147
Allocate space for r[].
Change assignment.
Change for loop range.
//int r[];
main() {
scanf("%d", &n);
// while( !(n >= 1 && n <=1000) )
if (!(n >= 1 && n <=1000) ) {
return 1;//scanf("%d", &n);
}
int r[n]; // allocate
// for( i=1; i < n; i++)
for( i=0; i < n; i++) // Change range (#MrHappyAsthma)
...
// r[i] == 0;
r[i] = 0; // change
r[i] = p - x ;
// for ( koniec = 0 ; koniec < i+1 ; koniec++ )
for ( koniec = 0 ; koniec < n ; koniec++ )
I wrote a c program for matrix multiplication. Now I want to divide the number of rows into 5 blocks of N/5. Function should compute first block of rows in first iteration, second part in second iteration and so on. How do I specify starting row and ending row in each iteration ? I have tried it below. Could anyone help me correcting it.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, m, n, p, q, c, d, k,g, sum = 0,start=0,end=m/5;
int **first, **second, **multiply;
printf("Enter the number of rows and columns of first matrix\n");
scanf("%d%d", &m, &n);
printf("Value entered %d%d \n",m,n);
first = malloc(m*sizeof(int*));
for ( i =0;i <m; i++)
first[i] =malloc(n*sizeof(int));
printf("Enter the number of rows and columns of second matrix \n");
scanf("%d%d", &p,&q);
printf("value entered %d%d \n",p,q);
second = malloc(p*sizeof(int*));
for( i=0;i<p;i++)
second[i] = malloc(q*sizeof(int));
multiply = malloc(m*sizeof(int*));
for ( i=0;i<m;i++)
multiply[i] = malloc(q*sizeof(int));
printf("Enter the elements of first matrix\n");
for( c = 0 ; c < m ; c++ )
for ( d = 0 ; d < n ; d++ )
scanf("%d", &first[c][d]);
if ( n != p )
printf("Matrices with entered orders can't be multiplied with each other.\n");
else {
printf("Enter the elements of second matrix\n");
for ( c = 0 ; c < p ; c++ ){
for ( d = 0 ; d < q ; d++ )
scanf("%d", &second[c][d]);
}
for(g=0;g<5;g++){
for ( c = start ; c < end ; c++ ) {
for ( d = 0 ; d < q ; d++ ) {
for ( k = 0 ; k < p ; k++ ) {
sum = sum + first[c][k]*second[k][d];
}
multiply[c][d] = sum;
sum = 0;
}
}
start=start+m/5+1;
end=end+m/5;
}
printf("Product of entered matrices:-\n");
for ( c = 0 ; c < m ; c++ ) {
for ( d = 0 ; d < q ; d++ )
printf("%d\t", multiply[c][d]);
printf("\n");
}
for ( i = 0; i < p; i++)
free(second[i]);
free(second);
for ( i = 0; i < m; i++)
free(multiply[i]);
free(multiply);
}
for ( i = 0; i < m; i++)
free(first[i]);
free(first);
return 0;
}
Start indices usually are 0 (read it always), but about ending indices,
You must save them in variables rows/cols, when you're allocating/constructing the matrix.