I would like to receive a running sum of an array, 'Array.' But, I am having difficulty trying to create a for loop that can iterate through this array and add through the values in Array. Any ideas would be appreciated.
#include <stdio.h>
void cSum (int Array[], int length);
int main (void) {
int Array[5]={1,-1,92,5,432};
int length=5;
printSum(Array, length);
}
void cSum (int Array[], int length) {
int i;
int sum[length];
int running=0;
int product[length];
for (i=0; i<length; i++) {
//Difficulty trying to get the cummulative sum
sum[i]=Array[i];
running=running+1
}
printf("sum: ");
for (i=0; i<length; i++) {
printf("%d ", sum[i]);
}
}
A simple approach is to set up the first element of sum, and then proceed with the remaining elements in the loop:
sum[0] = array[0];
for (i = 1; i < length; ++i){
sum[i] = sum[i - 1] + array[i];
}
I've taken the liberty of renaming Array to the less idiosyncratic array. Consider also using a size_t type for the indexing variable i rather than an int.
Related
I am working on an old exam and the problems states that a given array (int zahlen[]={1,4,5,1,5,7,9,2,3,4}) has values that are the same. The task is to replace the values that are the same with '-1'. After each replacement, a given variable, count, has to be increased by one.
My problem is that the variable count is two-times higher than normal (In this case there are only 3 of the same numbers and the variable shows 6.)
The function is called array_unique. I am would be grateful for a brief explanation of my mistake.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
system("chcp 1252");
int zahlen[]={1,4,5,1,5,7,9,2,3,4};
int len = sizeof(zahlen)/sizeof(int);
int erg = array_unique(zahlen,len);
printf("Es wurden %d doppelte Zahlen gelöscht: \n",erg);
printf("Das Array hat nun folgende Werte: ");
printArrayUnique(zahlen,len);
return 0;
}
void printArrayUnique(int *array, int len){
for(int i=0; i<len; i++){
if(array[i]!=-1){
printf("%d ",array[i]);
}
}
}
int array_unique(int *array, int len){
int count=0;
for(int i=0; i<len;i++){
for(int j=i+1; j<len;j++){
if(array[i]==array[j]){
array[j] = -1;
count++;
}
}
}
return count;
}
I have not figured out any other solution to fix the faulty value of count.
The issue is due to the fact that your are counting duplicates more than once; so, when you have found a duplicate entry, you correctly replace that with -1 but then, later in the loops, you will be (potentially, at least) comparing two or more of those -1 values.
Just add a check that either value is not -1 (along with the test for equality) before incrementing the count variable:
int array_unique(int* array, int len)
{
int count = 0;
for (int i = 0; i < len; i++) {
for (int j = i + 1; j < len; j++) {
if (array[i] == array[j] && array[j] != -1) {
array[j] = -1;
count++;
}
}
}
return count;
}
Note also that, as mentioned in the comments, you really do need declarations of your functions before you use them. Add the following two lines before the main function:
void printArrayUnique(int* array, int len);
int array_unique(int* array, int len);
I'm trying to write a program that sorts an array of size N via a selections sort and then conducts a binary search for a random number in that array and displays the index in which that number is present. I noticed that without my binary search function I begin to get a stack overflow when N is greater than 1e5 and when I try to run the binary search I run into the error "read access violation". I would greatly appreciate any help on this especially considering my N is supposed to be 1e6.
#define N 10
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//function prototypes
void selectionSort(int array[], size_t length);
void swap(int* elementPtr, int* element2Ptr);
void printPass(int array[], size_t length, unsigned int pass, size_t index);
size_t binarySearch(const int b[], int searchKey, size_t low, size_t high);
unsigned long long int counter = 0;
unsigned long long int counter2 = 0;
long long unsigned int counter3 = 0;
int main(void) {
int array[N];
srand(time(NULL));
for (size_t i = 0; i < N; i++) {
array[i] = rand() % 90 + 10; // give each element a value
}
/*
puts("Unsorted array:");
for (size_t i = 0; i < N; i++) { //print the array
printf("%d ", array[i]);
}
puts("{\n");
*/
selectionSort(array, N);
/*
puts("Sorted array:");
for (size_t i = 0; i < N; i++) { //print the array
printf("%d ", array[i]);
}
*/
printf("\nTotal amount of comparisons: %d\n", counter);
printf("Total amount of swaps: %d", counter2);
int value = rand() % N + 1;
int index = binarySearch(array, value, 0, N);
printf("\nThe amount of times the value was compared was: %d\n", counter3);
if (index != -1) {
printf("%d was first found on index %d\n", value, index);
}
else printf("%d was not found on the array\n", value);
}
void selectionSort(int array[], size_t length) {
//loop over length - 1 elements
for (size_t i = 0; i < length - 1; i++) {
size_t smallest = i; //first index of remaining array
//loop to find index of smallest element
for (size_t j = i + 1; j < length; j++) {
counter++;
if (array[j] < array[smallest]) {
smallest = j;
}
}
swap(array + i, array + smallest); //swap smallest element
//printPass(array, length, i + 1, smallest); //output pass
}
}
//function that swaps two elements in the array
void swap(int* elementPtr,int* element2Ptr)
{
counter2++;
int temp;
temp = *elementPtr;
*elementPtr = *element2Ptr;
*element2Ptr = temp;
}
//function that prints a pass of the algorithm
void printPass(int array[], size_t length, unsigned int pass, size_t index) {
printf("After pass %2d: ", pass);
//output elements till selected item
for (size_t i = 0; i < index; i++) {
printf("%d ", array[i]);
}
printf("%d ", array[index]); //indicate swap
//finish outputting array
for (size_t i = index + 1; i < length; i++) {
printf("%d ", array[i]);
}
printf("%s", "\n "); //for alignment
//indicate amount of array that is sorted
for (unsigned int i = 0; i < pass; i++) {
printf("%s", "-- ");
}
puts(""); //add newline
}
size_t binarySearch(const int b[], int searchKey, size_t low, size_t high) {
counter3++;
if (low > high) {
return -1;
}
size_t middle = (low + high) / 2;
if (searchKey == b[middle]) {
return middle;
}
else if (searchKey < b[middle]) {
return binarySearch(b, searchKey, low, middle - 1);
}
else {
return binarySearch(b, searchKey, middle + 1, high);
}
}
For N as big as 1e5 or 1e6, you can't afford allocating it on stack. The size of an int is 4 bytes and so you'll consume 4e5 bytes from stack just for your array.
You will need to dynamically allocate the array and instead of
int array[N];
you should have
int *array = malloc(sizeof(int) * N);
and after you are done with everything, don't forget to
free(array);
Now you should have enough space on stack for the recursive binary search.
UPDATE:
After I've run the code myself, indeed, the binarySearch function always yields segmentation fault. The problem is the type of the parameters, namely size_t. There are cases where high argument from the binarySearch function becomes -1. But because the size_t is an unsigned type, you have an integer underflow, thus high will become maxint. So your condition if (low > high) would never become true. You'll have to change the types of low and high to a signed integer to have the function working.
Still, I suggest going for the dynamic allocation, even though your stack might cope with that.
Even outside of the great answer that was posted, I am seeing other problems with this code. I have issues running it with N = 2, N =5, and N = 10.
I believe you have some problems with passing the variables into your binary search function. I think that you are passing incorrect values that are overflowing and causing all sorts of memory nightmares. This is causing your read access violations.
Do your small cases function appropriately? Despite the suggestions to minimize your footprint. I would double check simple cases are functioning.
My issue is that I am getting segmentation fault (core dumped) each time I try, I have yet to clean up my code, but I am stumped.
I must enter the values in with the compiler e.g "./filename 0 100" whereby 0 is min and 100 is max.
It must then fill the array of 10 elements with random numbers (0-100). I am so close, just can't fathom the main function.
Also, how can I print the array {0,1,2,3} in format "[0,1,2,3]" including the commas, without it looking like "[0,1,2,3, ]"
#include <stdlib.h>
#include <stdio.h>
int getRandom(int min, int max);
void fillArray(int data[], int size, int min, int max);
void printArray(int data[], int size);
int main(int argc, char *argv[]) {
int a;
int b;
if (argc>=3){
a = atoi(argv[1]);
b = atoi(argv[2]);
int arr[10];
printf("\t An array with random values from 0 to 100 \n");
fillArray(arr,10 ,a, b);
printArray(arr, 10);
} else {
printf("Incorrect number of arguments - please call with assignment min max\n");
}
return 0;
}
int getRandom(int min, int max) {
int result = 0;
int low = 0;
int high = 0;
if (min<max) {
low = min;
high = max+1;
} else {
low = max + 1;
high = min;
}
result = (rand() % (high-low)) + low;
return result;
}
void fillArray(int data[], int size, int min, int max){
int i;
for(i=min ; i < max+1; i++){
data[i] = getRandom(min,max);
}
}
void printArray(int data[], int size){
int i;
printf("[");
for(i=0; i<size; i++){
printf("%d,", data[i]);
}
printf("]");
}
I agree with #Steve Friedl that the main problem with your program lies in the fillArray function. There i should run from 0 to size.
As for your second question, testing whether you're printing the last number helps to suppress the unwanted comma:
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
printf("%d", data[i]);
if (i < size - 1)
printf(",");
}
printf("]");
}
If you prefer a more compact solution (although with an optimizing compiler there's not really a difference), you could write it as:
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
printf("%d%c", data[i], i < size-1 ? ',' : ']');
}
}
Also, in your main function, you should include a and b in your printing:
printf("\t An array with random values from %d to %d \n", a, b);
I believe this is blowing things up for you:
void fillArray(int data[], int size, int min, int max){
int i;
for(i=min ; i < max+1; i++){ // <-- HERE
data[i] = getRandom(min,max);
}
}
The calling function allocates 10 items in the arr array, and that's passed as the size parameter, but you're not using that parameter to limit filling up the array. If the max value is 100, then it's trying to fill one hundred slots instead of just ten.
for (i = 0; i < size; i++)
data[i] = getRandom(min,max);
should fix at least this issue.
EDIT: The comma thing, I prefer to add commas before the items unless this is the first. In this case it doesn't matter much, but it's more general, especially for variable-length lists where you don't know you're at the end until you get there. Augmenting the helpful response from #JohanC :
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
if (i > 0) printf(",");
printf("%d", data[i]);
}
printf("]");
}
#include <stdio.h>
int main(){
void sorting(){
int a[4];
a[0]=1;
a[1]=6;
a[2]=15;
a[3]=3;
a[4]=19;
int size = 4;
int t =1;
if (size ==0) return; // ie if you reach to the end stop
int i;
for (i=0;i<size-1;i++){
if(a[i+1] >a[i]) { //if the +1 element is bigger than before it do the swap
int j;
j= a[i+1];
a[i+1]=a[i]; //swap
a[i] = j; //swap
}
}
sorting(*a,size - 1);//recursion
void print_int() {
int i; // Loop counter
for (i = 0; i < 4; i++) {
printf("%d\n", a[i]);
}}
}
It compiles ok but when I try to run the file nothing appears? My intentions were to create an array sort them then display them.
Also, the code where the recursion happened "sorting(*a,size - 1);//"
if I tried to replace *a with a[] an error will happen. Why is that?
the error is "error expected expression before ']' token"!
thank you.
int a[4];
But you access a[4]=19; index 4 that is out of bound. You can access highest index 3.
I think function void sorting() should be defined outside main .Nested functions are GNU extensions in GCC.
Your code has to many problems. Here is a working Array sort:
#include <stdio.h>
void bubble_sort(int *array, int length){
int i,j, k, temp;
for (i = 0 ; i < length-1; i++){
for (k = 0 ; k < length-i-1; k++){
if (array[k] > array[k+1]){
temp = array[k];
array[k] = array[k+1];
array[k+1] = temp;
}
}
}
printf("The sorted Array List:\n\n");
for ( j = 0 ; j < length ; j++ ){
printf("%d ", array[j]);
}
}
int main(void){
int array[] = {1,6,15,3,19};
int length = sizeof array / sizeof array[0];
bubble_sort(array, length);
printf("\n");
return 0;
}
You should read about functions declarations and definitions.
About arrays you should know that if you declare:
int array[4];
Your working array is from 0 to 3 and not from 0 to 4.
Take a look at the following:
int main(void){
int array[] = {1,6,15,3,19};
int size = 5;
int i;
for(i=0;i<size;i++){
printf("%d ",array[i]);
}
return 0;
}
I have size=5 and not size=4- like you tried. You should be careful about number of Array elements.
Aside from all the problems spotted by others, you must repeatedly execute the for loop until no more exchanges are made, which is the standad way of bubbling. As you use recursion, it is of course nonsense to declare the array to be sorted (and its size) inside the function called recursively.
So am trying to do a question that aims to find 5 max elements in int 2D array.
I had no issues with dynamically allocating the array and inputting the elements into it.
printf("Your 2-d order of choice?\n");
scanf ("%d %d", &i ,&j);
int array[i][j];
//Taking 2d array input
for (int c = 0; c < i; c++)
{
for (int d = 0; d < j; d++)
{
scanf("%d", &array[c][d]);
}
}
However, to find the 5 max elements and store them in an array it asks for a function with prototype.
int * max5(int **, int ,int)
I don’t know how to use double pointer to traverse the 2D array, even though I read a few other posts regarding int**, and what will int* (return type) exactly be and how to incorporate it.
There are the many ways to pass array as pointers
As per you said that if you take array like int array[10][10];.
Using single pointer you can do like
int *arr = max5 ((int *)array, 10, 10);
And traverse array as
int * max5 (int *arr, int m, int n)
{
int i, j;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
printf("%d ", *((arr+i*n) + j));
//.........
}
OR using double pointer you can also do like
int *arr = max5 ((int **)array, 10, 10);
And traverse like
int * max5 (int **arr, int m, int n)// Same as int * max5 (int *arr[], int m, int n)
{
int i, j;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
printf("%d ", *((arr+i*n) + j));
//.........
}
Now other way also possible it just for your information
From C99, C language supports variable sized arrays to be passed simply by specifying the variable dimensions.
int *arr = max5 (array, 10, 10);
And traverse like
int * max5 (int arr[][10],int m,int n) //Same as int * max5 ( int (*arr)[10], int m,int n))
{
int i, j;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
printf("%d ", arr[i][j]);
//.........
}
This is the max5 function.
It gets 5 elements in res (allocated by malloc), then for the remaining elements of a, it finds the smallest elements of res and compare it with that a element - if the res element is maller than the a element, that res element is replaced with the a one.
Note that I wouldn't usually use a magic number (5) in the function, but since it's called max5 ..
#include <limits.h>
int *max5(int **a, int rows, int cols) {
int *res = malloc(5 * sizeof(int));
int i,j,k,n=0; // n, number of elements in res
for (i=0 ; i<rows ; i++) {
for (j=0 ; j<cols ; j++) {
if (n < 5) res[n++] = a[i][j];
else {
// find lowest res element
int lowest=0;
for(k=1 ; k<5 ; k++) { // start from 1!
if (res[k] < res[lowest]) {
lowest = k;
}
}
// if lowest res is < a[i][j], replace it
if (res[lowest] < a[i][j]) res[lowest] = a[i][j];
}
}
}
return res;
}
For the sake of demo, this is not optimized (looking for the min all the time). One way would be to sort the res array after 5 elements have been inserted, and after one of its element is replaced (which should statistically happen less and less over the iterations). Another way would be to build a tree when the elements are input initially.
As mentioned by #haccks, array is to be declared as a int **, then i rows must be int * allocated (ie, i pointers to int), then each of the row is to be allocated the size of j int.
With the given prototype, you have to declare array as int ** and dynamically allocate memory to it.
int **array = malloc(i*sizeof(int*));
for(int row = 0; row < i; row++)
array[row] = malloc(j*sizeof(int));
Now you can call your max5 function as
int *a = max5(array, i, j);
Then dynamically allocate an array inside max5 and return it from max5.