I have a global integer pointer array, which is created this way
int * array;
array = (int *) malloc(size * sizeof(int));
I also have a sorting algorithm, which is supposed to sort 4 first numbers of the array which size is larger than 4 (16 in this case). sizeOfArray is defined as 4 in this case:
int temp,i,j;
for(i=0;i<sizeOfArray;i++){
for(j=i;j<sizeOfArray;j++){
if(array[i] > array[j]){
temp=array[i];
array[i]=array[j];
array[j]=temp;
}
}
}
Output is really weird for some reason:
Unsorted: 7,6,9,3
Sorted: 3,6,5,1
The weirdest part is if I change algorithm to sort numbers in a descending order, it seems to work:
if(array[i] < array[j])
Unsorted: 10,0,1,8
Sorted: 10,8,1,0
What's causing this? I'm completely lost.
Here is your code wrapped to make an MCVE How to create a Minimal, Complete, Valid Example?:
#include <stdio.h>
#include <stdlib.h>
static void print(int n, int a[n])
{
for (int i = 0; i < n; i++)
printf("%2d", a[i]);
putchar('\n');
}
int main(void)
{
int size = 16;
int *array = (int *) malloc(size * sizeof(int));
array[0] = 7;
array[1] = 6;
array[2] = 9;
array[3] = 3;
int sizeOfArray = 4;
printf("Before:");
print(sizeOfArray, array);
int temp, i, j;
for (i = 0; i < sizeOfArray; i++)
{
for (j = i; j < sizeOfArray; j++)
{
if (array[i] > array[j])
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
printf("After: ");
print(sizeOfArray, array);
return 0;
}
The output from this program is:
Before: 7 6 9 3
After: 3 6 7 9
Since this is not the same as the output you get, there must be a difference — a crucial difference. Since you don't show the code that initializes the array, nor show the code that demonstrates that the first 4 elements have the unsorted values, nor show the code that demonstrates the sorted values are wonky, it is not possible to say for certain what is wrong — but the problem is not in the code you show.
I've not fixed the code to check that the memory allocation succeeds; nor have I modified the code to release the allocated space. Both should be done.
The code does use C99 features; it is trivial to revise it not to do so:
static void print(int n, int *a)
{
int i;
for (i = 0; i < n; i++)
and move the definition of sizeOfArray before the assignments.
I am sure this will work for your sorting array...in 2nd iteration sizeofarray-1 will work for loop j...
int temp,i,j;
for(i=0;i<sizeOfArray;i++)
{
for(j=0;j<sizeOfArray-1;j++)
{
if(array[i] > array[j])
{
temp=array[i];
array[i]=array[j];
array[j]=temp;
}
}
}
Let's do some iterations of your code with the values you provide : 7,6,9,3. Also, let's assume that sizeOfArray = 4.
For i = j, your condition will never be executed, because array[i] = array[j].
For i = 0 and j = 1 => 7 > 6 => array = {6, 7, 9, 3}
For i = 0 and j = 2 => 6 < 9 => array = {6, 7, 9, 3}
For i = 0 and j = 3 => 6 > 3 => array = {3, 7, 9, 6}
For i = 1 and j = 2 => 7 < 9 => array = {3, 7, 9, 6}
For i = 1 and j = 3 => 7 > 6 => array = {3, 6, 9, 7}
For i = 2 and j = 3 => 9 > 7 => array = {3, 6, 7, 9}
Thus, I obtained the four first elements of your array sorted correctly (which contains size elements and I assume that size = 16).
If you're not sure about the value of sizeOfArray or size, I suggest you to print them and to check if it's really the value you want.
Hope this helps you.
Related
For example I have an array:
arr[9] = {1, 3, 4, 9, 2, 9, 2, 9, 7}
I then sort the array to get
arr[9] = {1, 2, 2, 3, 4, 7, 9, 9, 9}
Then I count duplicates for each value using two for loops. The output I want is:
2 instances of 2
3 instances of 9
Instead, I get:
2 instances of 2
3 instances of 9
2 instances of 9
I know that after the loop goes once, when arr[6], the outer loop counts that there are two more 9 but after that is finished, and loop goes to arr[7], the outer loop still counts there is another 9 which is arr[8]. So my question, how do I stop the code when it has counted duplicates for each number in the array once. Thanks!
Example code:
#define NUM = 9
int main() {
arr[NUM] = {1, 3, 4, 9, 2, 9, 2, 9, 7};
sort_int_array(arr, NUM); //insertion sort function
int i, j, count=1;
for (i=0; i<NUM; i++) {
for (j=i+1;j<NUM; j++) {
if (arr[i] == arr[j]) {
count++;
}
if (arr[i] != arr[j] && count>1) {
printf("%d instances of %d\n", count, arr[i]);
count=1;
}
}
}
}
I found the answer guys, thank you for helping. I just needed to remove the 2nd for loop.
#define NUM = 9
int main() {
arr[NUM] = {1, 3, 4, 9, 2, 9, 2, 9, 7};
sort_int_array(arr, NUM); //insertion sort function
int i, count=1;
for (i=0; i<NUM; i++) {
if (arr[i] == arr[i+1]) {
count++;
}
if (arr[i] != arr[i+1] && count>1) {
printf("%d instances of %d\n", count, arr[i]);
count=1;
}
}
}
I think the problem is you go to the first nine, then it counts the next two. THEN it will go to the duplicate and also compare the duplicate against the other duplicate. I assume what you could do is check if arr[i] is not equal to arr[i - 1] so you don't compare duplicates
Here is a demonstrative program that shows how numbers of occurrences of elements of an array cam be calculated.
#include <stdio.h>
#include <stdlib.h>
int cmp( const void *a, const void *b )
{
int x = *( const int * )a;
int y = *( const int * )b;
return ( y < x ) - ( x < y );
}
int main(void)
{
int arr[] = {1, 3, 4, 9, 2, 9, 2, 9, 7};
const size_t N = sizeof( arr ) / sizeof( *arr );
qsort( arr, N, sizeof( int ), cmp );
for ( size_t i = 0; i != N; )
{
size_t j = i;
size_t count = 1;
while ( ++i != N && arr[i] == arr[j] ) ++count;
printf( "%zu instances of %d\n", count, arr[j] );
}
return 0;
}
The program output is
1 instances of 1
2 instances of 2
1 instances of 3
1 instances of 4
1 instances of 7
3 instances of 9
If you want you may substitute this call of printf
printf( "%zu instances of %d\n", count, arr[j] );
for this one
if ( count != 1 ) printf( "%zu instances of %d\n", count, arr[j] );
In this case the output will be
2 instances of 2
3 instances of 9
EDIT: As for your solution published as an answer to your own question then the code invokes undefined behavior due to accessing memory beyond the array in this expression arr[i+1] when i is equal to NUM - 1
for (i=0; i<NUM; i++) {
if (arr[i] == arr[i+1]) {
^^^^^^^^
count++;
}
if (arr[i] != arr[i+1] && count>1) {
^^^^^^^^
printf("%d instances of %d\n", count, arr[i]);
count=1;
}
}
You don't need to use two for loops for this, it would be inefficient and increases the complexity of the code.
If you are doing this with hand you would
Bring another sheet of paper.
for each number in the array:
if it's the first time you see this number:
Note it down and record it has count of 1
else:
then increment the count by 1
if you only need elements that occurred at least twice, you can filter out elements with count = 1.
As for the code:
// this is called frequency array, which we will use to store the
// number of occurrences (frequency) of a given number.
// The size of the array must be larger than the largest number in the array
int sz = 10 // sz = largest expected element + 1 (this only works for array of integers).
int freq[sz];
memset(freq, 0, sz * sizeof(int)); // reset all values in the array to 0
int arr[9] = {1, 2, 2, 3, 4, 7, 9, 9, 9};
int i;
for (i = 0;i < 9;i++){
cur = arr[i]; // read the current element
freq[cur] += 1; // increment its count by 1
}
for (i = 0;i < sz;i++) {
count = freq[i]; // read the count of the number i
if(count != 0) {
// a count of 0 means that the number didn't occur in the array
// you can also exclude numbers occurring only once by count > 1
printf("%d instances of %d\n", count, i);
}
}
I didn't test this code but this is the concept, you can find more here.
This implementation uses more space than needed, but it has fast access time, if you move to cpp, you can use stl map or unordered_map for more space-efficient solution.
I'm programming in C. I have to make a function called count , that counts how many times is larger than the subsequent element in the same array. For example, if we had a main code looking like this:
int main() {
int a1[] = { 5 };
int a2[] = { 1, 2, 3, 4, 5 };
int a3[] = { 5, 4, 3, 2, 1 };
int a4[] = { 1, 9, 3, 7, 5 };
int a5[] = { 7, 5, 6 };
printf("%d\n", count(a1, sizeof a1 / sizeof a1[0]));
printf("%d\n", count(a2, sizeof a2 / sizeof a2[0]));
printf("%d\n", count(a3, sizeof a3 / sizeof a3[0]));
printf("%d\n", count(a4, sizeof a4 / sizeof a4[0]));
printf("%d\n", count(a5, sizeof a5 / sizeof a5[0]));
return 0;
}
Count should return the following:
0
0
4
2
1
I have tried myself, but it seems like I get an off-by-one error that I don't know how to fix.
int count(int a[], int i){
int k=0;
int j;
for (j=0; j<=i-1; j++){
if(a[j] > a[j+1])
k++;
}
return k;
}
But this gives this wrong output:
0
1
5
3
2
Can someone spot the mistake in my code, or help me with this?
You're reading a[i] when j=i-1, which is out of array a bound.
for (j=0; j<=i-1; j++){
if(a[j] > a[j+1])
It should be
for (j=0; j<i-1; j++){
if(a[j] > a[j+1])
A way to avoid this off-by-one error is to use an idiomatic "iterate over an array" for loop and termination condition j < i but change the initial loop index from 0 to 1. The test inside the loop uses j and j - 1.
int count(const int *a, int i)
{
int k = 0;
for (int j = 1; j < i; j++) {
if (a[j - 1] > a[j])
k++;
}
return k;
}
I think j < i is easier to reason about than j <= i - 1 and be confident that it's correct.
I am trying to create a sorting method based on selection sort algorithm
With this current code, the array [10, 9, 8 .. 1] is "sorted" to
[9, 8 .. 2, 10, 1]
I mean like, it doesn't even put 10 in the right place
10 9 8 7 6 5 4 3 2 1
"sorted" to
9 8 7 6 5 4 3 2 10 1
What's the problem ?
void selectionSort(int array[], int length)
{
int i = 0, j = 0, temp = 0, swap = 0;
for(i = 0; i < length; i++)
{
temp = i;
for(j = 0; j < length; j++)
{
if(array[temp] > array[j])
{
temp = j;
}
}
swap = array[temp];
array[temp] = array[i];
array[i] = swap;
}
}
The inner loop should be written like
for(j = i + 1; j < length; j++)
^^^^^^^^^
After each iteration of i, the array upto i , should be sorted. You can print the array after each iteration of i and can see the logical error.
I have a 2D matrix
1 2 3
4 5 6
7 8 9
stored in C like this
int array[9] = {1,2,3,4,5,6,7,8,9};
and I would like to get the transpose of that matrix like this
int array_t[9] = {1,4,7,2,5,8,3,6,9};
without converting the original array into a 2D one. How can this be done?
This can be done by switching around the loops you would normally use to index it. If you wanted the original matrix you could loop through it with something like this
for (i = 0; i < 3; ++i) {
for (j = 0; j < 3; ++j) {
printf("%d ", array[j + i * 3]);
}
printf("\n");
}
If we switch the i and j loops we can get the desired output as in the following sample program
#include <stdio.h>
int main() {
int array[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int i, j;
for (j = 0; j < 3; ++j) {
for (i = 0; i < 3; ++i) {
printf("%d ", array[j + i * 3]);
}
printf("\n");
}
}
This is related to the mathematical definition of the transpose of a 2D matrix. The transpose operation on a 2D matrix swaps the rows with the columns, in the C program when we are indexing it we swap our row and column loops.
For my assignment I have to take in an array of values, save them to a second array and print out a "square" of the 4 highest values. This means the "square" for which the sum of its elements is the greatest in the array.
Example: Given the array 1 2 3 4
5 6 7 8
9 10 11 12
the output should be 7 8
11 12
I was originally trying to use sets of nested for loops to find and store each of the subsequent largest values into the second array, but can't seem to figure out the proper algorithm. What I have so far just gives me the same value (in this example's case, 12). Also, I have come to realize that this way won't allow me to keep the formatting the same in the second array.
What I mean is that if I'm saving the largest number found into array b[0][0], it will be in the wrong spot, and my square would be off, looking something like:
12 11
10 9
Here's what I have so far:
int main(){
int og[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}, new[2][2]={}, rows;
int columns, i, high,j,high2,high3,high4;
high = new[i][0];
high2= high - 1;
high3= high2 - 1;
high4= high3 - 1;
rows = 3;
columns = 4;
for (i=0; i<=rows; i++){
for(j=0; j<=columns; j++){
if (high < og[j][i])
high = og[j][i];
}
}
for(i=1;i<=rows;i++){
for(j=1;j<=columns;j++){
if(high2 < og[j][i])
high2= og[j][i];
}
}
printf("max = %d, %d\n", high, high2);
//return high;
system("pause");
return 0;
The logic should go roughly as follows (I dont have a compiler atm to test it, so let me know in the comments if i made a derpy error):
int i = 0;
int j = 0;
int max = 0;
int sum = 0;
int i_saved = 0;
int j_saved = 0;
for(i = 0; i < rows - 1; i++){
for(j =0; j < columns -1; j++){
sum = og[i][j] + og[i][j+1] + og[i+1][j] + og[i+1][j+1]; //sum the square
if (sum > max){
max = sum;
i_saved = i;
j_saved = j;
}
}
}
Since OP is asking for the values used in order to save to another array, all you have to do is retrieve the values again! We have the indices saved already, so this should be relatively trivial.
int [][] arr = [2][2];
arr[0][0] = og[i_saved][j_saved];
arr[0][1] = og[i_saved][j_saved+1];
arr[1][0] = og[i_saved+1][j_saved];
arr[1][1] = og[i_saved+1][j_saved+1];
The same way we summed them, we can also use that logic pattern to extract them!
I created this solution:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int Mat[3][4]={{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}};
int maximum = 0;
int Max_2x2[2][2] = {{1, 2},
{5, 6}};
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 3; j++) {
maximum = max(Mat[i][j]+Mat[i][j+1]+Mat[i+1][j]+Mat[i+1][j+1], maximum);
if(maximum == Mat[i][j]+Mat[i][j+1]+Mat[i+1][j]+Mat[i+1][j+1]) {
Max_2x2[0][0] = Mat[i][j];
Max_2x2[0][1] = Mat[i][j+1];
Max_2x2[1][0] = Mat[i+1][j];
Max_2x2[1][1] = Mat[i+1][j+1];
}
}
}
cout << maximum << endl;
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 2; j++) {
cout << Max_2x2[i][j] << " ";
}
cout << endl;
}
return 0;
}
which gives the following output:
38 // maximum solution
7 8 // output array
11 12
This is obviously not a general solution, but it works for your example.
int new[2][2]={}
I'm not sure this is valid. You might need to specify a 0 value for each cell. Even it it's not required, it's good practice.
high = new[i][0];
I don't see where i has been initialized.