Not getting all results shifting my array - c

I'm trying to make a program that shifts all the elements of an array to the right by one and move the last element into the first position. My problem is when I run my code it's giving me the number 5 twice. Can someone help me, maybe my logic or my for loop is not right?
#include <stdio.h>
int main ()
{
int array[6];
int x;
int temp;
printf("Enter six numbers.\n\n");
for (x = 0; x < 6; x++) {
printf("Enter a number : ", x + 1);
scanf("%d", &array[x]);
temp = array[x - 1];
}
for (x = 6 - 1; x > 0; x--) {
array[x] = array[x - 1];
}
array[0] = temp;
for (x = 0; x < 6; x++) {
printf("%d\n", array[x]);
}
return 0;
}

You could make a for loop like
for(i=0; i<SIZE; ++i)
{
scanf("%d", &arr[(i+1)%SIZE]);
}
The (i+1)%SIZE would evaluate to i+1 if i+1 is less than SIZE. Otherwise, it would wrap around.
Or you can
int t=arr[SIZE-1];
for(i=SIZE-1; i>0; --i)
{
arr[i]=arr[i-1];
}
arr[0]=t;
save the last element into a temporary variable, shift other elements towards right and finally assign the first element the value in the temporary variable.
As Gourav pointed out, in the first iteration of your first for loop, arr[x-1] would become arr[-1] as x is 0. You are trying to access memory which is not part of that array. This invokes undefined behavior.

I will try to explain it with the very easiest algorithm and yes easy means not efficient as from performance perspective.
For example, let's say you have an array of six elements:
1 2 3 4 5 6
From the question, all I understood is that you want to reverse this array to have a final array to be:
6 5 4 3 2 1
A naive way of doing is to store the first element in a temporary variable, assign the second element to the first element and after that assign the temporary variable to the second element and repeat this until all elements are swapped as shown below:
temp = arr[0]
arr[0] = arr[1]
arr[1] = temp
You will need two loops to do this, one decrementing and one incrementing
1 2 3 4 5 6 i=0; j=5
2 1 3 4 5 6 i=1; j=5
2 3 1 4 5 6 i=2; j=5
2 3 4 1 5 6 i=3; j=5
2 3 4 5 1 6 i=4; j=5
2 3 4 5 6 1 i=5; j=5
Next, you have to execute the above loop with one less iteration:
2 3 4 5 6 1 i=0; j=4
3 2 4 5 6 1 i=1; j=4
3 4 2 5 6 1 i=2; j=4
3 4 5 2 6 1 i=3; j=4
3 4 5 6 2 1 i=4; j=4
So, the loops would be:
for(i=5; i>0; i--)
{
for(j=0; j<i; j++)
{
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}

You can make things a bit more generic by adding a direction to your shift routine and putting the shift code in a function that takes the array, the number of members and the direction to shift as arguments. Then its just a matter of iterating in the proper direction and shifting the elements in the correct direction and putting the final value in the proper place. For example, you could write a simple function as follows:
/** shift array index in in circular manner by 1 in the
* 0 - left or 1 - right direction.
*/
void arrayshift (int *a, size_t nmemb, int dir)
{
if (dir) { /* shift to RIGHT */
int tmp = a[nmemb - 1];
for (size_t i = nmemb - 1; i > 0; i--)
a[i] = a[i - 1];
a[0] = tmp;
}
else { /* shift to LEFT */
int tmp = a[0];
for (size_t i = 1; i < nmemb; i++)
a[i - 1] = a[i];
a[nmemb - 1] = tmp;
}
}
A simple test routine could be:
#include <stdio.h>
enum { LEFT, RIGHT };
void arrayshift (int *a, size_t nmemb, int dir);
int main (int argc, char **argv) {
int a[] = { 1, 2, 3, 4, 5, 6 },
dir = argc > 1 ? LEFT : RIGHT;
size_t n = sizeof a / sizeof *a;
printf ("original:");
for (size_t i = 0; i < n; i++)
printf (" %d", a[i]);
putchar ('\n');
arrayshift (a, n, dir);
printf ("shifted :");
for (size_t i = 0; i < n; i++)
printf (" %d", a[i]);
putchar ('\n');
return 0;
}
/** shift array index in in circular manner by 1 in the
* 0 - left or 1 - right direction.
*/
void arrayshift (int *a, size_t nmemb, int dir)
{
if (dir) { /* shift to RIGHT */
int tmp = a[nmemb - 1];
for (size_t i = nmemb - 1; i > 0; i--)
a[i] = a[i - 1];
a[0] = tmp;
}
else { /* shift to LEFT */
int tmp = a[0];
for (size_t i = 1; i < nmemb; i++)
a[i - 1] = a[i];
a[nmemb - 1] = tmp;
}
}
Example Use/Output
$ ./bin/array_cir_shift_by_1
original: 1 2 3 4 5 6
shifted : 6 1 2 3 4 5
$ ./bin/array_cir_shift_by_1 0
original: 1 2 3 4 5 6
shifted : 2 3 4 5 6 1
You can also pass the number of element to shift the array by and use the modulo operator to help with the indexing. (that is left for another day)

Related

Generating increasing subsequences out of n numbers of length k

I want to generate all possible increasing subsequences of numbers (repetition allowed) from 1 to n, but of length k.
Ex. n=3, k=2
Output:
1 1
1 2
1 3
2 2
2 3
3 3
This is my code:
#include <stdio.h>
int s[100];
int n=6;
int k=4;
void subk(int prev,int index)
{
int i;
if (index==k)
{
for(int i=0; i<k; i++)
printf("%d ",s[i]);
printf("\n");
return;
}
s[index]=prev;
for (i=prev; i<=n; ++i)
{
subk(i,index+1);//,s,n,k);
}
}
int main()
{
int j;
for (j = 1; j<=n ; ++j)
{
subk(j,0);
}
return 0;
}
But this generates some unwanted repetitions. How do I eliminate those?
I have tested your code with n = 3 and k = 2 and got the following result:
1 1
1 1
1 1
1 2
1 2
1 3
2 2
2 2
2 3
3 3
This is obviously incorrect, as there are several identical numbers like 1 1 or 1 2.
But what exactly went wrong?
Let's write down the right results if n = 3 and k = 3. Now compare those to the result we got from the program when n = 3 and k = 2.
correct program (incorrect)
k = 3 k = 2
1 1 1 1 1
1 1 2 1 1
1 1 3 1 1
1 2 2 1 2
1 2 3 1 2
1 3 3 1 3
2 2 2 2 2
2 2 3 2 2
2 3 3 2 3
3 3 3 3 3
Now we can see that the incorrect output of the program is the same as the first two columns of the correct answer when we set k = 3. This means that the program solves the problem for 3 columns if we set k = 2, but only displays the first two columns.
You need to stop the program from writing the same number several times.
Solution 1
One way to do this is to execute the for-loop in the subk-function only once when it writes the last number (index == (k - 1)) into the buffer s.
In order to achieve this, you need to add the following two lines to the end of your for-loop.
if (index == (k - 1))
break;
(Instead of the break you could also use return)
After you added these two lines the function should look like this:
void subk(int prev, int index)
{
int i;
if (index == k)
{
for (int i = 0; i<k; i++)
printf("%d ", s[i]);
printf("\n");
return;
}
s[index] = prev;
for (i = prev; i <= n; ++i)
{
subk(i, index + 1);//,s,n,k);
if (index + 1 == k)
break;
}
}
Solution 2
Another way to solve the problem is to move the line s[index] = prev; to the beginning of the function and change the k in the if-statement to k - 1.
Now the function should look like this:
void subk(int prev, int index)
{
int i;
s[index] = prev;
if (index == k - 1)
{
for (int i = 0; i<k; i++)
printf("%d ", s[i]);
printf("\n");
return;
}
for (i = prev; i <= n; ++i)
{
subk(i, index + 1);//,s,n,k);
}
}
With this solution, the for-loop is never executed when the index shows that the program is at the last 'sub-number'. It just displays the number and exits the function because of the return.
You get the right result with both solutions, but I personally like the second solution better, because there is no additional if-statement that is executed every iteration of the for-loop and the program is (slightly) faster.

Why is my program not dividing even numbers by two?

It should scan 10 int numbers and then display them backwards, dividing the even ones by two, but it just displays them without dividing.
es:
10 9 8 7 6 5 4 3 2 1 ==> 1 2 3 2 5 3 7 4 9 5
but mine does:
10 9 8 7 6 5 4 3 2 1 ==> 1 2 3 4 5 6 7 8 9 10
#include <stdio.h>
int main(void)
{
int a[10];
for(int i = 0; i < 10; i++)
scanf("%d", &a[i]);
for (int i = 0; i < 10; i++) {
if (a[i] % 2 == 0 ) {
a[i] = a[i] / 2; i++;
}
else
i++;
}
for(int i = 9; i > -1; i--)
printf("%d\n", a[i]);
return 0;
}
The middle loop incorrectly increments i twice per iteration:
for (int i = 0; i < 10; i++) { // <<== One increment
if (a[i]%2 == 0 ) {
a[i] = a[i]/2; i++; // <<== Another increment - first branch
}
else
i++; // <<== Another increment - second branch
}
In your case, all even numbers happen to be stored at even positions that your loop skips.
Note: A better solution is to drop the middle loop altogether, and do the division at the time of printing.
The body of your second for loop advances i. Since it's also advanced in the loop's clause, it's advanced twice, effectively skipping any other element. Remove those advancements, and you should be OK:
for(int i=0; i<10; i++) {
if (a[i] % 2 == 0) {
a[i] /= 2;
}
}
In your program you incrementing the for loop variable i two times inside the loop and loop also increment the value one time so the values are skipped that is the reason you are getting wrong output.herewith i have attached the corrected program and its output.hope you understand the concept .Thank you
#include <stdio.h>
int main(void)
{
int a[10];
printf("\n Given Values are");
printf("\n-----------------");
for(int i = 0; i < 10; i++)
scanf("%d", &a[i]);
for (int i = 0; i < 10; i++)
{
if (a[i] % 2 == 0 )
{
a[i] = a[i] / 2;
}
}
printf("\n After dividing the even numbers by 2 and print in reverse order");
printf("\n ----------------------------------------------------------------\n");
for(int i = 9; i > 0; i--)
printf("%d\n", a[i]);
return 0;
}
Output
Given Values are
-----------------
1
2
3
4
5
6
7
8
9
10
After dividing the even numbers by 2 and print in reverse order
----------------------------------------------------------------
5
9
4
7
3
5
2
3
1

What should I do for sort array?

I tried to sort arr by excluding those who were already selected as the largest numbers but it didn't work.
The result is this:
As I intended, at first cycle, the store is {9, 0, 0, 0, 0 ... } and when arr[i] becomes 9, the rest of process should be skipped. I have to sort it without additional functions and it's too difficult to me. What is the problem?
int i = 0;
int j = 0;
int num = 0;
int sign = 0;
int arr[10] = { 1,5,3,4,8,7,5,9,8,0 };
int max = arr[0];
int store[10] = { 0 };
int k = 0;
for (j = 0; j < 10; j++) {
printf("store: ");
for (int n = 0; n < 10; on++)
printf("%d ", store[n]);
printf("\n");
for (i = 0; i < 10; i++) {
sign = 0;
k = 0;
while (k < 10) {
if (arr[i] == store[k]) {
sign = 1;
break;
}
k++;
}
if (sign == 1) {
continue;
}
if (arr[i] > max) {
max = arr[i];
}
}
store[j] = max;
}
You have several errors here:
The array store has a size of 10, but in the jth pass through the outer loop, only j values have been filled in; the rest is still zero. So whenever you iterate over store, you should use j as upper limit.
You are looking for the max in each iteration. Therefore, it is not enough to initialise max once outside the outer loop. You do that, and it will stay 9 ever after. You should reset max for every j.
Finally, your idea to go through the array to see whether you have already processed a certain value does not work. Your array has duplicates, two 8's and two 5's. You will only place one eight and one five with your strategy and re-use the last value of max for the last two elements. (Plus, that idea lead to O(n³) code, which is very wasteful.
You can work around that by keeping an extra array where you store whether (1) or not (0) you have already processed a value at a certain index or by setting processed entries in the array to a very low value.
What you want to implement is selection sort: Find the maximum value in the whole list and move it to the front. Then find the maximum in the whole list except the first item and move it to the second slot and so on:
* 1 5 3 4 8 7 5 9 8 0
9 * 5 3 4 8 7 5 1 8 0
9 8 * 3 4 5 7 5 1 8 0
9 8 8 * 4 5 7 5 1 3 0
9 8 8 7 * 5 4 5 1 3 0
9 8 8 7 5 * 4 5 1 3 0
9 8 8 7 5 5 * 4 1 3 0
9 8 8 7 5 5 4 * 1 3 0
9 8 8 7 5 5 4 3 * 1 0
9 8 8 7 5 5 4 3 1 * 0
9 8 8 7 5 5 4 3 1 0 *
Here, all items to the left of the asterisk have been sorted and everything to the right of the asterisk is still unsorted. When the * (at position j) has moved to the right, the whole array is sorted.
This sort is in-place: It destroys the original order of the array. That is useful, because the position of an element tells us whether it has been processed or not. In the third iteration, the algorithm can distinguish between the 8 that has been sorted and the 8 that hasn't been sorted yet. (This sort is often described as sorting a hand of cards: Look fo the lowest, put it to the left and so on. If you must sort into a second array, copy the original array and sort the copy in place.)
Here's the code that sorts your array and prints out the diagram above:
#include <stdlib.h>
#include <stdio.h>
int main()
{
int arr[10] = {1, 5, 3, 4, 8, 7, 5, 9, 8, 0};
int i = 0;
int j = 0;
for (j = 0; j < 10; j++) {
int imax = j;
int swap = arr[j];
// print array
for (i = 0; i < 10; i++) {
if (i == j) printf("* ");
printf("%d ", arr[i]);
}
printf("\n");
// find index of maximum item
for (i = j + 1; i < 10; i++) {
if (arr[i] > arr[imax]) {
imax = i;
}
}
// swap first unsorted item and maximum item
arr[j] = arr[imax];
arr[imax] = swap;
}
// print fully sorted array
for (i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
printf("*\n");
return 0;
}
Use i and j.
N is 10 and the data consists of shuffled numbers 0 to N-1.
j goes from 0 to N-1. At each step, you want to fill it with
the maximum of the unprocessed input.
So i goes from j+1 to N-1, in the inner loop. If arr[j] < arr[i],
swap arr[i] and arr[j].
It speeds up considerably as you get towards the end.

How to find all subsets whose sum adds up to the value of a target value using dynamic programming in C

So I have been trying to do a variant of the subset sum problem, which I want to do using dynamic programming. So what I am aiming for is for example, to have an input of
m = 25 // Target value
n = 7 // Size of input set
and the input set to be for example {1, 3, 4, 6, 7, 10, 25}. So the wanted output would be something like
{1, 3, 4, 7, 10} and {25}.
Here is the code
#include <stdio.h>
#include <stdlib.h>
int main()
{
// Get input sequence
int n = 7; // Size of input set
int m = 25; // Target value
int *S; // Input set
int **C; // Cost table
int i,j,potentialSum,leftover;
S=(int*) malloc((n+1)*sizeof(int));
C=malloc((m+1)*sizeof(int*));
for (int rows = 0; rows<=m; rows++) {
C[rows] = malloc((m+1)*sizeof(int));
}
if (!S || !C)
{
printf(" FAILED %d\n",__LINE__);
exit(0);
}
S[0] = 0;
S[1] = 1;
S[2] = 3;
S[3] = 4;
S[4] = 6;
S[5] = 7;
S[6] = 10;
S[7] = 25;
// Initialize table for DP
C[0][0]=0; // DP base case
// For each potential sum, determine the smallest index such
// that its input value is in a subset to achieve that sum.
for (potentialSum=1; potentialSum<=m; potentialSum ++)
{
for (j=1;j<=n;j++)
{
leftover=potentialSum-S[j]; // To be achieved with other values
if (leftover<0) // Too much thrown away
continue;
if (C[leftover][0] == (-1)) // No way to achieve leftover
continue;
if (C[leftover][0]<j) // Indices are included in
break; // ascending order.
}
C[potentialSum][0]=(j<=n) ? j : (-1);
}
// Output the input set
printf(" i S\n");
printf("-------\n");
for (i=0;i<=n;i++)
printf("%3d %3d\n",i,S[i]);
// Output the DP table
printf("\n\n i C\n");
printf("-------\n");
for (i=0;i<=m;i++)
printf("%3d %3d\n",i,C[i][0]);
if (C[m][m]==(-1))
printf("No solution\n");
else
{
printf("\n\nSolution\n\n");
printf("(Position) i S\n");
printf("------------------\n");
for (i=m;i>0;i-=S[C[i][0]])
printf(" %3d %3d\n",C[i][0],S[C[i][0]]);
}
}
This will output the following
i S
-------
0 0
1 1
2 3
3 4
4 6
5 7
6 10
7 25
i C
-------
0 0
1 1
2 -1
3 2
4 2
5 3
6 4
7 3
8 3
9 4
10 4
11 4
12 5
13 4
14 4
15 5
16 5
17 5
18 5
19 6
20 5
21 5
22 6
23 6
24 6
25 6
Solution
(Position) i S
------------------
6 10
5 7
3 4
2 3
1 1
Program ended with exit code: 0
My problem is that I can only output one solution, and that is the solution that needs the smaller values and goes up to 25, so when 25 is used it isn't in the solution. The C array in the code is a 2-D array, since I thought I could maybe do another backtrace while computing the first one? I couldn't figure out how to do so, so I left C[i][0] fixed to the first column, just to demonstrate a single solution. Any tips in the right direction would be greatly appreciated. I found a solution using Python, but the problem is solved recursively, which I don't think helps me, but that code is here.
Thanks for all the help in advance.
I did not fully understand your code. But here is a C code which finds all the subsets that sum to target.
#include <stdio.h>
int a[] = { 0, 1, 3, 4, 6, 7, 10, 25 }; //-- notice that the input array is zero indexed
int n = 7;
int target = 25;
int dp[8][26];
int solutions[1 << 7][8]; //-- notice that the number of subsets could be exponential in the length of the input array a.
int sz[1 << 7]; //-- sz[i] is the length of subset solutions[i]
int cnt = 0; //-- number of subsets
void copy(int srcIdx, int dstIdx){
int i;
for (i = 0; i < sz[srcIdx]; i++)
solutions[dstIdx][i] = solutions[srcIdx][i];
sz[dstIdx] = sz[srcIdx];
}
//-- i, and j are indices of dp array
//-- idx is the index of the current subset in the solution array
void buildSolutions(int i, int j, int idx){
if (i == 0 || j == 0) return; // no more elements to add to the current subset
if (dp[i - 1][j] && dp[i - 1][j - a[i]]){ // we have two branches
cnt++; // increase the number of total subsets
copy(idx, cnt); // copy the current subset to the new subset. The new subset does not include a[i]
buildSolutions(i - 1, j, cnt); //find the remaining elements of the new subset
solutions[idx][sz[idx]] = a[i]; // include a[i] in the current subset
sz[idx]++; // increase the size of the current subset
buildSolutions(i - 1, j - a[i], idx); // calculate the remaining of the current subset
}
else if (dp[i - 1][j - a[i]]){ // we only have one branch
solutions[idx][sz[idx]] = a[i]; // add a[i] to the current subset
sz[idx]++;
buildSolutions(i - 1, j - a[i], idx); // calculate the remaining of the current subset
}
else buildSolutions(i - 1, j, idx); // a[i] is not part of the current subset
}
int main(){
int i, j;
// initialize dp array to 0
for (i = 0; i <= n; i++)
for (j = 0; j <= target; j++) dp[i][j] = 0;
//-- filling the dp array
for (i = 0; i <= n; i++)
dp[i][0] = 1;
for (i = 1; i <= n; i++){
for (j = 1; j <= target; j++){
if (j < a[i])
dp[i][j] = dp[i - 1][j];
else
dp[i][j] = dp[i - 1][j] || dp[i - 1][j - a[i]];
}
}
//-- building all the solutions
for (i = 0; i < sizeof(sz); i++) sz[i] = 0; //-- initializing the sz array to 0
buildSolutions(n, target, 0);
//-- printing all the subsets
for (i = 0; i <= cnt; i++){
for (j = 0; j < sz[i]; j++){
printf("%d ", solutions[i][j]);
}
printf("\n");
}
}
If you have any questions about the code, do not hesitate to ask.

A bug on bubble sorting

I want to sort a 2*n matrix, n is given in the input. Make a program to output a matrix. Here is the requirement:
the first column MUST be sorted in ASC, and
the second column in DESC if possible.
For example, let n = 5, and the matrix is
3 4
1 2
3 5
1 6
7 3
The result should be
1 6
1 2
3 5
3 4
7 3
So I write down the code like this. First line input the value n, and the following lines like above.
#include <stdio.h>
#define TWO_16 65536
#define TWO_15 32768
int v[100000][2];
int z[100000];
int vec[100000];
int n;
int main()
{
int i, j;
scanf ("%d", &n); // give the value of n;
for (i = 1; i <= n; i++) // filling the matrix;
{
scanf ("%d%d", &v[i][0], &v[i][1]);
z[i] = TWO_16 * v[i][0] + TWO_15 - v[i][1];
vec[i] = i;
}
for (i = 1; i <= n; i++)
for (j = 1; j <= i; j++)
{
if (z[j] > z[i])
{
int t = vec[i];
vec[i] = vec[j];
vec[j] = t;
}
}
for (i = 1; i <= n; i++) // output the matrix
printf("%d %d\n",v[vec[i]][0],v[vec[i]][1]);
return 0;
}
But in gcc, the output is
1 6
3 5
3 4
1 2
7 3
What's more, when the first line is changed to "1 2" and the second is changed to "3 4" in input, the result also changed.
What's the problem of my code?
Additional information:
I use z[] because I use a function that satisfy the requirement of this problem, so I can simply sort them. And vec[] stores the original index, because moving arrays may cost lots of time. So v[vec[i]][0] means the 'new' array's item i.
Note that v[0] is NOT used. n is less than 100000, not equal.
You are comparing values stored in z[], but swapping elements of vec.
So when in the begginig you have:
i vec z
------------------
1 1 z[1]
2 2 z[2]
3 3 z[3]
...
After for e.g. swapping 2 with 3
i vec z
------------------
1 1 z[1]
2 3 z[2]
3 2 z[3]
...
you will have improper mapping between vec and z.
So in another iteration you will again compare z[2] with z[3] and again you will have to swap elements of vec. That's why you should at least also swap elements of z or index elements of z using elements of vec
i vec z
------------------
1 1 z[vec[1]] = z[1]
2 3 z[vec[2]] = z[3]
3 2 z[vec[3]] = z[2]
...
Adding this should do the trick
...
int t = vec[i];
vec[i] = vec[j];
vec[j] = t;
//Add this also when swapping vec
t = z[i];
z[i] = z[j];
z[j] = t;
...
Array index start with 0, so your for cicles must start from 0
if (z[j] > z[i]): you want to sort v but you are comparing z and sorting vec. By sorting vec and comparing z bubble sort cannot work. You must use the same array.

Resources