Storing arrays into new arrays - arrays

I am not very good with words so I included a visual sample of my code. I would appreciate the help. Thank you (To add I am also a fresh programmer trying to learn algorithms but im struggling on this one)
Is there a working way to store a 2d array into a 1D array?? I have tried to do it in this way but I'm getting garbage values instead when I print it out.
#include <stdio.h>
int main() {
int disp[4][4] = {{12, 14, 32, 9},
{19, 24, 3, 4},
{11, 26, 3, 8},
{13, 24, 7, 5}
};
int quadrant_size = 2;
int k = 0;
int flat[4] = {0};
int N = 4;
int x, y, i, j;
for (x = 0 ; x < N ; x += quadrant_size) {
for (y = 0 ; y < N ; y += quadrant_size) {
int mx = disp[x][y];
for (i = x ; i < x + quadrant_size ; i++) {
for (j = y ; j < y + quadrant_size ; j++) {
if (disp[i][j] > mx) {
mx = disp[i][j];
flat[k] = disp[i][j];
k++;
}
}
}
printf("%d ", mx);
}
printf("\n");
}
for (i = 0; i < 4; i++) {
printf("%d", flat[i]);
}
return 0;
}
Basically, the output of this program will give you a result of
24 32
26 8
I am trying to print this in a 1D array using flat[k] running through a for loop will generate (Code sample included) without the pattern shown above. However, I am getting random values instead of getting a result of (When converting 2D Arrays to a 1D array)
Should be: 24 32 26 8
Instead, I am getting: 141924268
Is there an efficient way of executing this?

I made a few changes to the code and marked them with comments.
The essential problem was that writing the maximum to the array (and incrementing its write index) was inside the loop for determining the max element.
In your code you added each 'increment' to the array and not the final value as intended.
Also note, that there is no bounds check on k. So it might overflow the flat-array. It might be a good idea to add that if you use this code on other matrix sizes as well.
#include <stdio.h>
int main() {
int disp[4][4] = {
{12, 14, 32, 9},
{19, 24, 3, 4},
{11, 26, 3, 8},
{13, 24, 7, 5}
};
int quadrant_size = 2;
int k = 0;
int flat[4] = {0};
int N = 4;
int x, y, i, j;
for (x = 0 ; x < N ; x += quadrant_size) {
for (y = 0 ; y < N ; y += quadrant_size) {
int mx = disp[x][y];
for (i = x ; i < N && i < x + quadrant_size ; i++) {
// ~~~~~~~~ additional bounds check
for (j = y ; j < N && j < y + quadrant_size ; j++) {
// ~~~~~~~~ additional bounds check
if (disp[i][j] > mx) {
mx = disp[i][j];
// removed code here
}
}
}
// move code here
// only accept the maximum
flat[k] = mx;
k++;
printf("%d ", mx);
}
printf("\n");
}
for (i = 0; i < k; i++) {
// ~ use k as bound, k knows how many elements where inserted
printf("%d ", flat[i]);
// ~ space for readability
}
return 0;
}

Related

What is wrong with my code? For some reason, the last value in vetFinal seems to be memory junk

Make a program in C that, given two connections between the numbers containing the 8 and 9 values each respectively and obtained through the keyboard, provide the numbers that appear on the two lists. For example, if the connections are u = {9, 32, 45, 21, 56, 67, 42, 55} and w = {24, 42, 32, 12, 45, 11, 67, 66, 78}, the function must provide the vector v = {32, 45, 67, 42}.
#include <stdio.h>
int main(){
int n = 0;
int u[8] = {};
int w[9] = {};
int v[n];
//Inform values for the first vector
for(int i = 0; i < 8; i++)
{
scanf("%i", &u[i]);
}
//Inform values for the second vector
for(int i=0; i < 9; i++)
{
scanf("%i", &w[i]);
}
//Check if there are overlapping values in both vectors and add them to the final vector.
for(int i = 0; i < 8; i++)
{
for(int j = 0; j < 9; j++)
{
if(u[i] == w[j])
{
n++;
v[i] = u[i];
}
}
}
//Print the final vector
for(int i = 0; i < n; i++)
{
printf("%i", v[i]);
}
return 0;
}
n++;
v[i] = u[i];
Unfortunately the size of v is fixed at 0 above and won't be changed just because you changed n.
Normally we solve this with dynamic memory but you should be able to initalize v to have size 72 because you can't go around the inner loop more than 8*7 times..
int v[72];

Checking 5 ints in an array if 3 are the same

I have a int array that contains five random numbers. I am trying to check if three of the numbers match.
int die[5] = {2, 3, 5, 2, 1};
int kind = 0;
int score = 0;
int i = 0;
int x = 0;
for (i; i <= 4; i++) {
for (x; x <= 4; x++) {
if (die[i] == die[x]) {
kind++;
score += die[i];
}
}
}
The issue I am running into is the very first case it will compare itself to itself. Which will always come back true. And if I add a +1 to the index, it will end up going out of bounds.
If I start at 1 instead of 0, then when it goes to the second digit, it will return the same once it checks itself against the 2nd number(itself).
You could check if i equals j and just continue; your loop.
for(i=0; i<=4; i++){
// you can set x=i+1 and skip some numbers
for(x=0; x<=4; x++){
if(i==x)
continue;
if (die[i] == die[x]) {
kind++;
score += die[i];
}
}
}
EDIT:
There are simpler ways of doing this (checking if 3 numbers are equal), but if you just want to skip an iteration, use continue.
int die[5] = {2, 3, 5, 2, 1};
int kind = 0;
int score = 0;
for (i = 0; i < 4; i++) { // last check will be die[3] == die[4] to avoid
// die[4] == die[4]
for (x = i + 1 ; x < 5; x++) { // it always checks with the next element
if (die[i] == die[x]) {
kind++;
score += die[i];
}
}
}

How many times a digit show up

Please help me. I don't get why the out put is in "occurs" is "30", instead of '3'.. It's as if I'm multiplying the answer with '10', but I'm not.. Maybe the answer to my problem is right in to my code but Can someone explain why and how? please.. Thank you very much in advance..
Please take a look at my code.
#include <stdio.h>
int main(){
int arr[10] = {7, 7, 3, 2, 9, 8, 5, 1, 7, 9};
int occur[10] = {NULL};
int max = 0;
int most;
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < 10; j++)
{
occur[arr[j]]++;
if(occur[arr[j]] > max)
{
max = occur[arr[j]];
most = arr[j];
}
}
}
printf("Most frequent: %d\ occurs: %d\n", most, max);
return 0;
}
I am getting the correct answer in "Most Frequent". But the "occurs" is 30, instead of just 3 because 7 occurs 3 times.
It becomes 30 because there is an outer loop which executes 10 times.
I'm guessing that you want to get the most frequent number in the array and how many times it occurred that's why you have an outer loop. This will not work if you have a number in your array that is greater than 9 which will result in index out of bounds problem in occur array. You should change your implementation to this:
#include <stdio.h>
int main(){
int arr[10] = {7, 7, 3, 2, 9, 8, 5, 1, 7, 9};
int max = 0;
int most;
for(int i = 0; i < 10; i++)
{
int tmp = arr[i], count = 0;
// if the current number is the current max number then skip
if(tmp == max)
continue;
for(int j = 0; j < 10; j++)
{
// increment count if number in index j is equal to tmp number
count += arr[j] == tmp ? 1 : 0;
}
// [this condition will depend on the requirement.]
// replace max and most if the count of tmp number is greater than your
// current max
if(count > max){
max = count;
most = tmp;
}
}
printf("Most frequent: %d\ occurs: %d\n", most, max);
return 0;
}
This is not tested so if there are any problems, please feel free to edit.
You ARE multiplying max by 10 since you are doing everything 100 times (instead of 10) because of your totally redundant for i loop.
Specifically your problem is you are incrementing the values in occurs 10 times (instead of once). Since most doesn't use the incremented values it doesn't have problem.
The faster, O(2n-1) complexity solution
#include <stdio.h>
int main(){
int arr[10] = {7, 7, 3, 2, 9, 8, 5, 1, 7, 9};
int occur[10] = {NULL};
int max = 0;
for(int i = 0; i < 10; ++i)
++occur[arr[i]];
for (int i = 1; i < 10; ++i)
if (occur[i] > occur[max])
max = i;
printf("Most frequent: %d\ occurs: %d\n", max, occur[max]);
return 0;
}
Yet faster, in O(n)... I had a feeling that..
int main(){
int arr[10] = {7, 7, 3, 2, 9, 8, 5, 1, 7, 9};
int occur[10] = {NULL};
int max = 0;
for(int i = 0; i < 10; ++i)
if (++occur[arr[i]] > occur[max])
max = arr[i];
printf("Most frequent: %d\ occurs: %d\n", max, occur[max]);
return 0;
}
I will not argue that your O(n^2) operations algorithm is not the ideal way to do the task.
But moving one line of code will fix your code.
Your loop:
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < 10; j++)
{
occur[arr[j]]++;
Fix:
for(int i = 0; i < 10; i++)
{
occur[arr[i]]++;
for(int j = 0; j < 10; j++)
{
I'll let you figure out how you can do this in O(2n) operations or less...

Finding largest 2x2 "square" of values in array C

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.

array operation using CUDA kernel

I'm writing CUDA kernel and threads are performing following tasks :
for example i have array of [1, 2, 3, 4] then I want answer [12, 13, 14, 23, 24, 34]
Suppose I've an array with n integers and i've two indexes i and j.
simple solution for that in C language will be :
k=0;
for (i = 0; i < n - 1; i++)
for(j = i+1; j < n-1 ; j++)
{ new_array[k] = array[i]*10 + array[j];
k++;
}
In CUDA I've tried my luck :
for(i = threadIdx.x + 1; i < n-1; i++ )
new_array[i] = array[threadIdx.x] * 10 + array[i];
But I think this is not totally correct or optimal way to do this. can anyone suggest anything better?
I'm assuming that the code you want to port to CUDA is the following:
#include <stdio.h>
#define N 7
int main(){
int array[N] = { 1, 2, 3, 4, 5, 6, 7};
int new_array[(N-1)*N/2] = { 0 };
int k=0;
for (int i = 0; i < N; i++)
for(int j = i+1; j < N; j++)
{
new_array[k] = array[i]*10 + array[j];
k++;
}
for (int i = 0; i < (N-1)*N/2; i++) printf("new_array[%d] = %d\n", i, new_array[i]);
return 0;
}
You may wish to note that you can recast the interior loop as
for (int i = 0; i < N; i++)
for(int j = i+1; j < N; j++)
new_array[i*N+(j-(i+1))-(i)*(i+1)/2] = array[i]*10 + array[j];
which will avoid the explicit definition of an index variable k by directly using index i*N+(j-(i+1))-(i)*(i+1)/2. Such an observation is useful becuase, if you interpret the indices i and j as thread indices in the ported code, then you will have a mapping between the 2d thread indices and the index needed to access the target array in the __global__ function you have to define.
Accordingly, the ported code is
#include <stdio.h>
#define N 7
__global__ void kernel(int* new_array_d, int* array_d) {
int i = threadIdx.x;
int j = threadIdx.y;
if (j > i) new_array_d[i*N+(j-(i+1))-(i)*(i+1)/2] = array_d[i]*10 + array_d[j];
}
int main(){
int array[N] = { 1, 2, 3, 4, 5, 6, 7};
int new_array[(N-1)*N/2] = { 0 };
int* array_d; cudaMalloc((void**)&array_d,N*sizeof(int));
int* new_array_d; cudaMalloc((void**)&new_array_d,(N-1)*N/2*sizeof(int));
cudaMemcpy(array_d,array,N*sizeof(int),cudaMemcpyHostToDevice);
dim3 grid(1,1);
dim3 block(N,N);
kernel<<<grid,block>>>(new_array_d,array_d);
cudaMemcpy(new_array,new_array_d,(N-1)*N/2*sizeof(int),cudaMemcpyDeviceToHost);
for (int i = 0; i < (N-1)*N/2; i++) printf("new_array[%d] = %d\n", i, new_array[i]);
return 0;
}
Please, add your own CUDA error check in the sense of What is the canonical way to check for errors using the CUDA runtime API?. Also, you may wish to extend the above CUDA code to the case of block grids of non-unitary sizes.

Resources