Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
When I'm running the program, the 2nd and the 3rd values being printed are garbage values, and I don't know why. I think it should be the numbers I've entered.
The code:
int main()
{
int a = 0, b = 0;
int * students = NULL;
int * size = &a;
int * studentscount = &b;
func1(students, size, studentscount);
return 0;
}
#include "Source.h"
int checkAllocation(void * ptr)
{
if (ptr == NULL)
return 1;
return 0;
}
int * doubleArr(int *arr, int size)
{
int * newArr = (int*)malloc(size * sizeof(int));
checkAllocation(newArr);
for (int i = 0; i < size; i++)
newArr[i] = arr[i];
size *= 2;
newArr = (int*)realloc(newArr, size);
checkAllocation(newArr);
free(arr);
return (newArr);
}
void func1(int *students, int *size, int *studentscount)
{
int num;
students = (int *)malloc(sizeof(int) * 2);
checkAllocation(students);
*(studentscount) = 0;
*(size) = 2;
printf("Enter students, to end enter a negative number.\n");
do
{
printf("Enter student number %d: ", *(studentscount)+1);
scanf("%d", &num);
if (num >= 0)
{
*(students + *(studentscount)) = num;
*(studentscount) += 1;
}
if (*(studentscount) == (*size))
{
students = doubleArr(students, *(size));
*(size) *= 2;
}
} while (num >= 0);
printf("******************\nArray size: %d\nNumber of students: %d\n******************\n", *(size), *(studentscount));
for (int i = 0; i < *(studentscount); i++)
printf("student #%d: %d\n", i + 1, *(students + i));
free(students);
}
Any suggestions to make the code print the values I entered and not the garbage values?
There are some issues you should probably work on, but the reason for garbage is very likely statement realloc(newArr, size), which considers only the count but not the size of datatype int. Hence, instead of doubling the array size, you are actually decreasing it; Consequently, realloc might give you back a different memory block where only portions of the previous one has been taken over; or some parts of the memory you have written values to have gone invalid. Anyway, you have a good chance here to loose your entered values. So - as pointed out by bluepixy, statement realloc(newArr, size*sizeof(int)) should solve the main problem.
Note further that statement realloc, when allocating memory at a different place, takes over the content of the former memory block and (in this case) frees the former block (cf. cppreference of realloc). So there is no need to transfer the data manually, there is particularly no need to first malloc and then realloc, and there is consequently no need for a separate free at the end. So the code of doubleArr could actually look like the following.
int * doubleArr(int *arr, int size) {
return realloc(arr,size*2*sizeof(int));
}
Related
I have this code so far. It works and does what I want it to. I'm wondering if I could make it better. I do not really care for user input or any other "finish touches," just want to make the code more efficient and maybe more useful for future projects.
Excessive comments are for my personal use, I find it easier to read when I go back to old projects for references and what not.
Thanks!
#include<stdio.h>
#include<stdlib.h>
void fabonacci(int * fibArr,int numberOfSeries){
int n;
//allocate memory size
fibArr = malloc (sizeof(int) * numberOfSeries);
//first val, fib = 0
*fibArr = 0;//100
fibArr++;
//second val, fib = 1
*fibArr = 1;//104
fibArr++;
//printing first two fib values 0 and 1
printf("%i\n%i\n", *(fibArr- 2),*(fibArr- 1));
//loop for fib arr
for(n=0;n<numberOfSeries -2;n++,fibArr++){
//108 looking back at 104 looking back at 100
//112 looking back at 108 looking back at 104
*fibArr = *(fibArr-1) + *(fibArr -2);
//printing fib arr
printf("%i\n", *fibArr);
}
}
int main(){
//can implm user input if want
int n = 10;
int *fib;
//calling
fabonacci(fib,n);
}
Your code is halfway between two possible interpretations and I can't tell which one you meant. If you want fibonacci(n) to just give the nth number and not have any external side effects, you should write it as follows:
int fibonacci(int n) {
int lo, hi;
lo = 0;
hi = 1;
while(n-- > 0) {
int tmp = hi;
lo = hi;
hi = lo + tmp;
}
return lo;
}
You need no mallocs or frees because this takes constant, stack-allocated space.
If you want, instead, to store the entire sequence in memory as you compute it, you may as well require that the memory already be allocated, because this allows the caller to control where the numbers go.
// n < 0 => undefined behavior
// not enough space allocated for (n + 1) ints in res => undefined behavior
void fibonacci(int *res, int n) {
res[0] = 0;
if(n == 0) { return; }
res[1] = 1;
if(n == 1) { return; }
for(int i = 2; i <= n; i++) {
res[i] = res[i-1] + res[i-2];
}
}
It is now the caller's job to allocate memory:
int main(){
int fib[10]; // room for F_0 to F_9
fibonacci(fib, 9); // fill up to F_9
int n = ...; // some unknown number
int *fib2 = malloc(sizeof(int) * (n + 2)); // room for (n + 2) values
if(fib2 == NULL) { /* error handling */ }
fibonacci(fib2 + 1, n); // leave 1 space at the start for other purposes.
// e.g. you may want to store the length into the first element
fib2[0] = n + 1;
// this fibonacci is more flexible than before
// remember to free it
free(fib2);
}
And you can wrap this to allocate space itself while still leaving the more flexible version around:
int *fibonacci_alloc(int n) {
int *fib = malloc(sizeof(int) * (n + 1));
if(fib == NULL) { return NULL; }
fibonacci(fib, n);
return fib;
}
One way to improve the code is to let the caller create the array, and pass the array to the fibonacci function. That eliminates the need for fibonacci to allocate memory. Note that the caller can allocate/free if desired, or the caller can just declare an array.
The other improvement is to use array notation inside of the fibonacci function. You may be thinking that the pointer solution has better performance. It doesn't matter. The maximum value for n is 47 before you overflow a 32-bit int, so n is not nearly big enough for performance to be a consideration.
Finally, the fibonacci function should protect itself from bad values of n. For example, if n is 1, then the function should put a 0 in the first array entry, and not touch any other entries.
#include <stdio.h>
void fibonacci(int *array, int length)
{
if (length > 0)
array[0] = 0;
if (length > 1)
array[1] = 1;
for (int i = 2; i < length; i++)
array[i] = array[i-1] + array[i-2];
}
int main(void)
{
int fib[47];
int n = sizeof(fib) / sizeof(fib[0]);
fibonacci(fib, n);
for (int i = 0; i < n; i++)
printf("fib[%d] = %d\n", i, fib[i]);
}
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
int main()
{
int a,query,in,n,b[n],sum[a];
sum[1]=0;
scanf("%d",&query);
for(a=1;a<=query;a++)
{
scanf("%d",&in);
for(n=1;n<=in;n++)
{
b[n]=1+7*(n-1)+6*(n-1)*(n-2)+(n-1)*(n-2)*(n-3);
sum[a]=sum[a]+b[n];
}
}
for(a=1;a<=query;a++)
{
printf("%d\n",sum[a]);
}
return 0;
}
I have made this code which is running in terminal .
But in hacker rank it is showing
Input (stdin)
2
2
5
Your Output (stdout)
~ no response on stdout ~
Expected Output
9
225
Compiler Message
Segmentation Fault
Now what should I do to solve the problem .
Your variables are uninitialized. As a result your program invokes Undefined Behavior.
For example you do not initialize n, but you then declare int b[n]. What is the size of array b? Nobody really knows, since n has a garbage value.
Start by figuring out what the values of your variables should be, and then start coding.
Array indexing starts from 0, thus your for loops are not looking good.
Change this:
for(a=1;a<=query;a++)
to this:
for (a = 0; a < query; a++)
int main()
{
int a, query, in, n, *b, *sum;
scanf("%d",&query);
sum = malloc(query * sizeof(int));
/* do some checks if the malloc was successful */
for(a = 0; a < query; a++)
{
scanf("%d",&in) ; /* you should check if scan has returned 1 */
b = malloc(in * sizeof(int)); /* and again check against any allocation errors */
for(n = 0; n < in; n++)
{
b[n] = 1+7*(n)+6*(n)*(n-1)+(n)*(n-1)*(n-2);
sum[a] = sum[a] + b[n];
}
free(b);
}
/* the rest */
In int a,query,in,n,b[n],sum[a];, the value of a is not initialised and is having garbage value which could be anything. This value is used as the size of the variable length array sum. So the size of the array could be anything which is probably not what you want.
a could be 0 in which case sum is an array of size 0 which will in turn make sum[1] incorrect (it would be undefined behavior).
The same applies to n and b[n].
In the nested for loop, with sum[a]=sum[a]+b[n]; you are using sum[a] which has not been initialised. It has garbage value and the result is indeterminate.
If you wanted all elements of sum to be initialised with 0, you can do
int sum[20]={0};
at the time of declaring it.
The same goes for b[n]=1+7*(n-1)+6*(n-1)*(n-2)+(n-1)*(n-2)*(n-3); as well.
And array indexing starts at 0.
Perhaps you could use the loops like
for (a = 0; a < query; a++) {
instead of
for (a = 1; a <= query; a++)
If you choose the starting index as 0, the inner nested loop should be like
for(n=0;n<in;n++)
{
//b[n]=1+7*(n-1)+6*(n-1)*(n-2)+(n-1)*(n-2)*(n-3);
b[n]=1+7*(n)+6*(n)*(n-1)+(n)*(n-1)*(n-2);
sum[a]=sum[a]+b[n];
}
See demo.
Your problem is in this line:
int a,query,in,n,b[n],sum[a];
What is the meaning of b[n]? And of sum[a]? Assuming that you would like to have a language with magically growing arrays, C is a bad choice.
In C language arrays are a structure with size known at compile time. Anyway, let's assume that your compiler supports the horrible hack of variable-length arrays. You can do this:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main(void) {
int a, query, in , n;
scanf("%d", &query);
int sum[query+1];
for (a = 1; a <= query; a++) {
sum[a] = 0;
scanf("%d", &in);
int b[in+1];
for (n = 1; n <= in ; n++) {
b[n] = 1 + 7 * (n - 1) + 6 * (n - 1) * (n - 2) + (n - 1) * (n - 2) * (n - 3);
sum[a] = sum[a] + b[n];
}
}
for (a = 1; a <= query; a++) {
printf("%d\n", sum[a]);
}
return 0;
}
Note the changes: first you need to know the size of the array, then you can allocate it. Moreover, I increased the size of the array in order to support your choice of starting from 1. Lastly I also zeroed the initial value for sum array.
Alright so I'm sure this is pretty simple and all but I have no idea how to use functions. Up until now I was able to get by with everything in main but now I'm required to use functions for just about anything I do. So from my code below, how do I read in (or w.e. the proper terminology is) a function from main?
EDIT: To clarify to everyone, my question is how can I access the array I returned in main?
Code below takes in the test scores from different amount of students specified by user input.
#include <stdio.h>
#include <stdlib.h>
int** getTestData();
int main (){
///this is where I'm lost..
int (*a)[];
a = getTestData();
}
int** getTestData(){
int students, numberOfTests, testScores, i, j;
int** testScoreBank;
// reads in studens
scanf("%i", &students);
testScoreBank = (int**) malloc (sizeof(int)*students);
for(i=0; i<students;i++){
//how many number of tests there are
scanf("%i", &numberOfTests);
testScoreBank = (int*) malloc (sizeof(int)*numberOfTests);
for(j=0; j<numberOfTests; j++){
//the tests themselves
scanf("%i", &testScores);
testScoreBank[i][j] = testScores;
}
}
return testScoreBank;
}
Ok, here is an example with global variables, how to fill your array inside a function, and access it in main()
#include <stdio.h>
#include <stdlib.h>
int** getTestData();
int numberOfStudents;
int* studentTestSizes;
int main (){
int** testScoresBank = getTestData();
int i, j;
for (i = 0; i < numberOfStudents; i++) {
for (j = 0; j < studentTestSizes[i]; j++) {
printf("%d", testScoresBank[i][j]);
}
}
return 0;
}
int** getTestData() {
int** testScoreBank;
// reads in studens
scanf("%d", &numberOfStudents);
testScoreBank = malloc(sizeof(int*) * numberOfStudents);
studentTestSizes = malloc(sizeof(int) * numberOfStudents);
int i;
for (i = 0; i < numberOfStudents; i++) {
//how many number of tests there are
scanf("%d", studentTestSizes + i);
testScoreBank[i] = malloc(sizeof(int) * studentTestSizes[i]);
int j;
for (j = 0; j < studentTestSizes[i]; j++) {
//the tests themselves
int testScore;
scanf("%d", &testScore);
testScoreBank[i][j] = testScore;
}
}
return testScoreBank;
}
alternative for global variables is to make global variables local and pass pointers to them to getTestData function, example is here:
#include <stdio.h>
#include <stdlib.h>
int** getTestData();
int main (){
int numberOfStudents; // those variables are now here
int* studentTestSizes;
int** testScoresBank = getTestData(&numberOfStudents, &studentTestSizes); // passing the pointers so we can change values that are pointed to
int i, j;
for (i = 0; i < numberOfStudents; i++) {
for (j = 0; j < studentTestSizes[i]; j++) {
printf("%d", testScoresBank[i][j]);
}
}
return 0;
}
int** getTestData(int* numberOfStudentsPtr, int** studentTestSizesPtr) {
int** testScoreBank;
// reads in studens
scanf("%d", numberOfStudentsPtr); // it's already a pointer so we must omit &
int numberOfStudents = *numberOfStudentsPtr; // will be constant from now on
testScoreBank = malloc(sizeof(int*) * numberOfStudents);
*studentTestSizesPtr = malloc(sizeof(int) * numberOfStudents);
int* studentTestSizes = *studentTestSizesPtr;
int i;
for (i = 0; i < numberOfStudents; i++) {
//how many number of tests there are
scanf("%d", studentTestSizes + i);
testScoreBank[i] = malloc(sizeof(int) * studentTestSizes[i]);
int j;
for (j = 0; j < studentTestSizes[i]; j++) {
//the tests themselves
int testScore;
scanf("%d", &testScore);
testScoreBank[i][j] = testScore;
}
}
return testScoreBank;
}
In addition to the other answers, you have a number of subtle issues to consider. Two are just general helpful tips for writing/debugging your beginning applications (1) if you are taking user input, prompt for it - you can strip the prompts later, but it is much easier to enter data in response to an informative prompt than it is to wonder what the blinking cursor is doing down there -- did to program freeze?; (2) provide adequate spacing in your code - you can always delete blank lines later, but separating your code into functional blocks of logic will help you keep your logic straight.
When allocating space for numeric arrays, it is good practice to initialize all values to 0 as part of (or after) allocation. This will absolutely prevent the inadvertent read from uninitialized space. You can allocate and initialize all at once by using calloc instead of malloc. This also provides benefits when allocating arrays of pointers to char* as well.
While you may have fixed your allocation, you still have the glaring problem of knowing "How many students and tests do I have?". Here is where passing an additional pointer for the number of students and storing the number of tests in an additional array index is required. (there are other ways to do it, this is just efficient). You can declare the the number of students in main passing its pointer to getTestData. Updates to the value of students in getTestData are then available in main. But, "What if the students have a different number of scores? What then?" You are already filling an array of integers, if you just store the number of tests for the student as the first integer, you make that value available no matter where you pass the array.
Finally, you need to pay closer attention to your choice of variable types. For indexes and lengths that can never be negative, unsigned or size_t is a better choice and will allow the compiler to point out instances where you may be using that value incorrectly.
You need to validate each time you allocate memory with malloc or calloc, and you are responsible to keeping track of the address to the start of each allocation and freeing it when it is no longer needed.
That said, here is one approach to making it all work. Try it. Let me know if you have any questions:
#include <stdio.h>
#include <stdlib.h>
int **getTestData (size_t *students);
int main (void) {
int **a = NULL;
int j;
size_t i, s = 0;
if (!(a = getTestData (&s))) {
fprintf (stderr, "error: getTestData failed to return student data.\n");
return 1;
}
/* print student data */
putchar ('\n');
for (i = 0; i < s; i++)
{
printf (" Student[%2zu] scores : ", i+1);
/* adjust indexes to read no. of tests */
for (j = 1; j < a[i][0]; j++)
printf (" %3d", a[i][j]);
putchar ('\n');
}
putchar ('\n');
/* free allocated memory */
for (i = 0; i < s; i++)
free (a[i]);
free (a);
return 0;
}
int **getTestData (size_t *students)
{
size_t tests, testScores, s, t;
int **testScoreBank;
/* reads in students */
printf ("\n No. of students: ");
scanf ("%zu", students);
if (!(testScoreBank = calloc (*students, sizeof *testScoreBank))) {
fprintf (stderr, "%s() error: virtual memory exhausted.\n", __func__);
return NULL;
}
for (s = 0; s < *students; s++)
{
/* how many number of tests there are */
printf ("\n No. of scores for student[%2zu]: ", s+1);
scanf ("%zu", &tests);
tests += 1; /* allow space for number of tests as [s][0] */
testScoreBank[s] = calloc (tests, sizeof **testScoreBank);
testScoreBank[s][0] = tests;
for (t = 1; t < tests; t++)
{
/* the tests themselves */
printf (" student[%2zu]-test[%2zu] score: ", s+1, t);
scanf ("%zu", &testScores);
testScoreBank[s][t] = testScores;
}
}
return testScoreBank;
}
Use/Output
$ ./bin/testdata
No. of students: 2
No. of scores for student[ 1]: 3
student[ 1]-test[ 1] score: 88
student[ 1]-test[ 2] score: 91
student[ 1]-test[ 3] score: 82
No. of scores for student[ 2]: 4
student[ 2]-test[ 1] score: 93
student[ 2]-test[ 2] score: 95
student[ 2]-test[ 3] score: 96
student[ 2]-test[ 4] score: 91
Student[ 1] scores : 88 91 82
Student[ 2] scores : 93 95 96 91
(I assume this is just a snippet of your overall code and there's more to it or else you might have other problems)
Anyway you should be able to set up your 2D array with the following modifications:
scanf("%i", &students);
testScoreBank = malloc (sizeof(int*)*students); //sizeof int* instead of sizeof int.
for(i=0; i<students;i++)
{
scanf("%i", &numberOfTests);
*(testScoreBank + i)= malloc (sizeof(int)*numberOfTests); //You forgot the * operator on testScoreBank and to iterate through it.
for(j=0; j<numberOfTests; j++)
{
scanf("%i", &testScores);
testScoreBank[i][j] = testScores;
}
}
I have the input as array A = [ 2,3,4,1]
The output is simply all possible permutation from elements in A which can be done by single transposition (single flip of two neighbouring elements) operation. So the output is :
[3,2,4,1],[ 2,4,3,1],[2,3,1,4],[1,3,4,2]
Circular transpositioning is allowed. Hence [2,3,4,1] ==> [1,3,4,2] is allowed and a valid output.
How to do it in C?
EDIT
In python, it would be done as follows:
def Transpose(alist):
leveloutput = []
n = len(alist)
for i in range(n):
x=alist[:]
x[i],x[(i+1)%n] = x[(i+1)%n],x[i]
leveloutput.append(x)
return leveloutput
This solution uses dynamic memory allocation, this way you can do it for an array of size size.
int *swapvalues(const int *const array, size_t size, int left, int right)
{
int *output;
int sotred;
output = malloc(size * sizeof(int));
if (output == NULL) /* check for success */
return NULL;
/* copy the original values into the new array */
memcpy(output, array, size * sizeof(int));
/* swap the requested values */
sotred = output[left];
output[left] = output[right];
output[right] = sotred;
return output;
}
int **transpose(const int *const array, size_t size)
{
int **output;
int i;
int j;
/* generate a swapped copy of the array. */
output = malloc(size * sizeof(int *));
if (output == NULL) /* check success */
return NULL;
j = 0;
for (i = 0 ; i < size - 1 ; ++i)
{
/* allocate space for `size` ints */
output[i] = swapvalues(array, size, j, 1 + j);
if (output[i] == NULL)
goto cleanup;
/* in the next iteration swap the next two values */
j += 1;
}
/* do the same to the first and last element now */
output[i] = swapvalues(array, size, 0, size - 1);
if (output[i] == NULL)
goto cleanup;
return output;
cleanup: /* some malloc call returned NULL, clean up and exit. */
if (output == NULL)
return NULL;
for (j = i ; j >= 0 ; j--)
free(output[j]);
free(output);
return NULL;
}
int main()
{
int array[4] = {2, 3, 4, 1};
int i;
int **permutations = transpose(array, sizeof(array) / sizeof(array[0]));
if (permutations != NULL)
{
for (i = 0 ; i < 4 ; ++i)
{
int j;
fprintf(stderr, "[ ");
for (j = 0 ; j < 4 ; ++j)
{
fprintf(stderr, "%d ", permutations[i][j]);
}
fprintf(stderr, "] ");
free(permutations[i]);
}
fprintf(stderr, "\n");
}
free(permutations);
return 0;
}
Although some people think goto is evil, this is a very nice use for it, don't use it to control the flow of your program (for instance to create a loop), that is confusing. But for the exit point of a function that has to do several things before returning, it think it's actually a nice use, it's my opinion, for me it makes the code easier to understand, I might be wrong.
Have a look at this code I have written with an example :
void transpose() {
int arr[] = {3, 5, 8, 1};
int l = sizeof (arr) / sizeof (arr[0]);
int i, j, k;
for (i = 0; i < l; i++) {
j = (i + 1) % l;
int copy[l];
for (k = 0; k < l; k++)
copy[k] = arr[k];
int t = copy[i];
copy[i] = copy[j];
copy[j] = t;
printf("{%d, %d, %d, %d}\n", copy[0], copy[1], copy[2], copy[3]);
}
}
Sample Output :
{5, 3, 8, 1}
{3, 8, 5, 1}
{3, 5, 1, 8}
{1, 5, 8, 3}
A few notes:
a single memory block is preferred to, say, an array of pointers because of better locality and less heap fragmentation;
the cyclic transposition is only one, it can be done separately, thus avoiding the overhead of the modulo operator in each iteration.
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *single_transposition(const int *a, unsigned int n) {
// Output size is known, can use a single allocation
int *out = malloc(n * n * sizeof(int));
// Perform the non-cyclic transpositions
int *dst = out;
for (int i = 0; i < n - 1; ++i) {
memcpy(dst, a, n * sizeof (int));
int t = dst[i];
dst[i] = dst[i + 1];
dst[i + 1] = t;
dst += n;
}
// Perform the cyclic transposition, no need to impose the overhead
// of the modulo operation in each of the above iterations.
memcpy(dst, a, n * sizeof (int));
int t = dst[0];
dst[0] = dst[n-1];
dst[n-1] = t;
return out;
}
int main() {include
int a[] = { 2, 3, 4, 1 };
const unsigned int n = sizeof a / sizeof a[0];
int *b = single_transposition(a, n);
for (int i = 0; i < n * n; ++i)
printf("%d%c", b[i], (i % n) == n - 1 ? '\n' : ' ');
free(b);
}
There are many ways to tackle this problem, and most important questions are: how you're going to consume the output and how variable is the size of the array. You've already said the array is going to be very large, therefore I assume memory, not CPU will be the biggest bottleneck here.
If output is going to be used only few times (especially just once), it'll may be best to use functional approach: generate every transposition on the fly, and never have more than one in memory at a time. For this approach many high level languages would work as well as (maybe sometimes even better than) C.
If size of the array is fixed, or semi-fixed (eg few sizes known at compile-time), you can define structures, using C++ templates at best.
If size is dynamic and you still want to have every transposition in memory then you should allocate one huge memory block and treat it as contiguous array of arrays. This is very simple and straightforward on machine level. Unfortunately it's best tackled using pointer arithmetic, one feature of C/C++ that is renowned for being difficult to understand. (It isn't if you learn C from basics, but people jumping down from high level languages have proven track record of getting it completely wrong first time)
Other approach is to have big array of pointers to smaller arrays, which results in double pointer, the ** which is even more terrifying to newcomers.
Sorry for long post which is not a real answer, but IMHO there are too many questions left open for choosing the best solution and I feel you need bit more C basic knowledge to manage them on your own.
/edit:
As other solutions are already posted, here's a solution with minimum memory footprint. This is the most limiting approach, it uses same one buffer over and over, and you must be sure that your code is finished with first transposition before moving on to the next one. On the bright side, it'll still work just fine when other solutions would require terabyte of memory. It's also so undemanding that it might be as well implemented with a high level language. I insisted on using C++ in case you would like to have more than one matrix at a time (eg comparing them OR running several threads concurrently).
#define NO_TRANSPOSITION -1
class Transposable1dMatrix
{
private:
int * m_pMatrix;
int m_iMatrixSize;
int m_iCurrTransposition;
//transposition N means that elements N and N+1 are swapped
//transpostion -1 means no transposition
//transposition (size-1) means cyclic transpostion
//as usual in C (size-1) is the last valid index
public:
Transposable1dMatrix(int MatrixSize)
{
m_iMatrixSize = MatrixSize;
m_pMatrix = new int[m_iMatrixSize];
m_iCurrTransposition = NO_TRANSPOSITION;
}
int* GetCurrentMatrix()
{
return m_pMatrix;
}
bool IsTransposed()
{
return m_iCurrTransposition != NO_TRANSPOSITION;
}
void ReturnToOriginal()
{
if(!IsTransposed())//already in original state, nothing to do here
return;
//apply same transpostion again to go back to original
TransposeInternal(m_iCurrTransposition);
m_iCurrTransposition = NO_TRANSPOSITION;
}
void TransposeTo(int TranspositionIndex)
{
if(IsTransposed())
ReturnToOriginal();
TransposeInternal(TranspositionIndex);
m_iCurrTransposition = TranspositionIndex;
}
private:
void TransposeInternal(int TranspositionIndex)
{
int Swap1 = TranspositionIndex;
int Swap2 = TranspositionIndex+1;
if(Swap2 == m_iMatrixSize)
Swap2 = 0;//this is the cyclic one
int tmp = m_pMatrix[Swap1];
m_pMatrix[Swap1] = m_pMatrix[Swap2];
m_pMatrix[Swap2] = tmp;
}
};
void main(void)
{
int arr[] = {2, 3, 4, 1};
int size = 4;
//allocate
Transposable1dMatrix* test = new Transposable1dMatrix(size);
//fill data
memcpy(test->GetCurrentMatrix(), arr, size * sizeof (int));
//run test
for(int x = 0; x<size;x++)
{
test->TransposeTo(x);
int* copy = test->GetCurrentMatrix();
printf("{%d, %d, %d, %d}\n", copy[0], copy[1], copy[2], copy[3]);
}
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 8 years ago.
Improve this question
#include <conf.h>
#include <kernel.h>
#include <stdio.h>
#define MAX_ITEMS 50
typedef long double LD;
int run_solve_equ();
void xmain(){
int pid;
pid = create(run_solve_equ, 20*INITSTK, INITPRIO, "B", 0);
resume(pid);
}
int solve_equ(LD b, int n, LD a[], int choosen[] ){
if ( n == 1 )
if (a[0] == b) {
choosen[0] = 1;
return 1;
} /* if */
else if (b == 0) {
choosen[0] = 0;
return 1;
} /* else if*/
else {
choosen[0] = 0;
return 0;
}
else /* n > 1 */
if (solve_equ(b, n-1, a, choosen)) {
choosen[n-1] = 0;
return 1;
} /* if */
else if (solve_equ(b - a[n-1],n-1, a, choosen)) {
choosen[n-1] = 1;
return 1;
} /* else if */
else{
choosen[n-1] = 0;
return 0;
}
} /* solve_equ */
LD a[MAX_ITEMS];
int choosen[MAX_ITEMS];
char pstr[200];
extern long int tod;
int run_solve_equ() {
int n, i, result;
LD b, sum;
printf("How many numbers? No more than %d:", MAX_ITEMS );
scanf("%d",&n);
puts("Enter b:");
scanf("%Lf",&b);
a[0] = 1;
for (i = 1; i < n; i++)
a[i] = a[i-1]*2;
result = 0;
sprintf(pstr, "time = %ld\n", tod);
printf(pstr);
result = solve_equ(b,n, a, choosen);
sprintf(pstr, "time = %ld\n", tod);
printf(pstr);
sprintf(pstr, "Solution for b = %Lf, n = %d, value = %d :\n", b,
n,result);
printf(pstr);
printf("\ni:\n");
for (i = 0; i < n; i++) {
sprintf(pstr, "%-16d",i);
printf(pstr);
} // for
printf("\na[i]:\n");
for (i = 0; i < n; i++) {
sprintf(pstr, "%-16.1Lf", a[i]);
printf(pstr);
} // for
printf("\nchoosen[i]:\n");
for (i = 0; i < n; i++) {
sprintf(pstr, "%-16d", choosen[i]);
printf(pstr);
} // for
printf("\n");
sum = 0;
for (i = 0; i < n; i++)
if (choosen[i]) {
sum += a[i];
sprintf(pstr, " + %-16.1Lf", a[i]);
printf(pstr);
} /* if */
sprintf(pstr, " = %-16.1Lf\n", sum);
printf(pstr);
return 0;
}
I need to change this program so the search will be "parallel" by two processes:
Each will search a n-1, the first user on a [n-1] and the other not.
the problem is to find a number in the array that all the number togother are equal to another number b !
Not an answer, but I do have some constructive comments for you.
Reading the above code hurts. It hurts my eyes and it hurts my brain. Why?
Variable Names are non-descriptive an often one letter (outside of I). b, n, a - I don't know what these are at a glance and I don't want to find out by understanding what you wrote. I bet you won't understand what you wrote next week either. Do everyone a favor and make the names better.
Please, please use a bit of white space between your "code thoughts". Your code looks like one long run-on sentence that also hides what it does.
Don't mix braced and non-braced code - especially when your indentation is not consistent. It is very, very difficult to follow your if logic as-is right now. Go ahead and waste a few bytes of hard disk space and perhaps .25 seconds adding braces or at least fixing your indents.
Write useful comments. /* if */ is a terrible comment and you do similar stuff everywhere. I know what an if is, but perhaps a quick not of what you are checking?
Don't mix globals and extern defines in the middle of your code. Keep them together and it makes it easier to remember what is global and what is not. This is the most minor offense though and others may disagree.
Anyways, a bit off topic for your question, which will more than likely close as you've put little effort into solving it yourself, but my comments may help you with future coding projects and will at least make it easier for others to help you going forward.