I have a text file with a large matrix (56*10000). But here is a sample.
A B C D
1 3 4 5
3 5 6 10
2 2 6 11
3 2 3 38
3 3 1 19
I have a code which can read the file and also print it. I have two problems.
I can't seem to find a way to print a particular column. For example in MATLAB, if we want to print the second column we indicate it like [:,2].
Is there way where I can access the column by a particular name. For example, since these columns are named A B C D, if I want to print the second column, I just have to say, if case in B, print (B) and it has to print,
3
5
2
2
3
Here is the code that I have.
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE * fp;
int M = 5, N = 4;
char filter[1024] ;
double *Z_BS = (double *)malloc(M * N * sizeof(double));
fp = fopen("test.txt","r");
if (fp == NULL)
{
exit(1);
}
fgets(filter,1024,fp);
for (int rows = 0; rows < M; rows++)
{
for (int cols = 0; cols < N; cols++)
{
fscanf(fp, "%lf", Z_BS);
printf("%lf\t", *Z_BS);
}
printf("\n");
if (feof(fp))
{
break;
}
}
}
In C there is no way like matlab, but with the help of below idea you can generate the required offset
offset = row_size*i + column_number
lets say there are five 5 rows and 5 columns and you want to access 3 column.
A B C D E
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
when i = 0, 5*0+3 = 3
when i = 1, 5*1+3 = 8
when i = 2, 5*2+3 = 13
when i = 3, 5*3+3 = 18
when i = 4, 5*4+3 = 23
NOTE: check for EOF always or the offset is valid before using, you should not access anything beyond the file.
Unrelated, but if you just want to print the values, there's no need to allocate memory.
Using a local variable is enough
for (int rows = 0; rows < M; rows++) {
for (int cols = 0; cols < N; cols++) {
double Z_BS;
fscanf(fp, "%lf", &Z_BS);
printf("%lf\t", Z_BS);
}
printf("\n");
if (feof(fp)) {
break;
}
}
To print just one column, you can simply use the col variable, say print the second column
for (int cols = 0; cols < N; cols++) {
double Z_BS;
fscanf(fp, "%lf", &Z_BS);
if (cols == 1)
printf("%lf\t", Z_BS);
}
It says cols == 1, because the loop starts at 0 (first column = 0, second column = 1, ...).
To print by column name, don't skip the first row, but compare the name, e.g.
char colname[] = "B";
int colnum;
// Scan header row
for (int cols = 0; cols < N; cols++) {
char current[51];
fscanf(fp, "%.50s", current);
if (strcmp(current, colname) == 0) {
colnum = cols;
break;
}
}
and later while printing
if (cols == colnum)
printf("%lf\t", Z_BS);
Related
I need to check if I can find inside of given matrix size of 5*8
a matrix that has a transpose and if there is more than one I must find the biggest one.
example of a given matrix
1 2 0 3 2 1 0 7
2 3 4 1 2 3 4 5
3 4 6 2 5 6 7 6
4 5 7 3 6 8 9 8
6 7 1 4 7 9 0 9
in this matrix we can find a matrix 4x4
that has transpose and its the biggest matrix in the main matrix
1 2 3 4
2 5 6 7
3 6 8 9
4 7 9 0
#include <stdio.h>
#define M 4
#define column 5
#define row 8
int main()
{
int matrixA[5][8];
printf("please enter a matrix to check if there is a transpose matrix\n");
for (int i = 0; i < column; i++)
{
for (int j = 0; j < row; j++)
{
printf("please enter %d row and %d column: ", i + 1, j + 1);
scanf("%d", &matrixA[i][j]);
}
}
transpose(matrixA, column, row);
}
void transpose(int A[][row], int c, int r)
{
int matrixAT[M][M];
for (int size = r; size > 0; size--)
{
for (int j = 0; j < c - size + 1; j++)
{
for (int b = 0; b <= r - size; b++)
{
printf("Checking Matrix at row: %d , column: %d ,size: %dx%d", j, b, size, size);
for (int k = j, w = 0; k < size + j; k++, w++)
{
for (int l = b, z = 0; l < size + b; l++, z++)
{
matrixAT[w][z] = A[k][l];
}
printf("/n");
}
if (IsSymmetric(matrixAT, size))
printf("Matrix found");
}
}
}
}
int IsSymmetric(int mat[M][M], int size)
{
int flag = 0;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (mat[i][j] == mat[j][i]) flag++;
}
}
return flag == size * size ? 1 : 0;
}
this is my code i dont know what im doing wrong
Your IsSymmetric is slow as it always check all elements why not stop on first inequality instead? Also copying it to temp array again and again ...
The main problem is You are not checking every position and size as you call transpose(matrixA, column, row); only once outside the loops ...
Also your main does not return anything and its declared as int ...
I would start with brute force like this:
#define column 5
#define row 8
int IsSymmetric(int mat[column][row], int i0,int j0,int size) // check n*n sub matrix at i0,j0 no need to copy again and again to temp array
{
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
if (mat[i0+i][j0+j] != mat[i0+j][j0+i]) return 0;
return 1;
}
int min(int a,int b){ return (a<b)?a:b; } // not sure if min is present in your environment if is comment this line out
int main()
{
int matrixA[5][8];
...
for (int i = 0; i < column; i++)
for (int j = 0; j < row; j++)
for (int n = 1; n <= min(column-i,row-j); n++)
if (IsSymmetric(matrixA,i,j,n))
{
// here do what you want with the i,j,n*n sub matrix
// like remember position and size for the biggest n
}
...
return 0; // return value as you declared int main
}
Hope I did not make any typo in here as I just wrote this into answer editor from your original code.
How ever as you can see its O(n^4) complexity (on average O(n^3)) which is really slow. However for your small matrix its not a problem.
In case you need something faster then we need to know more about the data ... for example what is the range of the values? Some hints:
on positive IsSymmetric test one cell bigger submatrix without testing the previous elements again (recursively increasing diagonal).
use histogram to detect values that might be only on diagonals (appear once globally or odd times locally)
Using the incremental symmetry test results in O(n^3) solution:
//---------------------------------------------------------------------------
#define column 5
#define row 8
//---------------------------------------------------------------------------
void submatrix_print(int mat[column][row], int i0,int j0,int n,int m)
{
int i,j;
printf("%i*%i at %i,%i\r\n",n,m,i0,j0);
for (i=0;i<n;i++,printf("\r\n"))
for (j=0;j<m;j++)
printf("%1i ",mat[i0+i][j0+j]);
}
//---------------------------------------------------------------------------
void submatrix_print_transposed(int mat[column][row], int i0,int j0,int n,int m)
{
int i,j;
printf("%i*%i at %i,%i\r\n",n,m,i0,j0);
for (i=0;i<m;i++,printf("\r\n"))
for (j=0;j<n;j++)
printf("%1i ",mat[i0+j][j0+i]);
}
//---------------------------------------------------------------------------
int min(int a,int b){ return (a<b)?a:b; }
int submatrix_symmetric(int mat[column][row], int i0,int j0) // returns biggest symetric submatrix size >=1 found at i0,j0
{
int i,n,N;
N=min(column-i0,row-j0); // max size that still fits into matrix
for (n=2;n<N;n++) // test all sizes above 1
for(i=0;i<n-1;i++) // only test newly added cells to last sub matrix
if (mat[i0+n-1][j0+i]!=mat[i0+i][j0+n-1])
return n-1; // first non match means last tested size i svalid
return n; // no mismatches mean full size is valid
}
//---------------------------------------------------------------------------
int main()
{
int mat[5][8]=
{
1,2,0,3,2,1,0,7,
2,3,4,1,2,3,4,5,
3,4,6,2,5,6,7,6,
4,5,7,3,6,8,9,8,
6,7,1,4,7,9,0,9,
};
submatrix_print(mat,0,0,5,8);
// submatrix_print_transposed(mat,0,0,5,8);
int i,j,n,i0=0,j0=0,n0=0;
for(i=0;i<column;i++)
for(j=0;j<row;j++)
{
n=submatrix_symmetric(mat,i,j);
if (n0<n){ n0=n; i0=i; j0=j; }
}
submatrix_print(mat,i0,j0,n0,n0);
return 0;
}
//-------------------------------------------------------------------------
The result of the code is:
5*8 at 0,0 // input matrix
1 2 0 3 2 1 0 7
2 3 4 1 2 3 4 5
3 4 6 2 5 6 7 6
4 5 7 3 6 8 9 8
6 7 1 4 7 9 0 9
4*4 at 1,3 // biggest symmetric sub matrix found
1 2 3 4
2 5 6 7
3 6 8 9
4 7 9 0
you can make a function that check if the matrix ican be transposed or no
and another function that take evry time a part from the main matrix and you move it everytime and check it with 1st function
example :
1st matrix :m[1][1] starting from zero
1 2
2 3
2 matrix :m[2][2] starting from one
2 0
3 4
then when you finish with 2 demension matrix you go to 3
till the end
i hope you understand me and sorry for my bad english
My code is very likely to be incorrect everywhere since I just go started on learning files.
The array of the text file is {3 2 1 3 4 5 6 1 2 3}
The array of the binary is {1 2 3 4 5 6 7 8 9 10}
#include <stdio.h>
#define ARR_SIZ 10
int main()
{
int arr_in[ARR_SIZ];
int arr_bin[ARR_SIZ];
int i = 0;
FILE * fp_in = fopen("data/in.txt", "r");
FILE * fp_bin = fopen("data/in.bin", "wb");
fread(arr_in, sizeof(int), ARR_SIZ, fp_in);
fread(arr_bin, sizeof(int), ARR_SIZ, fp_bin);
int sum[ARR_SIZ];
for (i=0; i < ARR_SIZ; i++){
fscanf("%d", arr_in);
fscanf("%d", arr_in);
sum[i] = arr_in[i] + arr_bin[i];
} printf("%d", sum[i]);
return 0;
}
fread() reads binary data even when the file is not opened with "b" which just means it doesn't do funny stuff with things like Windows-style line breaks.
If you want to read a text file you will how to do more complex work like reading in the data, look for line breaks, and than use the data before each line break. As that data is still a string you will need to convert it to an integer (e.g. using atoi())
You can use this simple program (without fread()):
#include <stdio.h>
#define SIZE 10
int main(void) {
FILE *text = fopen("in.txt", "r"); // --- declaration
FILE *binr = fopen("in.bin", "r");
int text_number[SIZE], binary_number[SIZE], sum = 0;
// alt: you can change sum to sum[SIZE] = {0} if you want to hold into an array.
// --- reading data and assigning into arrays
for (int i = 0; i < SIZE; i++) {
fscanf(text, "%d", &text_number[i]);
fscanf(binr, "%d", &binary_number[i]);
}
// --- summation
for (int i = 0; i < SIZE; i++) {
sum += text_number[i] + binary_number[i]; // alt: do sum[i] when you do sum[SIZE]
printf("%d ", sum); // alt: do sum[i]
sum = 0; // should be omitted when you change into sum[SIZE]
}
printf("\n");
return 0;
}
in.bin contains: 1 2 3 4 5 6 7 8 9 10
Similarly, in.txt contains: 3 2 1 3 4 5 6 1 2 3
And the result is: 4 4 4 7 9 11 13 9 11 13 (sum of both files' integers taken by array).
Note: If you want to store the sum into array, then use the alt code.
I'm not very much aware of fread(), so I just did what I could at the moment.
i am working on a program where the input is an ID of 9 numbers :
program checks if the id is correct or not by :-
checking if the string is formed by numbers only .
every number has a weight of 1 or 2 so it should be 1 2 1 2 1 2 1 2
1
multiply the weight and the number
if the number is bigger than 9 then add the numbers forming it .
if the number is from multiplication of 10 then the ID is correct ..
example :-
1 7 9 3 7 9 2 5 0-ID
1 2 1 2 1 2 1 2 1-Weight
1 14 9 6 7 18 2 10 0-num x weight
1 5 9 6 7 9 2 1 0-(4)
sum = 40 then it is a correct ID.
I wrote most of it but then i noticed that it has to be a string . so my questions are :
is there a way to put a string into an array?as doing it with an
array is way easier.
how do i locate a place in a string ? like if i want the third
character in a string how do i locate it?.
and here is the code that i did it does not work yet and it needs alot of changes but i guess i will put it anyways :-
#include<stdio.h>
#define N 9
void input(int num[N]);
int check(int num[N]);
int main()
{
int num[N],a;
input(num);
a = check(num);
if (a = 1)
printf("ID is correct");
else printf("ID is NOT correct");
}
void input(int num[N])
{
int i;
printf("Enter your ID (9digits) :-");
for (i = 0;i < N;i++)
scanf("%d",num[i]);
}
int check(int num[N])
{
int w[N] = { 1,2,1,2,1,2,1,2,1 },wxnum[N],i,tota[N],sum,g;
for (i = 0;i < N;i++)
wxnum[i] = num[i] * w[i];
for (i = 0;i < N;i++)
{
if (wxnum[i] > 9)
tota[i] = wxnum[i] / 10 + wxnum[i] % 10;
else tota[i] = wxnum[i];
}
sum = tota[0] + tota[1] + tota[2] + tota[3] + tota[4] + tota[5] + tota[6] + tota[7] + tota[8];
g = sum % 10;
if (g = 0)
return 1;
else
return 0;
}
Thanks everyone for your help.
You can get a string by doing
/*N is defined as 9 in your code.*/
/*Considering there is always a '\0' in every string, we should allocat N + 1 slot for your nine numbers and the extra '\0'.*/
char chStr[N + 1];
scanf("%s", chStr);
After you got the string, you can take advantage of the values of charactor '0' - '9' (their values are from 48 to 57 correspondingly) in ASCII table, and easily transfer the charactors into integers by doing:
int i = 0;
for (i = 0; i < N; i++)
{
chStr[i] = chStr[i] - '0';
}
If you are restrict on the type, you can transfer these char values into int values by adding extra two lines:
int num[N];
int i = 0;
for (i = 0; i < N; i++)
{
chStr[i] = chStr[i] - '0';
num[i] = (int) chStr[i];
}
Please note that my code didn't check the validation of user input. To make it more secure, you can use
scanf("%9s", chStr);
to declare the maximum length that the user can input.
The malloc'd 2d array I have to work from is
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
This isn't constructed from a [][] array but rather malloc'd memory separated by printf("\n");
I'd like to manipulate it and make a for loop to traverse through the list so the result is
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 25
so the result is
Row 1 * Column 1-4
Row 2 * Column 1-4 ...
Any help would be appreciated, I'm having a brain fart right now (just got out of class)
typedef struct array {
int cols, rows;
int *arr;
} array;
array mkSum(array node)
{
int i;
for (i = 1; i <= ((node.cols) * (node.rows)); i++) //goes through all 25
{
//CODE TO MANIPULATE
}
for (i = 0; i < ((node.cols) * (node.rows)); i++) //goes through all 25
{
if (i % node.cols == 0)
printf("\n");
printf(" %d", node.arr[i]); //prints out elements
}
return(node);
}
mkSum is called by passing in a pointer to the array which comes in as the one i have to work from (first example)
mkSum(array);
The question is a bit unclear (in particular about the desired result), but I think for the manipulation you best use two nested loops, and simulate node.arr being a 2d array:
for (int col = 0; col < node.cols; col++ ) {
for (int row = 0; row < node.rows; row ++ ) {
... Element to modify: node.arr[row * node.cols + col]
}
}
You'll have to adjust to calculation formula for the fact that row/col starts with 0 in this approach.
Try this
for (int col = 1; col <= node.cols; col++ ) {
for (int row = 1; row <= node.rows; row ++ ) {
printf(" %d", col*row);
}
printf("\n");
}
So I have been trying to do a variant of the subset sum problem, which I want to do using dynamic programming. So what I am aiming for is for example, to have an input of
m = 25 // Target value
n = 7 // Size of input set
and the input set to be for example {1, 3, 4, 6, 7, 10, 25}. So the wanted output would be something like
{1, 3, 4, 7, 10} and {25}.
Here is the code
#include <stdio.h>
#include <stdlib.h>
int main()
{
// Get input sequence
int n = 7; // Size of input set
int m = 25; // Target value
int *S; // Input set
int **C; // Cost table
int i,j,potentialSum,leftover;
S=(int*) malloc((n+1)*sizeof(int));
C=malloc((m+1)*sizeof(int*));
for (int rows = 0; rows<=m; rows++) {
C[rows] = malloc((m+1)*sizeof(int));
}
if (!S || !C)
{
printf(" FAILED %d\n",__LINE__);
exit(0);
}
S[0] = 0;
S[1] = 1;
S[2] = 3;
S[3] = 4;
S[4] = 6;
S[5] = 7;
S[6] = 10;
S[7] = 25;
// Initialize table for DP
C[0][0]=0; // DP base case
// For each potential sum, determine the smallest index such
// that its input value is in a subset to achieve that sum.
for (potentialSum=1; potentialSum<=m; potentialSum ++)
{
for (j=1;j<=n;j++)
{
leftover=potentialSum-S[j]; // To be achieved with other values
if (leftover<0) // Too much thrown away
continue;
if (C[leftover][0] == (-1)) // No way to achieve leftover
continue;
if (C[leftover][0]<j) // Indices are included in
break; // ascending order.
}
C[potentialSum][0]=(j<=n) ? j : (-1);
}
// Output the input set
printf(" i S\n");
printf("-------\n");
for (i=0;i<=n;i++)
printf("%3d %3d\n",i,S[i]);
// Output the DP table
printf("\n\n i C\n");
printf("-------\n");
for (i=0;i<=m;i++)
printf("%3d %3d\n",i,C[i][0]);
if (C[m][m]==(-1))
printf("No solution\n");
else
{
printf("\n\nSolution\n\n");
printf("(Position) i S\n");
printf("------------------\n");
for (i=m;i>0;i-=S[C[i][0]])
printf(" %3d %3d\n",C[i][0],S[C[i][0]]);
}
}
This will output the following
i S
-------
0 0
1 1
2 3
3 4
4 6
5 7
6 10
7 25
i C
-------
0 0
1 1
2 -1
3 2
4 2
5 3
6 4
7 3
8 3
9 4
10 4
11 4
12 5
13 4
14 4
15 5
16 5
17 5
18 5
19 6
20 5
21 5
22 6
23 6
24 6
25 6
Solution
(Position) i S
------------------
6 10
5 7
3 4
2 3
1 1
Program ended with exit code: 0
My problem is that I can only output one solution, and that is the solution that needs the smaller values and goes up to 25, so when 25 is used it isn't in the solution. The C array in the code is a 2-D array, since I thought I could maybe do another backtrace while computing the first one? I couldn't figure out how to do so, so I left C[i][0] fixed to the first column, just to demonstrate a single solution. Any tips in the right direction would be greatly appreciated. I found a solution using Python, but the problem is solved recursively, which I don't think helps me, but that code is here.
Thanks for all the help in advance.
I did not fully understand your code. But here is a C code which finds all the subsets that sum to target.
#include <stdio.h>
int a[] = { 0, 1, 3, 4, 6, 7, 10, 25 }; //-- notice that the input array is zero indexed
int n = 7;
int target = 25;
int dp[8][26];
int solutions[1 << 7][8]; //-- notice that the number of subsets could be exponential in the length of the input array a.
int sz[1 << 7]; //-- sz[i] is the length of subset solutions[i]
int cnt = 0; //-- number of subsets
void copy(int srcIdx, int dstIdx){
int i;
for (i = 0; i < sz[srcIdx]; i++)
solutions[dstIdx][i] = solutions[srcIdx][i];
sz[dstIdx] = sz[srcIdx];
}
//-- i, and j are indices of dp array
//-- idx is the index of the current subset in the solution array
void buildSolutions(int i, int j, int idx){
if (i == 0 || j == 0) return; // no more elements to add to the current subset
if (dp[i - 1][j] && dp[i - 1][j - a[i]]){ // we have two branches
cnt++; // increase the number of total subsets
copy(idx, cnt); // copy the current subset to the new subset. The new subset does not include a[i]
buildSolutions(i - 1, j, cnt); //find the remaining elements of the new subset
solutions[idx][sz[idx]] = a[i]; // include a[i] in the current subset
sz[idx]++; // increase the size of the current subset
buildSolutions(i - 1, j - a[i], idx); // calculate the remaining of the current subset
}
else if (dp[i - 1][j - a[i]]){ // we only have one branch
solutions[idx][sz[idx]] = a[i]; // add a[i] to the current subset
sz[idx]++;
buildSolutions(i - 1, j - a[i], idx); // calculate the remaining of the current subset
}
else buildSolutions(i - 1, j, idx); // a[i] is not part of the current subset
}
int main(){
int i, j;
// initialize dp array to 0
for (i = 0; i <= n; i++)
for (j = 0; j <= target; j++) dp[i][j] = 0;
//-- filling the dp array
for (i = 0; i <= n; i++)
dp[i][0] = 1;
for (i = 1; i <= n; i++){
for (j = 1; j <= target; j++){
if (j < a[i])
dp[i][j] = dp[i - 1][j];
else
dp[i][j] = dp[i - 1][j] || dp[i - 1][j - a[i]];
}
}
//-- building all the solutions
for (i = 0; i < sizeof(sz); i++) sz[i] = 0; //-- initializing the sz array to 0
buildSolutions(n, target, 0);
//-- printing all the subsets
for (i = 0; i <= cnt; i++){
for (j = 0; j < sz[i]; j++){
printf("%d ", solutions[i][j]);
}
printf("\n");
}
}
If you have any questions about the code, do not hesitate to ask.