Find a pair in a struct array only once - arrays

I have a struct and a struct array similar to this:
struct point{
double x;
double y;
char name[10];
};
struct point points[1000];
I created an algorithm that calculates the distances between all the points and prints the pair with the smallest distance, like this:
int count = 0;
for (int i = 0; i < 1000; i++){
for(int j = 0; j < 1000; j++){
if(i != j){
double distance = sqrt(pow(points[i].x - points[j].x, 2) + pow(points[i].y - points[j].y, 2));
if(distance == min){
printf("%s - %s\n", points[i].name, points[j].name);
count++;
}
}
}
}
If there are multiple pairs with the same distance, it prints all of them, but it prints them TWICE (the second time in a different order), what would be an ideal logical gate in the printing loop to prevent the structures with the same distance being printed twice?

Change to this:
for (int i = 0; i < 999; i++){
for(int j = i+1; j < 1000; j++){
double distance = sqrt(pow(points[i].x - points[j].x, 2) + pow(points[i].y - points[j].y, 2));
if(distance == min){
printf("%s - %s\n", points[i].name, points[j].name);
count++;
}
}
}
I changed intervals for i and j and removed the if statement.

Instead of looping like this:
for(int i = 0; i < 1000; i++){
struct point a = points[i]
for(int j = 0; j < 1000; j++){
struct point b = points[j]
}
}
Try this so that you only loop over each point once
for(int i = 0; i < 999; i++){
struct point a = points[i]
for(int j = i; j < 1000; j++){
struct point b = points[j]
}
}

Related

Sorting a matrix

Im trying to sort a matrix by the sum of its row's digits, from highest to lowest. I dont know if i explained that correctly so here's some photos explaining it.
This is what my code outputs. Basically, it asks you for m and n, which are the dimensions of the matrix. In this example it's a 3x4, 3 rows and 4 columns. Then, the matrix should be sorted by rows, by the sum of row's digits. Which means, instead of what's being outputted in the picture above, the correct result should be this:
I have no idea how to sort this from highest to lowest, i have been trying for hours to no avail.
Here's my code:
#include <stdio.h>
#define N 30
void main(){
double a[N][N], s[N], p;
int i, j, m, n, max;
while(1){
printf("\nm, n? ");
scanf("%d%d", &m, &n);
if(m <= 0 || m > N || n <=0 || n > N)
break;
for(i = 0; i < m; i++){
printf("%2d. row? ", i+1);
for(j = 0; j < n; scanf("%lf", &a[i][j++]));
}
for(i = 0; i < m; i++)
for(s[i] = j = 0; j < n; s[i] += a[i][j++]);
for(j = 0; j < n - 1; j++){
for(max = i, j = i+1; j < n; j++)
if(s[j] > s[max])
max = i;
if(max != j){
p = s[j];
s[j] = s[max];
s[max] = p;
for(j = 0; j < m; j++){
p = a[j][i];
a[j][i] = a[j][max];
a[j][max] = p;
}
}
}
printf("New matrix: \n");
for(i = 0; i < m; i++){
for(j = 0; j < n; printf("%8.2lf", a[i][j++]));
printf("\n");
}
for(j = 0; j < m; j++)
printf("-------------");
printf("\n");
for(j = 0; j < m; printf("%8.2f \n", s[j++]));
printf("\n");
}
}
You can sort the rows of the matrix from highest to lowest, using a simple bubble sort algorithm.Your code modified below:
int main() {
double a[N][N], s[N], p;
int i, j, m, n, max;
while (1) {
printf("\nm, n? ");
scanf("%d%d", & m, & n);
if (m <= 0 || m > N || n <= 0 || n > N)
break;
for (i = 0; i < m; i++) {
printf("%2d. row? ", i + 1);
for (j = 0; j < n; scanf("%lf", & a[i][j++]));
}
for (i = 0; i < m; i++)
for (s[i] = j = 0; j < n; s[i] += a[i][j++]);
for (i = 0; i < m - 1; i++) { // modified here
for (j = i + 1; j < m; j++) { // modified here
if (s[j] > s[i]) { // modified here
p = s[i];
s[i] = s[j];
s[j] = p;
for (int k = 0; k < n; k++) {
p = a[i][k];
a[i][k] = a[j][k];
a[j][k] = p;
}
}
}
}
printf("New matrix: \n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; printf("%8.2lf", a[i][j++]));
printf("\n");
}
for (j = 0; j < m; j++)
printf("-------------");
printf("\n");
for (j = 0; j < m; printf("%8.2f \n", s[j++]));
printf("\n");
}
return 0;
}
Here's how i modified your code to achieve that:
Initialize a loop variable i to 0.
In the outer loop, run the inner loop j from i+1 to m-1.
In the inner loop, compare the sum of the row i with the sum of row
j. If the sum of row j is greater than the sum of row i, swap the
rows using a temporary variable.
After the inner loop finishes, increment the value of i by 1. Repeat
the outer loop until i becomes equal to m-1.
Output:
You can just use qsort to let it handle the sorting and item swapping. Then you only need to write the code for comparing two rows with each other.
Given something like this:
int matrix[3][4] =
{
{1,2,3,4},
{5,6,7,8},
{9,1,2,3},
};
You'd call qsort as:
qsort(matrix, 3, sizeof(int[4]), compare);
The only complexity is implementing the comparison callback function. There's two things to consider there:
We've told qsort that we have an array of 3 items, each of type int[4]. So the void pointers it passes along to us will actually be pointers to type int[4]. That is: int(*)[4].
qsort sorts in ascending order by default, where the item considered "less" ends up first. So we need to tweak that to get the largest item first.
Example:
int compare (const void* obj1, const void* obj2)
{
const int (*ptr1)[4] = obj1;
const int (*ptr2)[4] = obj2;
size_t sum1=0;
size_t sum2=0;
for(size_t i=0; i<4; i++)
{
sum1 += (*ptr1)[i];
sum2 += (*ptr2)[i];
}
if(sum1 > sum2) // largest sum considered "less" for qsort
return -1;
else
return 1;
return 0;
}
sum1 < sum2 would have placed the smallest row first.
Full example:
#include <stdio.h>
#include <stdlib.h>
int compare (const void* obj1, const void* obj2)
{
const int (*ptr1)[4] = obj1;
const int (*ptr2)[4] = obj2;
size_t sum1=0;
size_t sum2=0;
for(size_t i=0; i<4; i++)
{
sum1 += (*ptr1)[i];
sum2 += (*ptr2)[i];
}
if(sum1 > sum2) // largest sum considered "less" for qsort
return -1;
else
return 1;
return 0;
}
void print_matrix(size_t col, size_t row, int matrix[col][row])
{
for(size_t i=0; i<col; i++)
{
for(size_t j=0; j<row; j++)
{
printf("%d,", matrix[i][j]);
}
puts("");
}
}
int main (void)
{
int matrix[3][4] =
{
{1,2,3,4},
{5,6,7,8},
{9,1,2,3},
};
print_matrix(3,4,matrix);
puts("");
qsort(matrix, 3, sizeof(int[4]), compare);
print_matrix(3,4,matrix);
}

Sorting array in C

I'm trying to sort an array size in C, i have ran some tests on it before i publish it here (I have left the testing statement in).
I get the correct answer once but than it moves the higher value into the wrong array, even though i have used an IF statement.
If you guys run the program it will make sense to you.
#include <stdio.h>
# define size 3
int sum();
main() {
int a[size] = { 4, 2, 3 };
int temp, i, j, x;
for (j = 0; j < size; j++){
for (i = 1; i < size; i++){
for (x = 0; x < size; x++){
printf("%d", a[x]); //testing statement;
}
printf("\n");
if (a[j] > a[i]){
temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
}
for (x = 0; x < size; x++){
printf("%d", a[x]);
}
getch();
}
Change
for (i = 1; i < size; i++){
to something like
for (i = j + 1; i < size; i++) {
and your sort will work correctly. As it is, you're comparing the elements again with if (a[j] > a[i]){ which can move them back when you reset i to 1.

% symbols keep printing when trying to print out a char 2D array in C

I'm new to C and I'm just trying to print out a two 2 array.
This bug has been annoying me all day and I'm not really sure whats going on.
#include<stdio.h>
void run(int);
main()
{
run(5);
return 0;
}
//Have to make it a character array as it needs to
//store numbers AND commas.
run(int x)
{
int size = 2*x -1;
char array[size][size];
int i = 0;
int j = 0;
for( i; i < size; i++){
for(j; j< size; j++){
array[i][j] = '1';
}
}
int k = 0;
int l = 0;
for( k; k < size; k++){
for(l; l< size; l++){
printf( "%c" , array[l][k]);
}
printf("%\n", "");
}
}
This is the output I get:
1%
%
%
%
%
%
%
%
%
You code has several mistakes:
The biggest problem is that your not initializing your loop counters where you should:
for(i; i < size; i++){
for(j; j < size; j++){
With that, i & j are left as they were prior to the for statement. The first section of these statements does nothing at all. While that's harmless for i (since it's initialized to 0 before the for), that's devastating for j, which never goes back to 0. Your code should be:
for(i = 0; i < size; i++){
for(j = 0; j < size; j++){
The same issue exists with k & l, and the same fix should be applied:
for(k = 0; k < size; k++){
for(l = 0; l < size; l++){
Next, you're "rotating" access in your array. When you fill the array with values, you have i in your outer loop and j in the inner loop, and you use them as [i][j]:
array[i][j] = '1';
Think of that as Out & In --> [Out][In].
When you print the array, you "rotate" that, k is outer & l is inner, and you use them as [l][k]:
printf("%c", array[l][k]);
That's like doing [In][Out].
While that's not a problem with all values being identical ('1'), and the matrix being square (width == height), it won't work with other values or dimensions, and is confusing.
Last, you're attempt to print a new line is wrong. You have a % specifier, but your not really using any valid character after that, and you don't need that anyway, just print:
printf("\n");
So, all together, here's what the code should be:
run(int x)
{
int size = 2*x -1;
char array[size][size];
int i,j;
for(i = 0; i < size; i++){
for(j = 0; j < size; j++){
array[i][j] = '1';
}
}
int k, l;
for(k = 0; k < size; k++){
for(l = 0; l < size; l++){
printf("%c", array[k][l]);
}
printf("\n");
}
}
(And as a side note, k & l are not really required, you can simply reuse i & j)

Preventing duplicates from being stored when filling dynamic array with values from two different arrays

I need to know a method to keep duplicate numbers from being stored in a new array when taking numbers from two different arrays. The function is supposed to store each 'unique' value once and not store duplicate values again.
Here is my function code so far:
int * arrayIntersect(int *sizeOfResult, const int *a, const int *b, int sizeOfA, int sizeOfB){
int i;
int j;
int k = 0;
int c[(sizeOfA + sizeOfB)];
for(j = 0; j < sizeOfB; j++){
for(i = 0; i < sizeOfA; i++){
if(a[i] == b[j]){
c[k] = a[i];
(*sizeOfResult)++;
k++;
}
}
}
int *d = (int *)malloc(sizeof(int) * *sizeOfResult);
for(i = 0; i < *sizeOfResult; i++){
d[i] = c[i];
}
return d;
}
It prints the values I need, but I want to eliminate the same number from showing up multiple times when printing the contents of the new dynamic array.
Any idea on how to improve my code to allow prevent duplication?
The proper way to do it is having the arrays ordered and then doing a binary search for each insertion like #Murilo Vasoncelos pointed out.
Below is a quick and dirty solution that loops through a and b and for each iteration checks if the number has been inserted before. If it isn't, it inserts it.
int duplicate = 0;
*sizeOfResult = 0;
for(j = 0; j < sizeOfA; j++){
for(i = 0; i < (*sizeOfResult); i++){
if(c[i] == a[j]){
duplicate = 1;
break;
}
}
if (!duplicate)
{
c[(*sizeOfResult)] = a[i];
(*sizeOfResult)++;
}
duplicate = 0;
}
for(j = 0; j < sizeOfB; j++){
for(i = 0; i < (*sizeOfResult); i++){
if(c[i] == b[j]){
duplicate = 1;
break;
}
}
if (!duplicate)
{
c[(*sizeOfResult)] = b[i];
(*sizeOfResult)++;
}
duplicate = 0;
}
If your arrays a and b are ordered, you can simply use this linear algorithm for array intersection:
int* inter(int* szr, int* a, int* b, int sza, int szb)
{
int c[MAX(sza, szb)];
int i, j, k = 0;
for (i = 0, j = 0; i < sza && j < szb;) {
if (a[i] == b[j]) {
if (k == 0 || c[k - 1] < a[i]) {
c[k++] = a[i];
}
i++;
j++;
}
else if (a[i] < b[j]) {
i++;
}
else {
j++;
}
}
*szr = k;
int* ans = (int*)malloc(sizeof(int) * k);
for (i = 0; i < k; ++i) {
ans[i] = c[i];
}
return ans;
}

Product of numbers, not printing right number

I have a 2d array (matrix) where I am trying to calculate the biggest product of adjacent numbers. It's very similar to Project Euler Problem 11 except the user enters how many adjacent numbers they want in the calculation. I have it all right I think. The problem is if i use integer's to calculate the product of say 5 integers of 99 (e.g. 99*99*99*99*99) it will not display right. The maximum number of adjacent numbers which can be checked is 99. I have tried changing to long doubles (as you can see in the code) but it prints ridiculous numbers, e.g. with 3 adjacent numbers I entered 99 in all matrix positions and should get back 970299 (which I do when the maxProduct is an int), but instead I get:
-497917511184158537131936752181264370659584929560826523880745083032965215342755650440802286656251727430041200624372430370294634536699364412350122489510814753628581807006780156992324264734484592980976635224618682514265787653963930812412392499329499188301075222828863209569131692032
I feel like it's something obvious but I just can't see it.
#include <stdio.h>
#include <stdlib.h>
long double calcProduct(int n, int m, int ** matrix)
{
int i, x, y; //Loop counters
long double maxProduct; //Used to hold the maximum product of numbers found so far
long double temp; //Used to hold the current product of numbers
//Searching left to right
for(y = 0; y < n; y++)
{
for(x = 0; x <= n - m; x++)
{
for(i = 0; i < m; i++)
{
temp *= matrix[x + i][y];
}
if(temp > maxProduct)
{
maxProduct = temp;
}
temp = 1;
}
}
//Searching top down
for(x = 0; x < n; x++)
{
for(y = 0; y <= n - m; y++)
{
for(i = 0; i < m; i++)
{
temp *= matrix[x][y + i];
}
if(temp > maxProduct)
{
maxProduct = temp;
}
temp = 1;
}
}
temp = 1;
//Searching diagonal down right
for(x = 0; x < n - m; x++)
{
for(y = 0; y <= n - m; y++)
{
for(i = 0; i < m; i++)
{
temp *= matrix[x + i][y + i];
}
if(temp > maxProduct)
{
maxProduct = temp;
}
temp = 1;
}
}
temp = 1;
//Searching diagonal up right
for(x = 0; x < n - m; x++)
{
for(y = n - 1; y >= m - 1; y--)
{
for(i = 0; i < m; i++)
{
temp *= matrix[x + i][y - i];
}
if(temp > maxProduct)
{
maxProduct = temp;
}
temp = 1;
}
}
return maxProduct;
}
main()
{
int ** matrix; //2D array to hold the matrix items
int n, m; //Used to hold the size of the matrix (n) and the number of adjacent numbers to include in the calculation (m)
int i, j; //Loop counters
//Taking input of n (for size of grid) and m (number of adjacent numbers to include in calculation)
scanf("%d %d", &n, &m);
//Assign the array 'matrix' with the size of int multiplied by the number of items to hold (n)
matrix = (int **)malloc(sizeof(int*)*n);
//If the matrix is null then exit the program
if (matrix == NULL)
{
exit (0);
}
for(i = 0; i < n; i++)
{
matrix[i] = (int *)malloc(sizeof(int)*n);
if(matrix[i] == NULL) exit (0);
}
//Getting the numbers which are held in the matrix
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
scanf("%d", &matrix[i][j]);
}
}
//Prints the highest product by calling the method calcProduct, giving it n, m and the array matrix
printf("%.0Lf", calcProduct(n, m, matrix));
}
temp is not initialized in calcProduct, and neither is maxProduct. They will contain random, garbage values the first time through the loop, which is corrupting your maxProduct result.
'matrix is of type 'int'-Array, but your scanf() 'doubles' into it

Resources